141 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			141 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);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  );
							 | 
						||
| 
								 | 
							
								});
							 |