{"version":3,"file":"offscreenRenderer-DjqEzes2.js","sources":["../../../app/javascript/utils/photobookDefaultText.js","../../../app/javascript/utils/blobber.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","import { Brut } from \"@/components/brut/src/index.ts\";\nimport { isEqual, findIndex } from \"lodash-es\";\nimport swapper from \"./swapTemplate\";\nimport { defaultCaption, defaultTextPageText } from \"./photobookDefaultText\";\nimport Blobber from \"./blobber\";\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 { recenter, 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 recenter,\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 });\n },\n\n updateImageFramesFromDropPanes({\n sheet,\n primaryPaneData,\n secondaryPaneData = null\n }) {\n const renderer = buildCanvas(sheet, { reassignCanvasDimensions: true });\n\n return new Promise(resolve => {\n renderer.loadOffscreen(sheet.fabric, async () => {\n const imageFrames = renderer.nonLogoImageObjects();\n const frame = imageFrames.find(imageFrame => {\n const { userRotation, scale, ...adjustedRect } = primaryPaneData.rect;\n return isEqual(imageFrame.boundingBox.toJSON(), adjustedRect);\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 sheet,\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 sheet,\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(renderer, sheet, resolve);\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(renderer, sheet, resolve);\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 sheet,\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(renderer, sheet, resolve);\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","buildCanvas","sheet","reassignCanvasDimensions","perspectiveCanvasRequired","foilCanvasRequired","element","renderer","Brut","reinsertExtractedImagesOffscreen","canvas","images","recenter","selectImage","promises","object","index","image","imageOptions","userRotation","reinsertExtractedCaptionsOffscreen","captions","caption","findIndex","string","deleteTemporarilyOnscreenFoilCanvases","preview","text","papierBox","svg","perspectiveImages","previewImage","textbox","fabric","skodixSvg","coordinates","imageFrame","primaryPaneData","secondaryPaneData","imageFrames","frame","scale","adjustedRect","isEqual","secondFrame","coverSheet","swapper","template","options"],"mappings":"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"}