{"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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"}