140 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { ready } from "../utils";
 | 
						|
import { fabric } from "fabric";
 | 
						|
 | 
						|
fabric.Object.prototype.objectCaching = false;
 | 
						|
 | 
						|
const textboxDefaults = {
 | 
						|
  lockMovementX: true,
 | 
						|
  lockMovementY: true,
 | 
						|
  lockScalingX: true,
 | 
						|
  lockScalingY: true,
 | 
						|
  lockSkewingX: true,
 | 
						|
  lockSkewingY: true,
 | 
						|
  lockRotation: true,
 | 
						|
  lockUniScaling: true,
 | 
						|
  hasControls: false,
 | 
						|
  selectable: true,
 | 
						|
  fontFamily:
 | 
						|
    "system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji'",
 | 
						|
};
 | 
						|
 | 
						|
const updateDataURL = (canvas) => {
 | 
						|
  canvas.renderAll();
 | 
						|
  const data = canvas.toDataURL({
 | 
						|
    enableRetinaScaling: true,
 | 
						|
  });
 | 
						|
  canvas.dataURLInput.value = data;
 | 
						|
};
 | 
						|
 | 
						|
const setTextboxValue = (canvas, textbox, value) => {
 | 
						|
  textbox.set({ text: value });
 | 
						|
  updateDataURL(canvas);
 | 
						|
};
 | 
						|
 | 
						|
const setTextboxFromEvent = (canvas, textbox, { target }) => {
 | 
						|
  setTextboxValue(canvas, textbox, target.value);
 | 
						|
};
 | 
						|
 | 
						|
const makeLinkedTextbox = (canvas, selector, opts) => {
 | 
						|
  const box = new fabric.Textbox("", {
 | 
						|
    ...textboxDefaults,
 | 
						|
    ...opts,
 | 
						|
  });
 | 
						|
  box.on("input", updateDataURL.bind(box, canvas));
 | 
						|
 | 
						|
  var input = document.querySelector(selector);
 | 
						|
 | 
						|
  canvas.add(box);
 | 
						|
 | 
						|
  setTextboxValue(canvas, box, input.value);
 | 
						|
  input.addEventListener("input", setTextboxFromEvent.bind(input, canvas, box));
 | 
						|
 | 
						|
  return box;
 | 
						|
};
 | 
						|
 | 
						|
const makeStaticTextbox = (canvas, value, opts) => {
 | 
						|
  const box = new fabric.Textbox(value, {
 | 
						|
    ...textboxDefaults,
 | 
						|
    ...opts,
 | 
						|
  });
 | 
						|
  box.on("input", updateDataURL.bind(box, canvas));
 | 
						|
 | 
						|
  canvas.add(box);
 | 
						|
 | 
						|
  return box;
 | 
						|
};
 | 
						|
 | 
						|
const prepareCanvas = (input, canvasElement) => {
 | 
						|
  const inputContainer = input.parentElement;
 | 
						|
 | 
						|
  input.setAttribute("type", "hidden");
 | 
						|
 | 
						|
  canvasElement.setAttribute(
 | 
						|
    "class",
 | 
						|
    "social-media-preview-image rounded-lg border-2 border-gray-300"
 | 
						|
  );
 | 
						|
  canvasElement.setAttribute("width", 800);
 | 
						|
  canvasElement.setAttribute("height", 418);
 | 
						|
  inputContainer.appendChild(canvasElement);
 | 
						|
 | 
						|
  const canvas = new fabric.Canvas(canvasElement);
 | 
						|
  canvas.dataURLInput = input;
 | 
						|
 | 
						|
  return canvas;
 | 
						|
};
 | 
						|
 | 
						|
ready(() => {
 | 
						|
  const input = document.querySelector(
 | 
						|
    "[name='post[social_media_preview_image]']"
 | 
						|
  );
 | 
						|
  const canvasElement = document.createElement("canvas");
 | 
						|
  const canvas = prepareCanvas(input, canvasElement);
 | 
						|
 | 
						|
  fabric.Image.fromURL(
 | 
						|
    "/images/social-media-preview-background.png",
 | 
						|
    function (oImg) {
 | 
						|
      oImg.selectable = false;
 | 
						|
      canvas.add(oImg);
 | 
						|
 | 
						|
      const title = makeLinkedTextbox(canvas, "[name='post[title]']", {
 | 
						|
        left: 80,
 | 
						|
        top: 80,
 | 
						|
        width: 640,
 | 
						|
        fontWeight: "bold",
 | 
						|
        fontSize: 36,
 | 
						|
      });
 | 
						|
 | 
						|
      makeLinkedTextbox(canvas, "[name='post[excerpt]']", {
 | 
						|
        left: 80,
 | 
						|
        width: 560,
 | 
						|
        top: title.aCoords.bl.y + 20,
 | 
						|
        fill: "#4B5563",
 | 
						|
        fontSize: 18,
 | 
						|
      });
 | 
						|
 | 
						|
      var name = document
 | 
						|
        .querySelector("[property='og:site_name']")
 | 
						|
        .getAttribute("content");
 | 
						|
      makeStaticTextbox(canvas, name, {
 | 
						|
        left: 80,
 | 
						|
        width: 560,
 | 
						|
        top: 48,
 | 
						|
        fill: "#F87171",
 | 
						|
        fontSize: 18,
 | 
						|
        fontWeight: "bold",
 | 
						|
      });
 | 
						|
 | 
						|
      var rect = new fabric.Rect({
 | 
						|
        left: 0,
 | 
						|
        top: 0,
 | 
						|
        fill: "#F87171",
 | 
						|
        width: 14,
 | 
						|
        height: 418,
 | 
						|
        selectable: false,
 | 
						|
      });
 | 
						|
      canvas.add(rect);
 | 
						|
 | 
						|
      updateDataURL(canvas);
 | 
						|
    }
 | 
						|
  );
 | 
						|
});
 |