{"version":3,"file":"offscreenRenderer-DpPh8Esz.js","sources":["../../../app/javascript/utils/photobookDefaultText.js","../../../app/javascript/utils/blobber.js","../../../app/javascript/utils/findBestTemplate.js","../../../app/javascript/utils/offscreenRenderer.js"],"sourcesContent":["const defaultCaption = \"Add photo caption here\\nor delete if you prefer\";\nconst defaultTextPageText =\n \"ADD TITLE HERE\\nWrite a few words, a fun subtitle\\nor quote of your choice\";\n\nexport { defaultCaption, defaultTextPageText };\n","export default class Blobber {\n static base64ToBlob(base64) {\n const [typePart, base64Data] = base64.split(\",\");\n const byteCharacters = atob(base64Data); // Decodes Base64 string into a string of bytes\n const byteNumbers = new Array(byteCharacters.length);\n\n for (let i = 0; i < byteCharacters.length; i += 1) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n const type = typePart.split(\":\")[1].split(\";\")[0];\n const blob = new Blob([byteArray], { type });\n\n return URL.createObjectURL(blob);\n }\n\n static async blobUrlToBase64(url) {\n const data = await fetch(url);\n const blob = await data.blob();\n\n return new Promise(resolve => {\n const reader = new FileReader();\n reader.onloadend = () => {\n resolve(reader.result);\n };\n reader.readAsDataURL(blob);\n });\n }\n}\n","export default function findBestTemplate(image, alternativeSheets) {\n // we want to choose a template with a similar aspect ratio to the image\n // and one which has only one imageframe\n\n return new Promise(resolve => {\n if (!image) {\n resolve(null);\n return;\n }\n\n const loaderImage = new Image();\n loaderImage.onload = () => {\n const imageAspectRatio = loaderImage.width / loaderImage.height;\n let bestTemplate = null;\n let smallestDifference = Infinity;\n\n alternativeSheets.forEach(sheet => {\n if (!sheet.fabric) return;\n\n const { objects } = JSON.parse(sheet.fabric);\n const imageframes = objects.filter(obj => obj.type === \"imageframe\");\n\n if (imageframes.length === 1 && sheet.autofillable) {\n const [frame] = imageframes;\n const frameAspectRatio = frame.width / frame.height;\n const difference = Math.abs(imageAspectRatio - frameAspectRatio);\n\n if (difference < smallestDifference) {\n smallestDifference = difference;\n bestTemplate = sheet;\n }\n }\n });\n\n resolve(bestTemplate);\n };\n\n loaderImage.onerror = () => {\n resolve(null);\n };\n\n loaderImage.src = image.url;\n });\n}\n","import { Brut } from \"@/components/brut/src/index.ts\";\nimport { isEqual, findIndex } from \"lodash-es\";\nimport { defaultCaption, defaultTextPageText } from \"./photobookDefaultText\";\nimport Blobber from \"./blobber\";\nimport swapper from \"./swapTemplate\";\nimport findBestTemplate from \"./findBestTemplate\";\n\nconst buildCanvas = (\n sheet,\n {\n reassignCanvasDimensions = false,\n perspectiveCanvasRequired = false,\n foilCanvasRequired = false\n } = {}\n) => {\n let element;\n\n if (\"OffscreenCanvas\" in window) {\n element = new OffscreenCanvas(100, 100);\n } else {\n element = document.createElement(\"canvas\");\n element.width = 100;\n element.height = 100;\n }\n\n /* eslint-disable no-param-reassign */\n if (reassignCanvasDimensions) {\n element.width = sheet.width;\n element.height = sheet.height;\n }\n\n const renderer = new Brut(element, {\n offscreen: true,\n compressImage: true,\n perspectiveCanvasRequired: perspectiveCanvasRequired || foilCanvasRequired,\n foilCanvasRequired\n });\n renderer.init();\n return renderer;\n};\n\nconst reinsertExtractedImagesOffscreen = (\n canvas,\n images,\n { shouldRecenter, selectImage }\n) => {\n const promises = canvas.imageObjects().map((object, index) => {\n return new Promise(resolve => {\n if (images[index]) {\n const { image, imageOptions, userRotation } = images[index];\n canvas.setImageframeImage(\n object,\n image.url,\n image,\n {\n shouldRecenter,\n selectImage,\n imageOptions,\n userRotation\n },\n () => {\n canvas.checkObjectEdited(object);\n resolve();\n }\n );\n } else {\n resolve();\n }\n });\n });\n\n return Promise.all(promises);\n};\n\nconst reinsertExtractedCaptionsOffscreen = (canvas, captions) => {\n const promises = canvas.textObjects().map((object, index) => {\n return new Promise(resolve => {\n if (captions[index]) {\n canvas.setActiveObject(object);\n canvas.selectedTextbox = object;\n captions[index].forEach(caption => {\n canvas.updatePredefinedString(caption);\n const i = findIndex(\n object.predefinedStrings,\n string => string.key === caption.key\n );\n if (i === -1) {\n return;\n }\n caption.style = object.predefinedStrings[i].style;\n caption.textBox = object;\n object.predefinedStrings[i] = caption;\n });\n canvas.checkObjectEdited(object);\n resolve();\n } else {\n resolve();\n }\n });\n });\n\n return Promise.all(promises);\n};\n\n// This method removes the temporarily created foil canvases from the DOM to avoid memory consumption\n// The foil canvases are added to the DOM when the foil canvas is required\n// for rendering the template with the correct font-feature-settings\n// https://github.com/papier-ltd/website/pull/9693/\nconst deleteTemporarilyOnscreenFoilCanvases = () => {\n const canvases = document.getElementsByClassName(\n \"temporarily-onscreen-foil-canvas\"\n );\n\n [...canvases].forEach(canvas => {\n canvas.remove();\n });\n};\n\nexport default {\n renderCanvas(sheet, foilCanvasRequired = false) {\n let renderer = buildCanvas(sheet, {\n reassignCanvasDimensions: true,\n foilCanvasRequired\n });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, async () => {\n const base64 = await renderer.offscreenImageRepresentation();\n sheet.preview = Blobber.base64ToBlob(base64);\n sheet.svg = renderer.svgRepresentation();\n sheet.skodix_svg = renderer.skodixSvgRepresentation();\n renderer.dispose();\n renderer = null;\n\n if (foilCanvasRequired) {\n deleteTemporarilyOnscreenFoilCanvases();\n }\n\n resolve();\n });\n });\n },\n\n renderAndReturnImage(sheet, foilCanvasRequired = false) {\n let renderer = buildCanvas(sheet, {\n reassignCanvasDimensions: true,\n foilCanvasRequired\n });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, async () => {\n const preview = await renderer.offscreenImageRepresentation(\n undefined,\n true\n );\n renderer.dispose();\n renderer = null;\n resolve(preview);\n });\n });\n },\n\n renderAndReturnSvg(sheet, text) {\n let renderer = buildCanvas(sheet, { reassignCanvasDimensions: true });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, () => {\n const [papierBox] = renderer.textObjects();\n papierBox.replaceText(text);\n const svg = renderer.svgRepresentation();\n renderer.dispose();\n renderer = null;\n resolve(svg);\n });\n });\n },\n\n renderPreviewTemplateCanvas(sheet, images) {\n let renderer = buildCanvas(sheet, {\n reassignCanvasDimensions: true,\n perspectiveCanvasRequired: true\n });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, () => {\n const perspectiveImages = renderer.perspectiveImages();\n\n if (perspectiveImages.length !== images.length) {\n // We should not render the preview template if the number of images\n // does not match the number of perspective images\n // This is to prevent the preview template's stock product from showing in the image\n // We resolve null as this is the default value for the preview store's 'templatedPreviewImage' property\n // which is updated with the result of this function\n renderer.dispose();\n resolve(null);\n }\n\n const promises = images.map((image, index) =>\n perspectiveImages[index].setImageUrl(image)\n );\n\n Promise.all(promises).then(async () => {\n renderer.renderAll();\n const previewImage = await renderer.offscreenImageRepresentation(\n false,\n true\n );\n renderer.dispose();\n renderer = null;\n resolve(previewImage);\n });\n });\n });\n },\n\n removeDefaultText(sheet) {\n let renderer = buildCanvas(sheet);\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, async () => {\n const textboxes = renderer.textObjects();\n\n textboxes.forEach(textbox => {\n if ([defaultCaption, defaultTextPageText].includes(textbox.text)) {\n textbox.clearText();\n }\n });\n renderer.renderAll();\n const previewImage = await renderer.offscreenImageRepresentation();\n const fabric = renderer.jsonRepresentation();\n const svg = renderer.svgRepresentation();\n const skodixSvg = renderer.skodixSvgRepresentation();\n renderer.dispose();\n renderer = null;\n resolve({ previewImage, fabric, svg, skodixSvg, index: sheet.index });\n });\n });\n },\n\n getImageFrameCoordinates(sheet) {\n let renderer = buildCanvas(sheet);\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, () => {\n const imageFrames = renderer.nonLogoImageObjects();\n const coordinates = imageFrames.map(imageFrame => ({\n ...imageFrame.boundingBox.toJSON(),\n userRotation: imageFrame.userRotation,\n scale: imageFrame.imageOptions.scale\n }));\n renderer.dispose();\n renderer = null;\n resolve({ coordinates, index: sheet.index });\n });\n });\n },\n\n async renderCanvasAndCaptureData(renderer, sheet, resolve) {\n renderer.renderAll();\n const previewImage = await renderer.offscreenImageRepresentation();\n const fabric = renderer.jsonRepresentation();\n const svg = renderer.svgRepresentation();\n const skodixSvg = renderer.skodixSvgRepresentation();\n const images = renderer.imageArrayRepresentation();\n renderer.dispose();\n renderer = null;\n\n resolve({\n previewImage,\n fabric,\n svg,\n skodixSvg,\n images,\n index: sheet.index,\n id: sheet.id\n });\n },\n\n async updateImageFramesFromDropPanes({\n sheet,\n primaryPaneData,\n secondaryPaneData = null,\n chooseBetterTemplate = false,\n alternativeSheets = []\n }) {\n const sheetToUse = sheet;\n let sheetIsSwapped = false;\n\n const { objects } = JSON.parse(sheet.fabric);\n\n if (\n objects.filter(obj => obj.type === \"imageframe\").length === 1 &&\n chooseBetterTemplate\n ) {\n const template = await findBestTemplate(\n primaryPaneData.photo,\n alternativeSheets\n );\n if (template) {\n swapper.setupBackgroundTemplateSwap({\n sheet: sheetToUse,\n template,\n fromAutofill: true\n });\n sheetIsSwapped = true;\n }\n }\n\n const renderer = buildCanvas(sheetToUse, {\n reassignCanvasDimensions: true\n });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheetToUse.fabric, async () => {\n const imageFrames = renderer.nonLogoImageObjects();\n let [frame] = imageFrames;\n\n if (!sheetIsSwapped) {\n frame = imageFrames.find(imageFrame => {\n const { userRotation, scale, ...adjustedRect } =\n primaryPaneData.rect;\n return isEqual(imageFrame.boundingBox.toJSON(), adjustedRect);\n });\n }\n\n let secondFrame;\n\n if (secondaryPaneData?.rect) {\n secondFrame = imageFrames.find(imageFrame => {\n const { userRotation, scale, ...adjustedRect } =\n secondaryPaneData.rect;\n return isEqual(imageFrame.boundingBox.toJSON(), adjustedRect);\n });\n }\n\n if (primaryPaneData.photo) {\n // when we are adding an image to the main imageframe\n renderer.setImageframeImage(\n frame,\n primaryPaneData.photo.url,\n primaryPaneData.photo,\n {\n userRotation: primaryPaneData.userRotation || 0,\n scale: primaryPaneData.scale || 1\n },\n async () => {\n // when we have also provided a second imageframe to update\n if (secondFrame && secondaryPaneData) {\n // when the second imageframe should be cleared as no swapBackPhoto is provided\n if (!secondaryPaneData.photo) {\n secondFrame.clearImage();\n await this.renderCanvasAndCaptureData(\n renderer,\n sheetToUse,\n resolve\n );\n } else {\n // when we have an image to swap back to the second imageframe\n renderer.setImageframeImage(\n secondFrame,\n secondaryPaneData.photo.url,\n secondaryPaneData.photo,\n {\n userRotation: secondaryPaneData.userRotation || 0,\n scale: secondaryPaneData.scale || 1\n },\n async () => {\n await this.renderCanvasAndCaptureData(\n renderer,\n sheetToUse,\n resolve\n );\n }\n );\n }\n } else {\n // if we don't have a second imageframe to update\n // we just render the canvas for the main imageframe update (assigning the image)\n await this.renderCanvasAndCaptureData(\n renderer,\n sheetToUse,\n resolve\n );\n }\n }\n );\n } else {\n // when we don't have an image to add to the main imageframe\n frame.clearImage();\n if (secondFrame && secondaryPaneData) {\n // when we have been provided a second imageframe to update\n if (!secondaryPaneData.photo) {\n // if we are not provided a swapBackPhoto, we clear the second imageframe\n secondFrame.clearImage();\n await this.renderCanvasAndCaptureData(\n renderer,\n sheetToUse,\n resolve\n );\n } else {\n // if we have a swapBackPhoto, we update the second imageframe to have that image\n renderer.setImageframeImage(\n secondFrame,\n secondaryPaneData.photo.url,\n secondaryPaneData.photo,\n {\n userRotation: secondaryPaneData.userRotation || 0,\n scale: secondaryPaneData.scale || 1\n },\n async () => {\n await this.renderCanvasAndCaptureData(\n renderer,\n sheetToUse,\n resolve\n );\n }\n );\n }\n } else {\n // if we don't have a second imageframe to update\n // we just render the canvas for the main imageframe update (clearing the image)\n await this.renderCanvasAndCaptureData(\n renderer,\n sheetToUse,\n resolve\n );\n }\n }\n });\n });\n },\n\n extractImagesAndCaptions(coverSheet) {\n const renderer = buildCanvas(coverSheet);\n\n return new Promise(resolve => {\n renderer.loadOffscreen(coverSheet.fabric, () => {\n const images = swapper.extractImages(renderer);\n const captions = swapper.extractCaptions(renderer);\n renderer.dispose();\n resolve({ images, captions });\n });\n });\n },\n\n swapTemplateOffscreen(template, options) {\n const renderer = buildCanvas(template, {\n reassignCanvasDimensions: true,\n foilCanvasRequired: options.foilCanvasRequired\n });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(template.fabric, async () => {\n await reinsertExtractedImagesOffscreen(\n renderer,\n options.images,\n options\n );\n await reinsertExtractedCaptionsOffscreen(renderer, options.captions);\n const previewImage = await renderer.offscreenImageRepresentation();\n const fabric = renderer.jsonRepresentation();\n const svg = renderer.svgRepresentation();\n const skodixSvg = renderer.skodixSvgRepresentation();\n const images = renderer.imageArrayRepresentation();\n renderer.dispose();\n resolve({ previewImage, fabric, svg, images, skodixSvg });\n });\n });\n }\n};\n"],"names":["defaultCaption","defaultTextPageText","Blobber","base64","typePart","base64Data","byteCharacters","byteNumbers","i","byteArray","type","blob","url","resolve","reader","findBestTemplate","image","alternativeSheets","loaderImage","imageAspectRatio","bestTemplate","smallestDifference","sheet","objects","imageframes","obj","frame","frameAspectRatio","difference","buildCanvas","reassignCanvasDimensions","perspectiveCanvasRequired","foilCanvasRequired","element","renderer","Brut","reinsertExtractedImagesOffscreen","canvas","images","shouldRecenter","selectImage","promises","object","index","imageOptions","userRotation","reinsertExtractedCaptionsOffscreen","captions","caption","findIndex","string","deleteTemporarilyOnscreenFoilCanvases","preview","text","papierBox","svg","perspectiveImages","previewImage","textbox","fabric","skodixSvg","coordinates","imageFrame","primaryPaneData","secondaryPaneData","chooseBetterTemplate","sheetToUse","sheetIsSwapped","template","swapper","imageFrames","scale","adjustedRect","isEqual","secondFrame","coverSheet","options"],"mappings":"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"}