@reffy/infinite-canvas 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-KcoKIUJZ.js +281 -0
- package/dist/index.html +54 -0
- package/esm/Canvas.js +100 -112
- package/esm/Canvas.js.map +1 -1
- package/esm/Component.d.ts.map +1 -1
- package/esm/Component.js +273 -308
- package/esm/Component.js.map +1 -1
- package/esm/manager/ContextMenu.js +4 -17
- package/esm/manager/ContextMenu.js.map +1 -1
- package/esm/manager/Selection.js +87 -100
- package/esm/manager/Selection.js.map +1 -1
- package/esm/serializer/serializer.d.ts.map +1 -1
- package/esm/serializer/serializer.js +11 -5
- package/esm/serializer/serializer.js.map +1 -1
- package/esm/shapes/Shape.js +1 -1
- package/esm/shapes/Shape.js.map +1 -1
- package/lib/Canvas.js +100 -112
- package/lib/Canvas.js.map +1 -1
- package/lib/Component.d.ts.map +1 -1
- package/lib/Component.js +273 -308
- package/lib/Component.js.map +1 -1
- package/lib/manager/ContextMenu.js +4 -17
- package/lib/manager/ContextMenu.js.map +1 -1
- package/lib/manager/Selection.js +87 -100
- package/lib/manager/Selection.js.map +1 -1
- package/lib/serializer/serializer.d.ts.map +1 -1
- package/lib/serializer/serializer.js +11 -5
- package/lib/serializer/serializer.js.map +1 -1
- package/lib/shapes/Shape.js +1 -1
- package/lib/shapes/Shape.js.map +1 -1
- package/package.json +3 -2
- package/dist/index.js +0 -4114
- package/dist/index.js.map +0 -1
- package/dist/index.umd.js +0 -276
- package/dist/index.umd.js.map +0 -1
package/dist/index.umd.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../src/util/handles.ts","../src/util/webgl/m3.ts","../src/util/shaders.ts","../src/util/camera/camera.ts","../src/util/checks.ts","../src/util/files.ts","../src/util/color.ts","../src/manager/SceneCommand.ts","../src/util/clipboard.ts","../src/util/customEventType.ts","../src/shaders/shape.ts","../src/shaders/grid.ts","../src/shaders/img.ts","../src/bounding/type.ts","../src/bounding/BoundingBox.ts","../src/bounding/MultiBoundingBox.ts","../src/bounding/AABB.ts","../src/bounding/Marquee.ts","../src/state/camera.ts","../src/manager/FlipCommand.ts","../src/manager/TransformCommand.ts","../src/manager/Selection.ts","../src/manager/PointerEvent.ts","../src/manager/KeyEvent.ts","../src/manager/ContextMenu.ts","../src/manager/OrderCommand.ts","../src/state/pointerEvent.ts","../src/state/renderable.ts","../src/shapes/Renderable.ts","../src/shapes/Shape.ts","../src/shapes/Rect.ts","../src/shapes/Img.ts","../src/shapes/Grid.ts","../src/camera/Camera.ts","../src/serializer/serializer.ts","../src/Canvas.ts","../src/history/history.ts","../node_modules/@lit/reactive-element/decorators/custom-element.js","../node_modules/@lit/reactive-element/css-tag.js","../node_modules/@lit/reactive-element/reactive-element.js","../src/contextMenu/ContextMenu.ts","../src/contextMenu/Interaction.ts","../src/storage/storage.ts","../src/storage/dexie-primary-key.js","../src/storage/defaultStorage.ts","../src/loader/Loader.ts","../src/loader/Interaction.ts","../src/Component.ts","../src/API.ts"],"sourcesContent":["export const sides = [\"TOP\", \"BOTTOM\", \"LEFT\", \"RIGHT\"];\n\nexport const corners = [\"TOPLEFT\", \"TOPRIGHT\", \"BOTTOMLEFT\", \"BOTTOMRIGHT\"];\n\nexport type BoundingBoxCollisionType =\n | \"TOP\"\n | \"BOTTOM\"\n | \"LEFT\"\n | \"RIGHT\"\n | \"TOPRIGHT\"\n | \"TOPLEFT\"\n | \"BOTTOMRIGHT\"\n | \"BOTTOMLEFT\"\n | \"CENTER\";\n\ntype CornerType = \"TOPLEFT\" | \"TOPRIGHT\" | \"BOTTOMLEFT\" | \"BOTTOMRIGHT\";\n\nexport const cornerMap: Record<CornerType, CornerType> = {\n TOPLEFT: \"TOPRIGHT\",\n TOPRIGHT: \"TOPLEFT\",\n BOTTOMLEFT: \"BOTTOMRIGHT\",\n BOTTOMRIGHT: \"BOTTOMLEFT\",\n};\n\nexport function oppositeCorner(\n c: BoundingBoxCollisionType,\n): BoundingBoxCollisionType {\n if (cornerMap[c]) return cornerMap[c];\n return c;\n}\n\nexport const HANDLEPX = 8;\nexport const BORDERPX = 2;\n","export const m3 = {\n identity: function () {\n return [1, 0, 0, 0, 1, 0, 0, 0, 1];\n },\n\n translation: function (tx: number, ty: number) {\n return [1, 0, 0, 0, 1, 0, tx, ty, 1];\n },\n\n rotation: function (angleInRadians: number) {\n var c = Math.cos(angleInRadians);\n var s = Math.sin(angleInRadians);\n return [c, -s, 0, s, c, 0, 0, 0, 1];\n },\n\n scaling: function (sx: number, sy: number) {\n return [sx, 0, 0, 0, sy, 0, 0, 0, 1];\n },\n\n multiply: function (a: number[], b: number[]) {\n var a00 = a[0 * 3 + 0];\n var a01 = a[0 * 3 + 1];\n var a02 = a[0 * 3 + 2];\n var a10 = a[1 * 3 + 0];\n var a11 = a[1 * 3 + 1];\n var a12 = a[1 * 3 + 2];\n var a20 = a[2 * 3 + 0];\n var a21 = a[2 * 3 + 1];\n var a22 = a[2 * 3 + 2];\n var b00 = b[0 * 3 + 0];\n var b01 = b[0 * 3 + 1];\n var b02 = b[0 * 3 + 2];\n var b10 = b[1 * 3 + 0];\n var b11 = b[1 * 3 + 1];\n var b12 = b[1 * 3 + 2];\n var b20 = b[2 * 3 + 0];\n var b21 = b[2 * 3 + 1];\n var b22 = b[2 * 3 + 2];\n return [\n b00 * a00 + b01 * a10 + b02 * a20,\n b00 * a01 + b01 * a11 + b02 * a21,\n b00 * a02 + b01 * a12 + b02 * a22,\n b10 * a00 + b11 * a10 + b12 * a20,\n b10 * a01 + b11 * a11 + b12 * a21,\n b10 * a02 + b11 * a12 + b12 * a22,\n b20 * a00 + b21 * a10 + b22 * a20,\n b20 * a01 + b21 * a11 + b22 * a21,\n b20 * a02 + b21 * a12 + b22 * a22,\n ];\n },\n\n inverse(matrix: number[]) {\n const dst = [9];\n\n const m00 = matrix[0 * 3 + 0];\n const m01 = matrix[0 * 3 + 1];\n const m02 = matrix[0 * 3 + 2];\n const m10 = matrix[1 * 3 + 0];\n const m11 = matrix[1 * 3 + 1];\n const m12 = matrix[1 * 3 + 2];\n const m20 = matrix[2 * 3 + 0];\n const m21 = matrix[2 * 3 + 1];\n const m22 = matrix[2 * 3 + 2];\n\n const b01 = m22 * m11 - m12 * m21;\n const b11 = -m22 * m10 + m12 * m20;\n const b21 = m21 * m10 - m11 * m20;\n\n const det = m00 * b01 + m01 * b11 + m02 * b21;\n const invDet = 1.0 / det;\n\n dst[0] = b01 * invDet;\n dst[1] = (-m22 * m01 + m02 * m21) * invDet;\n dst[2] = (m12 * m01 - m02 * m11) * invDet;\n dst[3] = b11 * invDet;\n dst[4] = (m22 * m00 - m02 * m20) * invDet;\n dst[5] = (-m12 * m00 + m02 * m10) * invDet;\n dst[6] = b21 * invDet;\n dst[7] = (-m21 * m00 + m01 * m20) * invDet;\n dst[8] = (m11 * m00 - m01 * m10) * invDet;\n\n return dst;\n },\n\n projection(width: number, height: number) {\n const dst = [9];\n // Note: This matrix flips the Y axis so 0 is at the top.\n\n dst[0] = 2 / width;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n dst[4] = -2 / height;\n dst[5] = 0;\n dst[6] = -1;\n dst[7] = 1;\n dst[8] = 1;\n\n return dst;\n },\n\n transformPoint(m: number[], v: number[]) {\n var v0 = v[0];\n var v1 = v[1];\n var d = v0 * m[0 * 3 + 2] + v1 * m[1 * 3 + 2] + m[2 * 3 + 2];\n\n return [\n (v0 * m[0 * 3 + 0] + v1 * m[1 * 3 + 0] + m[2 * 3 + 0]) / d,\n (v0 * m[0 * 3 + 1] + v1 * m[1 * 3 + 1] + m[2 * 3 + 1]) / d,\n ];\n },\n};\n","export function createProgram(\n gl: WebGLRenderingContext,\n vert: string,\n frag: string,\n) {\n const vertShader = createShader(gl, gl.VERTEX_SHADER, vert);\n const fragShader = createShader(gl, gl.FRAGMENT_SHADER, frag);\n const program = gl.createProgram();\n gl.attachShader(program, vertShader);\n gl.attachShader(program, fragShader);\n gl.linkProgram(program);\n const success = gl.getProgramParameter(program, gl.LINK_STATUS);\n\n if (!success) {\n gl.deleteProgram(program);\n gl.deleteShader(vertShader);\n gl.deleteShader(fragShader);\n throw new Error(\n \"Program was not created or the link to shaders was not successful.\",\n );\n }\n\n gl.detachShader(program, vertShader);\n gl.detachShader(program, fragShader);\n\n return program;\n}\n\nfunction createShader(gl: WebGLRenderingContext, type: GLenum, source: string) {\n const shader = gl.createShader(type);\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);\n if (success) {\n return shader;\n }\n\n gl.deleteShader(shader);\n throw new Error(\"Shader was not created.\");\n}\n","import { Canvas } from \"Canvas\";\nimport { m3 } from \"../webgl/m3\";\n\nexport function getClipSpaceMousePosition(\n e: MouseEvent,\n canvas: HTMLCanvasElement,\n) {\n const rect = canvas.getBoundingClientRect();\n const cssX = e.clientX - rect.left;\n const cssY = e.clientY - rect.top;\n\n const normalizedX = cssX / canvas.clientWidth;\n const normalizedY = cssY / canvas.clientHeight;\n\n const clipX = normalizedX * 2 - 1;\n const clipY = normalizedY * -2 + 1;\n\n return [clipX, clipY];\n}\n\nexport function clipToCSS(\n clipX: number,\n clipY: number,\n canvas: HTMLCanvasElement,\n): [number, number] {\n const x = (clipX + 1) * 0.5 * canvas.clientWidth;\n const y = (1 - clipY) * 0.5 * canvas.clientHeight;\n return [x, y];\n}\n\n// Render: clip = P · V · world\n// Picking: world = inverse(P · V) · clip\nexport function screenToWorld(\n clientX: number,\n clientY: number,\n w: number,\n h: number,\n canvas: HTMLCanvasElement,\n worldMatrix: number[],\n): [number, number] {\n const rect = canvas.getBoundingClientRect();\n const dpr = window.devicePixelRatio || 1;\n\n // Device pixels relative to canvas\n const x = (clientX - rect.left) * dpr;\n const y = (clientY - rect.top) * dpr;\n\n const xClip = (x / w) * 2 - 1;\n const yClip = (y / h) * -2 + 1;\n\n // projection matrix transforms pixel space to clip space\n const proj = m3.projection(w, h);\n // view-projection matrix\n const pv = m3.multiply(proj, worldMatrix); // worldMatrix is view matrix and calculates the matrix to map world-space to clip-space\n\n // used to unproject and retrieve world coords\n const invPV = m3.inverse(pv);\n const [wx, wy] = m3.transformPoint(invPV, [xClip, yClip]);\n\n return [wx, wy];\n}\n\nexport function getWorldCoords(x: number, y: number, canvas: Canvas) {\n const { gl, canvas: innerCanvas } = canvas;\n return screenToWorld(\n x,\n y,\n gl.canvas.width,\n gl.canvas.height,\n innerCanvas,\n canvas.worldMatrix,\n );\n}\n\n/**\n * Transforms a point from world space to camera (view) space.\n * @param worldX X coordinate in world space\n * @param worldY Y coordinate in world space\n * @param cameraMatrix The camera/view matrix (usually canvas.worldMatrix)\n * @returns [cameraX, cameraY]\n */\nexport function worldToCamera(\n worldX: number,\n worldY: number,\n cameraMatrix: number[],\n): number[] {\n // The camera matrix maps camera space to world space, so invert it\n const invCamera = m3.inverse(cameraMatrix);\n return m3.transformPoint(invCamera, [worldX, worldY]);\n}\n\nexport function applyMatrixToPoint(\n matrix: number[],\n x?: number,\n y?: number,\n): [number, number] {\n const px = x ?? 0;\n const py = y ?? 0;\n return [\n matrix[0] * px + matrix[3] * py + matrix[6],\n matrix[1] * px + matrix[4] * py + matrix[7],\n ];\n}\n\nexport function getScaleXFromMatrix(matrix: number[]): number {\n return Math.hypot(matrix[0], matrix[1]);\n}\n\nexport function getScaleYFromMatrix(matrix: number[]): number {\n return Math.hypot(matrix[3], matrix[4]);\n}\n\nexport function getScalesFromMatrix(matrix: number[]): [number, number] {\n return [getScaleXFromMatrix(matrix), getScaleYFromMatrix(matrix)];\n}\n\nfunction isPositive(num: number) {\n return num / Math.abs(num);\n}\n\nexport function isScalePositive(matrix: number[]): number[] {\n return [isPositive(matrix[0]), isPositive(matrix[4])];\n}\n","export function arraysEqual(a, b) {\n if (a == undefined || b == undefined) return false;\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (a.length !== b.length) return false;\n\n // If you don't care about the order of the elements inside\n // the array, you should sort both arrays here.\n // Please note that calling sort on an array will modify that array.\n // you might want to clone your array first.\n\n for (var i = 0; i < a.length; ++i) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n}\n\nexport const isNumber = (a): a is number => typeof a === \"number\";\nexport const isObject = (a): a is object => a instanceof Object;\nexport const isBoolean = (arg): arg is boolean => arg === !!arg;\nexport const isFunction = (val): val is Function => typeof val === \"function\";\nexport const isUndefined = (val): val is undefined => val === undefined;\nexport const isNil = (val): val is null | undefined => val == null;\n\nexport const sameSign = (a: number, b: number) => Math.sign(a) === Math.sign(b);\n\nexport const normalizeSign = (v: number, EPS: number) => {\n if (Math.abs(v) < EPS) return 0;\n return Math.sign(v);\n};\n\nexport const willFlip = (current: number, factor: number, EPS: number) => {\n const next = current * factor;\n return normalizeSign(current, EPS) !== normalizeSign(next, EPS);\n};\n","import { SerializedCanvas } from \"../serializer\";\nimport { Img } from \"../shapes\";\n\nexport async function previewImage(file: File) {\n return new Promise<string | ArrayBuffer>((resolve, reject) => {\n let reader = new FileReader();\n reader.onload = (e) => {\n resolve(e.target.result);\n };\n\n reader.onerror = reject;\n reader.readAsDataURL(file);\n });\n}\n\nconst PERMISSIBLE_IMAGE_TYPES = [\n \"image/webp\",\n \"image/png\",\n \"image/jpeg\",\n \"image/jpg\",\n \"image/svg+xml\",\n \"image/avif\",\n \"image/gif\", // will be rendered as a still image\n \"image/apng\", // will be rendered as a still image\n];\n\nfunction isPermissibleImageType(fileType: string): boolean {\n return PERMISSIBLE_IMAGE_TYPES.includes(fileType);\n}\n\nexport async function hashStringToId(str: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(str);\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", data);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\n/**\n * Extract mimetype from base64 string\n */\nexport function getMimeType(data: string) {\n const match = /^data:([^;]+);base64,/.exec(data);\n return match ? match[1] : undefined;\n}\n\nexport async function addImages(\n files: FileList,\n addToCanvas: (src: string) => Promise<Img>,\n) {\n const images = [];\n if (files.length > 0) {\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n if (isPermissibleImageType(file.type)) {\n try {\n const src = await previewImage(file);\n if (typeof src === \"string\") {\n images.push(await addToCanvas(src));\n } else console.error(\"Image not added\");\n } catch {\n console.error(\"Failed to copy image.\");\n }\n }\n }\n }\n return images;\n}\n\nexport function downloadJSON(filename: string, data: SerializedCanvas) {\n const text = JSON.stringify(data, null, 2);\n const blob = new Blob([text], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n}\n\nexport async function readJSONFile<T = unknown>(file: File): Promise<T> {\n const text = await file.text();\n return JSON.parse(text) as T;\n}\n\nexport function convertToPNG(src: string, quality = 1.0): Promise<string> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n img.onload = () => {\n const canvas = document.createElement(\"canvas\");\n canvas.width = img.width;\n canvas.height = img.height;\n const ctx = canvas.getContext(\"2d\");\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.drawImage(img, 0, 0);\n const pngDataUrl = canvas.toDataURL(\"image/png\", quality);\n resolve(pngDataUrl);\n };\n img.onerror = reject;\n img.src = src;\n });\n}\n\nexport async function mergeMultiImg(imgs: Img[]): Promise<string> {\n const startX = getSmallestImgX(imgs);\n const startY = getSmallestImgY(imgs);\n const endX = getEndX(imgs);\n const endY = getEndY(imgs);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = endX - startX;\n canvas.height = endY - startY;\n const ctx = canvas.getContext(\"2d\");\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n // consider transformation as well\n const promises = imgs.map(async (img) => {\n return new Promise<void>(async (resolve, reject) => {\n try {\n const innerImg = new Image();\n innerImg.onload = () => {\n ctx.drawImage(\n innerImg,\n 0,\n 0,\n img.width,\n img.height,\n img.x - startX,\n img.y - startY,\n img.width * img.sx,\n img.height * img.sy,\n );\n resolve();\n };\n innerImg.onerror = reject;\n innerImg.src = img.src;\n } catch (err) {\n console.error(err);\n reject(err);\n }\n });\n });\n\n await Promise.all(promises);\n\n const data = canvas.toDataURL(\"image/png\");\n return data;\n}\n\nexport async function mergeImagesToCanvas(\n images: Img[],\n): Promise<{ mergedCanvas: HTMLCanvasElement; width: number; height: number }> {\n if (images.length === 0) {\n throw new Error(\"No images to merge.\");\n }\n\n // Compute bounding box for all images\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (const img of images) {\n minX = Math.min(minX, img.x);\n minY = Math.min(minY, img.y);\n maxX = Math.max(maxX, img.x + img.width);\n maxY = Math.max(maxY, img.y + img.height);\n }\n const width = Math.ceil(maxX - minX);\n const height = Math.ceil(maxY - minY);\n\n // Create offscreen canvas\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"Could not get 2D context\");\n\n // Draw each image at its relative position\n await Promise.all(\n images.map((img) => {\n return new Promise<void>((resolve, reject) => {\n const imageEl = new window.Image();\n imageEl.onload = () => {\n ctx.drawImage(\n imageEl,\n img.x - minX,\n img.y - minY,\n img.width,\n img.height,\n );\n resolve();\n };\n imageEl.onerror = reject;\n imageEl.src = img.src;\n });\n }),\n );\n\n return { mergedCanvas: canvas, width, height };\n}\n\nfunction getSmallestImgX(imgs: Img[]): number {\n return [...imgs].sort((a, b) => {\n return a.x - b.x;\n })[0].x;\n}\n\nfunction getSmallestImgY(imgs: Img[]): number {\n return [...imgs].sort((a, b) => {\n return a.y - b.y;\n })[0].y;\n}\n\nfunction getEndX(imgs: Img[]): number {\n const endImg = [...imgs].sort((a, b) => {\n return b.x + b.width * b.sx - (a.x + a.width * a.sx);\n })[0];\n return endImg.x + endImg.width * endImg.sx;\n}\n\nfunction getEndY(imgs: Img[]): number {\n const endImg = [...imgs].sort((a, b) => {\n return b.y + b.height * b.sy - (a.y + a.height * a.sy);\n })[0];\n return endImg.y + endImg.height * endImg.sy;\n}\n","export const BASE_BLUE: [number, number, number, number] = [0.33, 0.6, 0.95, 1];\nexport const LIGHT_BLUE: [number, number, number, number] = [\n 0.33, 0.6, 0.95, 0.6,\n];\nexport const MARQUEE_BLUE: [number, number, number, number] = [\n 0.33, 0.6, 0.95, 0.4,\n];\n","import { Canvas } from \"Canvas\";\nimport { Command } from \"../history\";\nimport { Renderable } from \"../shapes\";\n\n/**\n * what do we care about from the scene?\n * Definitely not camera movement\n * layers maybe?\n * children\n * children's individual transform is handled by the transform commands\n */\nexport interface SceneSnapshot {\n children: Renderable[];\n}\n\nexport function makeAddChildCommand(\n parent: Canvas,\n child: Renderable,\n label = \"Add Child\",\n): Command {\n return {\n label,\n do() {\n parent.children.push(child);\n },\n undo() {\n const i = parent.children.indexOf(child);\n if (i >= 0) parent.children.splice(i, 1);\n },\n };\n}\n\nexport function makeMultiAddChildCommand(\n parent: Canvas,\n children: Renderable[],\n label = \"Add Child\",\n): Command {\n return {\n label,\n do() {\n for (const child of children) {\n parent.appendChild(child);\n }\n },\n undo() {\n for (const child of children) {\n parent.removeChild(child);\n }\n },\n };\n}\n\nexport function makeRemoveChildCommand(\n parent: Canvas,\n child: Renderable,\n label = \"Remove Child\",\n): Command {\n let idx = -1;\n return {\n label,\n do() {\n idx = parent.children.indexOf(child);\n if (idx >= 0) parent.children.splice(idx, 1);\n },\n undo() {\n if (idx < 0) {\n parent.children.push(child);\n return;\n }\n parent.children.splice(idx, 0, child);\n },\n };\n}\n\nexport function makeMultiRemoveChildCommand(\n parent: Canvas,\n children: Renderable[],\n label = \"Remove Children\",\n): Command {\n // Store original indices so we can restore ordering on undo\n let positions: { child: Renderable; idx: number }[] = [];\n return {\n label,\n do() {\n // Build a unique set to avoid duplicate work\n const target = new Set(children);\n positions = [];\n parent.children.forEach((c, i) => {\n if (target.has(c)) positions.push({ child: c, idx: i });\n });\n // Remove in descending index order so earlier indices remain valid\n positions\n .slice()\n .sort((a, b) => b.idx - a.idx)\n .forEach(({ child }) => {\n parent.removeChild(child); // handles selection + GPU cleanup\n });\n },\n undo() {\n // Reinsert in ascending order at original indices\n positions\n .slice()\n .sort((a, b) => a.idx - b.idx)\n .forEach(({ child, idx }) => {\n if (parent.children.includes(child)) return; // already restored\n // Insert at the recorded index preserving draw order\n parent.children.splice(\n Math.min(idx, parent.children.length),\n 0,\n child,\n );\n // Re-establish parent link (manual since we bypass appendChild)\n child.addParent(parent);\n });\n parent.markOrderDirty();\n },\n };\n}\n","import { convertToPNG, getWorldCoords } from \".\";\nimport { Img } from \"../shapes\";\nimport { Canvas } from \"Canvas\";\nimport { CanvasHistory } from \"history\";\nimport { makeMultiAddChildCommand } from \"../manager/SceneCommand\";\n\ninterface InfiniteCanvasClipboardElement {\n src: string;\n x: number;\n y: number;\n sx: number;\n sy: number;\n}\n\ninterface InfiniteCanvasClipboard {\n type: \"infinite_canvas\";\n elements: InfiniteCanvasClipboardElement[];\n}\n\nconst acceptedPasteMimeType = [\"image/\", \"text/plain\"];\n\nexport const probablySupportsClipboardWriteText = () => {\n return \"clipboard\" in navigator && \"writeText\" in navigator.clipboard;\n};\n\n// the original copying method involved writing to clipboard API which can take a long time when writing multiple images\n// opted for in canvas only copying, which is faster\nexport async function copy(selected: Img[], clipboardEvent?: ClipboardEvent) {\n const dataStored: InfiniteCanvasClipboard = {\n type: \"infinite_canvas\",\n elements: selected.map((img) => ({\n src: img.src,\n x: img.x,\n y: img.y,\n sx: img.sx,\n sy: img.sy,\n })),\n };\n\n const json = JSON.stringify(dataStored);\n const clipboardItem = new ClipboardItem({\n \"text/plain\": new Blob([json], { type: \"text/plain\" }),\n });\n\n if (probablySupportsClipboardWriteText()) {\n try {\n await navigator.clipboard.write([clipboardItem]);\n return;\n } catch (err) {\n console.error(err);\n }\n }\n\n try {\n if (clipboardEvent) {\n clipboardEvent.clipboardData?.setData(\"text/plain\", json);\n return;\n }\n } catch (err) {\n console.error(err);\n }\n\n if (!copyTextViaExecCommand(json)) {\n throw new Error(\"Error copying to clipboard.\");\n }\n}\n\nfunction copyTextViaExecCommand(text: string | null) {\n // execCommand doesn't allow copying empty strings, so if we're\n // clearing clipboard using this API, we must copy at least an empty char\n if (!text) {\n text = \" \";\n }\n\n const isRTL = document.documentElement.getAttribute(\"dir\") === \"rtl\";\n\n const textarea = document.createElement(\"textarea\");\n\n textarea.style.border = \"0\";\n textarea.style.padding = \"0\";\n textarea.style.margin = \"0\";\n textarea.style.position = \"absolute\";\n textarea.style[isRTL ? \"right\" : \"left\"] = \"-9999px\";\n const yPosition = window.pageYOffset || document.documentElement.scrollTop;\n textarea.style.top = `${yPosition}px`;\n textarea.style.fontSize = \"12pt\";\n\n textarea.setAttribute(\"readonly\", \"\");\n textarea.value = text;\n\n document.body.appendChild(textarea);\n\n let success = false;\n\n try {\n textarea.select();\n textarea.setSelectionRange(0, textarea.value.length);\n\n success = document.execCommand(\"copy\");\n } catch (error: any) {\n console.error(error);\n }\n\n textarea.remove();\n\n return success;\n}\n\nexport async function paste(\n clientX: number,\n clientY: number,\n canvas: Canvas,\n history: CanvasHistory,\n isWorldCoord: boolean = true,\n) {\n // check if there is anything from your clipboard to paste from\n const items = await navigator.clipboard.read();\n const types = items[0].types;\n\n const [wx, wy] = isWorldCoord\n ? [clientX, clientY]\n : getWorldCoords(clientX, clientY, canvas);\n\n for (const type of types) {\n const allowed = acceptedPasteMimeType.find((allowed) =>\n allowed.endsWith(\"/\") ? type.startsWith(allowed) : type === allowed,\n );\n if (!allowed) continue;\n\n const blob = await items[0].getType(type);\n try {\n if (type === \"text/plain\") {\n const data: InfiniteCanvasClipboard = JSON.parse(await blob.text());\n if (data.elements.length === 0) return;\n\n let minX = Infinity,\n minY = Infinity;\n\n for (const el of data.elements) {\n if (el.x < minX) minX = el.x;\n if (el.y < minY) minY = el.y;\n }\n\n const images = await Promise.all(\n data.elements.map((element) =>\n canvas.addImageToCanvas(\n element.src,\n wx + element.x - minX,\n wy + element.y - minY,\n element.sx,\n element.sy,\n ),\n ),\n );\n\n history.push(makeMultiAddChildCommand(canvas, images));\n return;\n }\n } catch (err) {\n console.error(\"Failed to parse clipboard data\", err);\n continue;\n }\n\n let base64: string | undefined;\n\n if (type.startsWith(\"image/svg\")) {\n try {\n const svgText = await blob.text();\n base64 = await convertToPNG(\n `data:image/svg+xml;base64,${btoa(svgText)}`,\n );\n } catch (err) {\n console.error(\"SVG conversion failed\", err);\n continue;\n }\n } else {\n try {\n base64 = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n } catch (err) {\n console.error(\"Image read failed\", err);\n continue;\n }\n }\n\n try {\n const img = await canvas.addImageToCanvas(base64!, wx, wy);\n history.push(makeMultiAddChildCommand(canvas, [img]));\n return;\n } catch (err) {\n console.error(\"Failed to add image to canvas\", err);\n continue;\n }\n }\n}\n","export const ContextMenuEvent = {\n Open: \"opencontextmenu\",\n Close: \"closecontextmenu\",\n} as const;\n\nexport const CanvasEvent = {\n Dirty: \"dirty\",\n Save: \"save\",\n SelectionChanged: \"selectionchanged\",\n Render: \"render\",\n Resize: \"resize\",\n Zoom: \"zoom\",\n ModeChange: \"modechange\",\n HistoryChange: \"historychange\",\n PointerDown: \"pointerdown\",\n PointerUp: \"pointerup\",\n PointerMove: \"pointermove\",\n ImageAdded: \"imageadded\",\n ImageRemoved: \"imageremoved\",\n Change: \"statechange\",\n} as const;\n\nexport const CustomClipboardEvent = {\n Copy: \"copy\",\n Cut: \"cut\",\n Paste: \"paste\",\n} as const;\n\nexport const LoaderEvent = {\n start: \"startloading\",\n done: \"completeloading\",\n} as const;\n\nexport const SaveEvent = {\n Save: \"save\",\n SaveCompleted: \"savecompleted\",\n SaveFailed: \"savefailed\",\n} as const;\n","const vert = `\nattribute vec2 a_position;\n\nuniform vec2 u_resolution;\nuniform mat3 u_matrix;\nuniform float u_z;\n\n// all shaders have a main function\nvoid main() {\n vec2 position = (u_matrix * vec3(a_position, 1)).xy;\n\n vec2 zeroToOne = position / u_resolution;\n vec2 zeroToTwo = zeroToOne * 2.0;\n vec2 clipSpace = zeroToTwo - 1.0;\n float z = mix(1.0, -1.0, u_z);\n\n gl_Position = vec4(clipSpace * vec2(1, -1), z, 1);\n}\n`;\n\nconst frag = `\nprecision mediump float;\nuniform vec4 u_color;\n\nvoid main() {\n gl_FragColor = u_color;\n}\n`;\n\nexport { vert as shapeVert, frag as shapeFrag };\n","export const gridVert = /* glsl */ `\n#extension GL_OES_standard_derivatives : enable\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\nprecision highp int;\n#else\nprecision mediump float;\nprecision mediump int;\n#endif\n\nuniform mat3 u_ViewProjectionInvMatrix;\nuniform float u_ZoomScale;\nuniform float u_CheckboardStyle;\nuniform float u_z;\n\nattribute vec2 a_Position;\n\nvarying vec2 v_Position;\n\nvec2 project_clipspace_to_world(vec2 p) {\n return (u_ViewProjectionInvMatrix * vec3(p, 1.0)).xy;\n}\n\nvoid main() {\n v_Position = project_clipspace_to_world(a_Position);\n float z = mix(1.0, -1.0, u_z);\n gl_Position = vec4(a_Position, z, 1.0);\n}\n`;\n\nexport const gridFrag = /* glsl */ `\n#extension GL_OES_standard_derivatives : enable\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\nprecision highp int;\n#else\nprecision mediump float;\nprecision mediump int;\n#endif\n\nuniform mat3 u_ViewProjectionInvMatrix;\nuniform float u_ZoomScale;\nuniform float u_CheckboardStyle;\n\nvarying vec2 v_Position;\n\nconst vec4 GRID_COLOR = vec4(0.87, 0.87, 0.87, 1.0);\nconst vec4 PAGE_COLOR = vec4(0.986, 0.986, 0.986, 1.0);\nconst int CHECKERBOARD_STYLE_NONE = 0;\nconst int CHECKERBOARD_STYLE_GRID = 1;\nconst int CHECKERBOARD_STYLE_DOTS = 2;\nconst float BASE_GRID_PIXEL_SIZE = 100.0;\n\nvec2 scale_grid_size(float zoom) {\n if (zoom < 0.125) return vec2(BASE_GRID_PIXEL_SIZE * 125.0, 0.125);\n else if (zoom < 0.25) return vec2(BASE_GRID_PIXEL_SIZE * 25.0, 0.25);\n else if (zoom < 0.5) return vec2(BASE_GRID_PIXEL_SIZE * 5.0, 0.5);\n return vec2(BASE_GRID_PIXEL_SIZE, 4.0);\n}\n\nvec4 render_grid_checkerboard(vec2 coord) {\n float alpha = 0.0;\n\n vec2 size = scale_grid_size(u_ZoomScale);\n float gridSize1 = size.x;\n float gridSize2 = gridSize1 / 10.0;\n float zoomStep = size.y;\n int checkboardStyle = int(floor(u_CheckboardStyle + 0.5));\n\n if (checkboardStyle == CHECKERBOARD_STYLE_GRID) {\n vec2 grid1 = abs(fract(coord / gridSize1 - 0.5) - 0.5) / fwidth(coord) * gridSize1 / 2.0;\n vec2 grid2 = abs(fract(coord / gridSize2 - 0.5) - 0.5) / fwidth(coord) * gridSize2;\n float v1 = 1.0 - min(min(grid1.x, grid1.y), 1.0);\n float v2 = 1.0 - min(min(grid2.x, grid2.y), 1.0);\n\n if (v1 > 0.0) {\n alpha = v1;\n } else {\n alpha = v2 * clamp(u_ZoomScale / zoomStep, 0.0, 1.0);\n }\n }\n \n return mix(PAGE_COLOR, GRID_COLOR, alpha);\n}\n\nvoid main() {\n gl_FragColor = render_grid_checkerboard(v_Position);\n}\n`;\n","const vert = `\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\n\nuniform vec2 u_resolution;\nuniform mat3 u_matrix;\nuniform float u_z;\n\nvarying vec2 v_texCoord;\n\nvoid main() {\n vec2 position = (u_matrix * vec3(a_position, 1)).xy;\n vec2 zeroToOne = position / u_resolution;\n vec2 zeroToTwo = zeroToOne * 2.0;\n vec2 clipSpace = zeroToTwo - 1.0;\n float z = mix(1.0, -1.0, u_z);\n\n gl_Position = vec4(clipSpace * vec2(1, -1), z, 1);\n\n v_texCoord = a_texCoord;\n}\n`;\n\nconst frag = `\n#ifdef GL_FRAGMENT_PRECISION_HIGH\nprecision highp float;\n#else\nprecision mediump float;\n#endif\n \nuniform sampler2D u_image;\n \nvarying vec2 v_texCoord;\n \nvoid main() {\n gl_FragColor = texture2D(u_image, v_texCoord);\n}\n`;\n\nexport { vert as imageVert, frag as imageFrag };\n","export enum BoundingBoxMode {\n ACTIVE, // direct interaction allowed\n PASSIVE, // when just display the rect but not the corner handles - no direct interaction allowed\n}\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface PositionData extends Point {\n width: number;\n height: number;\n}\n","import {\n BASE_BLUE,\n LIGHT_BLUE,\n BORDERPX,\n HANDLEPX,\n corners,\n sides,\n BoundingBoxCollisionType,\n applyMatrixToPoint,\n getScalesFromMatrix,\n isScalePositive,\n normalizeSign,\n willFlip,\n} from \"../util\";\nimport { Rect } from \"../shapes/Rect\";\nimport { Shape } from \"../shapes/Shape\";\nimport { BoundingBoxMode } from \"./type\";\nimport { FlipDirection } from \"../manager\";\n\n// different from multi bounding box, the corners and handles are separated here because they need to be individually toggled\nexport class BoundingBox {\n target: Shape;\n width: number;\n height: number;\n sides: Map<string, Rect> = new Map();\n corners: Map<string, Rect> = new Map();\n borderSize: number = 0;\n boxSize: number = 0;\n mode: BoundingBoxMode = BoundingBoxMode.ACTIVE;\n\n constructor(target: Shape, mode?: BoundingBoxMode) {\n this.target = target;\n this.setDimension();\n this.mode = mode ?? BoundingBoxMode.ACTIVE;\n this.borderSize = BORDERPX;\n this.boxSize = HANDLEPX / 2;\n\n this.addSides();\n\n if (this.mode === BoundingBoxMode.ACTIVE) {\n this.addCorners();\n }\n }\n\n private setDimension() {\n const edge = this.target.getEdge();\n this.width = edge.maxX - edge.minX;\n this.height = edge.maxY - edge.minY;\n }\n\n private getSidesInScreenSpace(type: string, matrix?: number[]) {\n const [scaleX, scaleY] = matrix ? getScalesFromMatrix(matrix) : [1, 1];\n const { width, height, borderSize } = this;\n const [x, y] = applyMatrixToPoint(matrix);\n const [signX, signY] = isScalePositive(matrix);\n\n return {\n TOP: {\n x: signX > 0 ? x : x - width * scaleX,\n y,\n width: width * scaleX,\n height: borderSize,\n },\n BOTTOM: {\n x: signX > 0 ? x : x - width * scaleX,\n y: y + height * scaleY * signY,\n width: width * scaleX,\n height: borderSize,\n },\n LEFT: {\n x,\n y: signY > 0 ? y : y - height * scaleY,\n width: borderSize,\n height: height * scaleY,\n },\n RIGHT: {\n x: x + width * scaleX * signX,\n y: signY > 0 ? y : y - height * scaleY,\n width: borderSize,\n height: height * scaleY,\n },\n }[type];\n }\n\n private getCornersInScreenSpace(type: string, matrix: number[]) {\n const [scaleX, scaleY] = matrix ? getScalesFromMatrix(matrix) : [1, 1];\n const { width, height, boxSize } = this;\n const [x, y] = applyMatrixToPoint(matrix);\n const [signX, signY] = isScalePositive(matrix);\n\n return {\n TOPLEFT: {\n x: x - boxSize,\n y: y - boxSize,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n TOPRIGHT: {\n x: x - boxSize + width * scaleX * signX,\n y: y - boxSize,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n BOTTOMLEFT: {\n x: x - boxSize,\n y: y - boxSize + height * scaleY * signY,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n BOTTOMRIGHT: {\n x: x - boxSize + width * scaleX * signX,\n y: y - boxSize + height * scaleY * signY,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n }[type];\n }\n\n setPassive() {\n this.mode = BoundingBoxMode.PASSIVE;\n this.removeCorners();\n }\n\n setActive() {\n this.mode = BoundingBoxMode.ACTIVE;\n this.addCorners();\n }\n\n getPositions(): number[] {\n return this.target.getPositions() as number[];\n }\n\n /**\n * x and y should be world position\n */\n hitTest(\n wx: number,\n wy: number,\n worldMatrix: number[],\n ): BoundingBoxCollisionType | null {\n if (this.mode === BoundingBoxMode.PASSIVE) return;\n\n const [scaleX, scaleY] = getScalesFromMatrix(this.target.worldMatrix);\n const [signX, signY] = isScalePositive(this.target.worldMatrix);\n\n // converted to screen space\n const [hx, hy] = applyMatrixToPoint(worldMatrix, wx, wy);\n\n // ths hit margin should be in screen size\n const HIT_MARGIN = 4;\n\n for (const type of corners) {\n const corner = this.getCornersInScreenSpace(\n type,\n this.target.worldMatrix,\n );\n if (\n hx >= corner.x - HIT_MARGIN &&\n hx <= corner.x + corner.width + HIT_MARGIN &&\n hy >= corner.y - HIT_MARGIN &&\n hy <= corner.y + corner.height + HIT_MARGIN\n ) {\n return type as BoundingBoxCollisionType;\n }\n }\n\n for (const type of sides) {\n const side = this.getSidesInScreenSpace(type, this.target.worldMatrix);\n if (\n hx >= side.x - HIT_MARGIN &&\n hx <= side.x + side.width + HIT_MARGIN &&\n hy >= side.y - HIT_MARGIN &&\n hy <= side.y + side.height + HIT_MARGIN\n ) {\n return type as BoundingBoxCollisionType;\n }\n }\n\n const [x, y] = applyMatrixToPoint(this.target.worldMatrix);\n\n const w = this.width * scaleX * signX;\n const h = this.height * scaleY * signY;\n\n const minX = Math.min(x, x + w);\n const maxX = Math.max(x, x + w);\n const minY = Math.min(y, y + h);\n const maxY = Math.max(y, y + h);\n\n if (hx >= minX && hx <= maxX && hy >= minY && hy <= maxY) {\n return \"CENTER\";\n }\n }\n\n update() {\n this.updateSides();\n this.updateCorners();\n }\n\n render(gl: WebGLRenderingContext, program: WebGLProgram): void {\n this.update();\n\n for (const [key, handle] of this.sides.entries()) {\n handle.render(gl, program);\n }\n\n for (const [key, corner] of this.corners.entries()) {\n corner.render(gl, program);\n }\n }\n\n destroy() {\n for (const [_, handle] of this.sides.entries()) {\n handle.destroy();\n }\n\n for (const [key, corner] of this.corners.entries()) {\n corner.destroy();\n }\n }\n\n move(dx: number, dy: number) {\n this.target.updateTranslation(dx, dy);\n }\n\n resize(dx: number, dy: number, direction: BoundingBoxCollisionType) {\n if (this.target instanceof Rect) {\n const baseW = Math.abs(this.width);\n const baseH = Math.abs(this.height);\n\n const aspectRatio = baseW / baseH;\n\n // Use the shape's local scale (ignore camera/view)\n const curSX = this.target.sx;\n const curSY = this.target.sy;\n\n const EPS = 1e-6;\n\n // Current effective world sizes (clamped away from 0 to avoid division issue)\n const prevWorldW =\n Math.abs(baseW * curSX) < EPS\n ? EPS * normalizeSign(baseW * curSX || 1, EPS)\n : baseW * curSX;\n const prevWorldH =\n Math.abs(baseH * curSY) < EPS\n ? EPS * normalizeSign(baseH * curSY || 1, EPS)\n : baseH * curSY;\n\n const changeInXScale = dx / prevWorldW;\n const changeInYScale = dy / prevWorldH;\n\n const min = EPS;\n const factor =\n direction === \"LEFT\" ||\n direction === \"BOTTOMLEFT\" ||\n direction === \"TOPLEFT\"\n ? 1 - changeInXScale\n : direction === \"RIGHT\" ||\n direction === \"BOTTOMRIGHT\" ||\n direction === \"TOPRIGHT\"\n ? 1 + changeInXScale\n : direction === \"TOP\"\n ? 1 - changeInYScale\n : 1 + changeInYScale;\n\n if (willFlip(curSX, factor, min) || willFlip(curSY, factor, min)) return;\n const nextW = baseW * curSX * factor;\n const nextH = baseH * curSY * factor;\n if (Math.abs(nextW) < min || Math.abs(nextH) < min) return;\n\n this.target.updateScale(factor, factor);\n\n if (direction === \"LEFT\") {\n const anchor = baseH * curSY;\n const newOrigin = baseH * this.target.sy;\n this.target.updateTranslation(dx, (anchor - newOrigin) / 2);\n } else if (direction === \"RIGHT\") {\n const anchor = baseH * curSY;\n const newOrigin = baseH * this.target.sy;\n this.target.updateTranslation(0, (anchor - newOrigin) / 2);\n } else if (direction === \"TOP\") {\n const anchor = baseW * curSX;\n const newOrigin = baseW * this.target.sx;\n this.target.updateTranslation((anchor - newOrigin) / 2, dy);\n } else if (direction === \"BOTTOM\") {\n const anchor = baseW * curSX;\n const newOrigin = baseW * this.target.sx;\n this.target.updateTranslation((anchor - newOrigin) / 2, 0);\n } else if (direction === \"BOTTOMLEFT\") {\n this.target.updateTranslation(dx, 0);\n } else if (direction === \"TOPLEFT\") {\n this.target.updateTranslation(\n dx,\n (dx / aspectRatio) * Math.sign(this.target.sx),\n );\n } else if (direction === \"TOPRIGHT\") {\n this.target.updateTranslation(\n 0,\n (-dx / aspectRatio) * Math.sign(this.target.sx),\n );\n }\n }\n }\n\n // a reset method to reset the scale\n reset() {\n this.target.setScale(1, 1);\n }\n\n flip(direction: FlipDirection) {\n const { x, y, sx, sy } = this.target;\n direction === \"vertical\"\n ? this.target.flipVertical(this.height)\n : this.target.flipHorizontal(this.width);\n\n return {\n ref: this.target,\n start: { x, y, sx, sy },\n end: {\n x: this.target.x,\n y: this.target.y,\n sx: this.target.sx,\n sy: this.target.sy,\n },\n };\n }\n\n private addCorners() {\n for (const type of corners) {\n const r = new Rect(\n this.getCornersInScreenSpace(type, this.target.worldMatrix),\n );\n r.color = this.mode === BoundingBoxMode.ACTIVE ? BASE_BLUE : LIGHT_BLUE;\n this.corners.set(type, r);\n }\n }\n\n private removeCorners() {\n this.corners.clear();\n }\n\n private updateCorners() {\n for (const type of corners) {\n const config = this.getCornersInScreenSpace(\n type,\n this.target.worldMatrix,\n );\n const corner = this.corners.get(type);\n\n if (corner) {\n corner.setTranslation(config.x, config.y);\n corner.width = config.width;\n corner.height = config.height;\n corner.color =\n this.mode === BoundingBoxMode.ACTIVE ? BASE_BLUE : LIGHT_BLUE;\n }\n }\n }\n\n private addSides() {\n for (const type of sides) {\n const r = new Rect(\n this.getSidesInScreenSpace(type, this.target.worldMatrix),\n );\n r.color = this.mode === BoundingBoxMode.ACTIVE ? BASE_BLUE : LIGHT_BLUE;\n this.sides.set(type, r);\n }\n }\n\n private updateSides() {\n for (const type of sides) {\n const config = this.getSidesInScreenSpace(type, this.target.worldMatrix);\n const side = this.sides.get(type);\n\n // only scale the side that should change, e.g. if it grows horizontally, scale only the width with scale and not height\n if (side) {\n side.setTranslation(config.x, config.y);\n side.width = config.width;\n side.height = config.height;\n side.color =\n this.mode === BoundingBoxMode.ACTIVE ? BASE_BLUE : LIGHT_BLUE;\n }\n }\n }\n}\n","import {\n BASE_BLUE,\n BORDERPX,\n HANDLEPX,\n corners,\n sides,\n BoundingBoxCollisionType,\n applyMatrixToPoint,\n getScalesFromMatrix,\n willFlip,\n} from \"../util\";\nimport {\n AlignDirection,\n FlipDirection,\n FlipSnapshotItem,\n NormalizeOption,\n NormalizeMode,\n TransformSnapshotItem,\n} from \"../manager\";\nimport { Rect } from \"../shapes/Rect\";\n\nconst HANDLE_TYPES: BoundingBoxCollisionType[] = [\n ...corners,\n ...sides,\n] as BoundingBoxCollisionType[];\n\nexport class MultiBoundingBox {\n targets: Rect[] = [];\n x: number;\n y: number;\n width: number;\n height: number;\n handles: Map<string, Rect> = new Map(); // unlike regular bounding box, since there is no different modes, there is no need to distinguish sidess and corners\n borderSize: number = 0;\n boxSize: number = 0;\n scale: number[];\n\n constructor(shapes?: Rect[]) {\n this.scale = [1, 1];\n if (shapes) shapes.forEach((shape) => this.add(shape));\n this.addHandles();\n }\n\n add(shape: Rect) {\n if (!this.targets.includes(shape)) {\n this.targets.push(shape);\n }\n }\n\n remove(shape: Rect) {\n const idx = this.targets.indexOf(shape);\n if (idx != -1) this.targets.splice(idx, 1);\n }\n\n render(gl: WebGLRenderingContext, program: WebGLProgram): void {\n this.update();\n\n for (const [key, handle] of this.handles.entries()) {\n handle.render(gl, program);\n }\n }\n\n update() {\n this.borderSize = BORDERPX;\n this.boxSize = HANDLEPX / 2;\n\n this.recalculateBounds();\n this.updateHandles();\n }\n\n destroy() {\n for (const [_, handle] of this.handles.entries()) {\n handle.destroy();\n }\n }\n\n move(dx: number, dy: number) {\n for (const target of this.targets) {\n target.updateTranslation(dx, dy);\n }\n }\n\n // dx and dy are in world units\n resize(\n dx: number,\n dy: number,\n direction: BoundingBoxCollisionType,\n parentMatrix: number[],\n ) {\n const prevW = this.width;\n const prevH = this.height;\n\n const isTop = direction.includes(\"TOP\");\n const isBottom = direction.includes(\"BOTTOM\");\n const isLeft = direction.includes(\"LEFT\");\n const isRight = direction.includes(\"RIGHT\");\n\n const anchorX = isLeft\n ? this.x + prevW\n : isRight\n ? this.x\n : this.x + prevW / 2;\n const anchorY = isTop\n ? this.y + prevH\n : isBottom\n ? this.y\n : this.y + prevH / 2;\n\n const min = 1e-6;\n const prevWorldW = Math.abs(prevW) < min ? (prevW < 0 ? -min : min) : prevW;\n const prevWorldH = Math.abs(prevH) < min ? (prevH < 0 ? -min : min) : prevH;\n\n const [worldScaleX, worldScaleY] = getScalesFromMatrix(parentMatrix);\n const changeInXScale = (dx * worldScaleX) / prevWorldW;\n const changeInYScale = (dy * worldScaleY) / prevWorldH;\n\n const factor = direction.includes(\"LEFT\")\n ? 1 - changeInXScale\n : direction.includes(\"RIGHT\")\n ? 1 + changeInXScale\n : direction === \"TOP\"\n ? 1 - changeInYScale\n : 1 + changeInYScale;\n\n if (\n willFlip(this.scale[0], factor, min) ||\n willFlip(this.scale[1], factor, min)\n )\n return;\n const nextW = prevW * factor;\n const nextH = prevH * factor;\n if (Math.abs(nextW) < min || Math.abs(nextH) < min) return;\n\n for (const target of this.targets) {\n const tx = target.x;\n const ty = target.y;\n\n const [wtx, wty] = applyMatrixToPoint(parentMatrix, tx, ty);\n\n const newWtx = anchorX + (wtx - anchorX) * factor;\n const newWty = anchorY + (wty - anchorY) * factor;\n\n const dWx = newWtx - wtx;\n const dWy = newWty - wty;\n\n const sX =\n Math.abs(worldScaleX) < min\n ? worldScaleX < 0\n ? -min\n : min\n : worldScaleX;\n const sY =\n Math.abs(worldScaleY) < min\n ? worldScaleY < 0\n ? -min\n : min\n : worldScaleY;\n\n // delta local change\n const dLx = dWx / sX;\n const dLy = dWy / sY;\n\n target.updateScale(factor, factor);\n target.updateTranslation(dLx, dLy);\n }\n }\n\n flip(\n worldMatrix: number[],\n direction: FlipDirection,\n getWorldCoords: (x: number, y: number) => number[],\n ) {\n const [worldScaleX, worldScaleY] = getScalesFromMatrix(worldMatrix);\n\n const transformArray: FlipSnapshotItem[] = [];\n\n const [wtx, wty] = getWorldCoords(this.x, this.y);\n\n for (const target of this.targets) {\n const transform: FlipSnapshotItem = {\n ref: target,\n start: { x: target.x, y: target.y, sx: target.sx, sy: target.sy },\n };\n\n if (direction === \"vertical\") {\n const scaleH = target.height * target.sy;\n target.setTranslation(target.x, -target.y - scaleH);\n target.flipVertical(target.height);\n } else {\n const scaleW = target.width * target.sx;\n target.setTranslation(-target.x - scaleW, target.y);\n target.flipHorizontal(target.width);\n }\n\n transform.end = {\n x: target.x,\n y: target.y,\n sx: target.sx,\n sy: target.sy,\n };\n transformArray.push(transform);\n }\n\n return transformArray;\n }\n\n align(direction: AlignDirection) {\n if (this.targets.length <= 1) return;\n\n const transformArray: TransformSnapshotItem[] = [];\n\n const dir = [\n direction === \"top\" ? 1 : direction === \"bottom\" ? -1 : 0,\n direction === \"left\" ? 1 : direction === \"right\" ? -1 : 0,\n ];\n\n let aim = dir[0] !== 0 ? Infinity * dir[0] : Infinity * dir[1];\n\n for (const [k, v] of this.targets.entries()) {\n const box = v.getBoundingBox();\n aim =\n direction === \"top\" || direction === \"left\"\n ? Math.min(direction === \"top\" ? box.minY : box.minX, aim)\n : Math.max(direction === \"bottom\" ? box.maxY : box.maxX, aim);\n }\n\n for (const target of this.targets) {\n const transform: TransformSnapshotItem = {\n ref: target,\n start: { x: target.x, y: target.y, sx: target.sx, sy: target.sy },\n };\n const aabb = target.getBoundingBox();\n target.updateTranslation(\n direction === \"top\" || direction === \"bottom\"\n ? 0\n : aim - (direction === \"left\" ? aabb.minX : aabb.maxX),\n direction === \"top\" || direction === \"bottom\"\n ? aim - (direction === \"top\" ? aabb.minY : aabb.maxY)\n : 0,\n );\n transform.end = {\n x: target.x,\n y: target.y,\n sx: target.sx,\n sy: target.sy,\n };\n transformArray.push(transform);\n }\n\n return transformArray;\n }\n\n normalize(type: NormalizeOption, mode: NormalizeMode) {\n const transformArray: TransformSnapshotItem[] = [];\n\n const reference = this.targets[0];\n const goal =\n type === \"height\"\n ? mode === \"first\"\n ? reference.height * reference.sy\n : this.targets.reduce((a, b) => a + Math.abs(b.height * b.sy), 0) /\n this.targets.length\n : type === \"width\"\n ? mode === \"first\"\n ? reference.width * reference.sx\n : this.targets.reduce((a, b) => a + Math.abs(b.width * b.sx), 0) /\n this.targets.length\n : type === \"scale\"\n ? mode === \"first\"\n ? reference.sx\n : this.targets.reduce((a, b) => a + Math.abs(b.sx), 0) /\n this.targets.length\n : mode === \"first\"\n ? reference.width * reference.height * reference.sx * reference.sy\n : this.targets.reduce(\n (a, b) => a + Math.abs(b.sx * b.width * b.height * b.sy),\n 0,\n ) / this.targets.length; // size calculation aims to get the same area for both\n\n for (const target of this.targets) {\n const transform: TransformSnapshotItem = {\n ref: target,\n start: { x: target.x, y: target.y, sx: target.sx, sy: target.sy },\n };\n\n // origin of transformation is the center of the rect\n const center = [\n (target.x + target.width * target.sx) / 2,\n (target.y + target.height * target.sy) / 2,\n ];\n\n if (type === \"height\") {\n const currH = target.height * target.sy;\n const scale = Math.abs(goal / currH);\n target.updateScale(scale, scale);\n } else if (type === \"width\") {\n const currw = target.width * target.sx;\n const scale = Math.abs(goal / currw);\n target.updateScale(scale, scale);\n } else if (type === \"scale\") {\n // keep existing scale direction\n const signX = Math.sign(target.sx);\n const signY = Math.sign(target.sy);\n target.setScale(goal * signX, goal * signY);\n } else if (type === \"size\") {\n // get current area\n const currentArea =\n target.width * target.height * target.sx * target.sy;\n const scale = Math.sqrt(Math.abs(goal / currentArea));\n target.updateScale(scale, scale);\n }\n\n // the x and y of origin has not change, we need to move this to recenter\n const newCenter = [\n (target.x + target.width * target.sx) / 2,\n (target.y + target.height * target.sy) / 2,\n ];\n target.updateTranslation(\n center[0] - newCenter[0],\n center[1] - newCenter[1],\n );\n transform.end = {\n x: target.x,\n y: target.y,\n sx: target.sx,\n sy: target.sy,\n };\n transformArray.push(transform);\n }\n return transformArray;\n }\n\n getPositions(): number[] {\n return [\n this.x,\n this.y, // Top-left\n this.x + this.width,\n this.y, // Top-right\n this.x + this.width,\n this.y + this.height, // Bottom-right\n this.x,\n this.y + this.height, // Bottom-left\n ];\n }\n\n hitTest(\n x: number,\n y: number,\n worldMatrix: number[],\n ): BoundingBoxCollisionType | null {\n const [hx, hy] = applyMatrixToPoint(worldMatrix, x, y);\n const HIT_MARGIN = 4;\n\n for (const type of HANDLE_TYPES) {\n const config = this.getHandleConfig(type);\n if (\n hx >= config.x - HIT_MARGIN &&\n hx <= config.x + config.width + HIT_MARGIN &&\n hy >= config.y - HIT_MARGIN &&\n hy <= config.y + config.height + HIT_MARGIN\n ) {\n return type as BoundingBoxCollisionType;\n }\n }\n\n const bx1 = Math.min(this.x, this.x + this.width);\n const bx2 = Math.max(this.x, this.x + this.width);\n const by1 = Math.min(this.y, this.y + this.height);\n const by2 = Math.max(this.y, this.y + this.height);\n\n if (hx >= bx1 && hx <= bx2 && hy >= by1 && hy <= by2) {\n return \"CENTER\";\n }\n }\n\n private getBounds() {\n const arr = Array.from(this.targets);\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n\n for (const rect of arr) {\n const [startX, startY] = applyMatrixToPoint(rect.worldMatrix);\n const [endX, endY] = applyMatrixToPoint(\n rect.worldMatrix,\n rect.width,\n rect.height,\n );\n\n minX = Math.min(minX, rect.sx < 0 ? endX : startX);\n minY = Math.min(minY, rect.sy < 0 ? endY : startY);\n maxX = Math.max(maxX, rect.sx < 0 ? startX : endX);\n maxY = Math.max(maxY, rect.sy < 0 ? startY : endY);\n }\n return { minX, minY, maxX, maxY };\n }\n\n private recalculateBounds() {\n const { minX, minY, maxX, maxY } = this.getBounds();\n\n this.x = this.scale[0] < 0 ? maxX : minX;\n this.y = this.scale[1] < 0 ? maxY : minY;\n this.width = this.scale[0] * (maxX - minX);\n this.height = this.scale[1] * (maxY - minY);\n }\n\n private addHandles() {\n for (const type of HANDLE_TYPES) {\n const config = this.getHandleConfig(type);\n const rect = new Rect(config);\n rect.color = BASE_BLUE;\n this.handles.set(type, rect);\n }\n }\n\n private updateHandles() {\n for (const type of HANDLE_TYPES) {\n const handle = this.handles.get(type);\n const config = this.getHandleConfig(type);\n\n if (handle) {\n handle.setTranslation(config.x, config.y);\n handle.width = config.width;\n handle.height = config.height;\n }\n }\n }\n\n private getHandleConfig(type: string) {\n let { x, y, width, height, borderSize, boxSize } = this;\n\n return {\n TOP: {\n x,\n y,\n width: width,\n height: borderSize,\n },\n BOTTOM: {\n x,\n y: y + height,\n width: width,\n height: borderSize,\n },\n LEFT: {\n x,\n y,\n width: borderSize,\n height: height,\n },\n RIGHT: {\n x: x + width,\n y,\n width: borderSize,\n height: height,\n },\n TOPLEFT: {\n x: x - boxSize,\n y: y - boxSize,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n TOPRIGHT: {\n x: x - boxSize + width,\n y: y - boxSize,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n BOTTOMLEFT: {\n x: x - boxSize,\n y: y - boxSize + height,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n BOTTOMRIGHT: {\n x: x - boxSize + width,\n y: y - boxSize + height,\n width: boxSize * 2,\n height: boxSize * 2,\n },\n }[type];\n }\n}\n","export class AABB {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n // matrix: number[];\n\n constructor(minX: number, minY: number, maxX: number, maxY: number) {\n this.minX = minX;\n this.minY = minY;\n this.maxX = maxX;\n this.maxY = maxY;\n }\n\n getArea() {\n return (this.maxY - this.minY) * (this.maxX - this.minX);\n }\n\n static isColliding(a: AABB, b: AABB): boolean {\n return (\n a.minX <= b.maxX &&\n a.maxX >= b.minX &&\n a.minY <= b.maxY &&\n a.maxY >= b.minY\n );\n }\n}\n","import { Rect } from \"../shapes/Rect\";\nimport {\n applyMatrixToPoint,\n BASE_BLUE,\n BORDERPX,\n BoundingBoxCollisionType,\n getScalesFromMatrix,\n MARQUEE_BLUE,\n sides,\n} from \"../util\";\nimport { AABB } from \"./AABB\";\n\nconst RECT_TYPES = [\"CENTER\", ...sides] as BoundingBoxCollisionType[];\n\n/**\n * Its properties related to rendering are all stored as camera space value - will need to convert to world coordinates when used\n */\nexport class MarqueeSelectionBox {\n // move and resize based on drag\n // create the side bars and also a center piece that is coloured with alpha\n x: number;\n y: number;\n width: number = 0;\n height: number = 0;\n rects: Map<string, Rect> = new Map();\n borderSize: number = 0;\n AABB: AABB;\n\n constructor(x: number, y: number, worldMatrix: number[]) {\n const [hx, hy] = applyMatrixToPoint(worldMatrix, x, y);\n this.x = hx;\n this.y = hy;\n this.addRects();\n }\n\n private getRectConfig(type: string) {\n // height and width adjusted to cover up the corner\n let { x, y, width, height, borderSize } = this;\n return {\n TOP: {\n x,\n y,\n width: width < 0 ? width : width + borderSize,\n height: borderSize,\n },\n BOTTOM: {\n x,\n y: y + height,\n width: width < 0 ? width : width + borderSize,\n height: borderSize,\n },\n LEFT: {\n x: height < 0 && width < 0 ? x - borderSize : x,\n y,\n width: borderSize,\n height: height < 0 && width < 0 ? height : height + borderSize,\n },\n RIGHT: {\n x: x + width,\n y,\n width: borderSize,\n height: height < 0 ? height : height + borderSize,\n },\n CENTER: {\n x,\n y,\n width,\n height,\n },\n }[type];\n }\n\n render(gl: WebGLRenderingContext, program: WebGLProgram): void {\n this.update();\n\n for (const [_, rect] of this.rects.entries()) {\n rect.render(gl, program);\n }\n }\n\n update() {\n this.borderSize = BORDERPX;\n this.updateRects();\n }\n\n destroy() {\n for (const [_, rect] of this.rects.entries()) {\n rect.destroy();\n }\n }\n\n /**\n * Apply bounding box in world dimension\n * @returns\n */\n getBoundingBox(getWorldCoords: (x: number, y: number) => number[]) {\n const [wx, wy] = getWorldCoords(this.x, this.y);\n const [wW, wH] = getWorldCoords(this.x + this.width, this.y + this.height);\n\n const minX = Math.min(wx, wW);\n const maxX = Math.max(wx, wW);\n const minY = Math.min(wy, wH);\n const maxY = Math.max(wy, wH);\n\n return new AABB(minX, minY, maxX, maxY);\n }\n\n resize(dx: number, dy: number, worldMatrix: number[]) {\n const [scaleX, scaleY] = getScalesFromMatrix(worldMatrix);\n this.width += dx * scaleX;\n this.height += dy * scaleY;\n }\n\n private addRects() {\n for (const type of RECT_TYPES) {\n const config = this.getRectConfig(type);\n const rect = new Rect(config);\n rect.color = BASE_BLUE;\n this.rects.set(type, rect);\n }\n }\n\n private updateRects() {\n for (const type of RECT_TYPES) {\n const rect = this.rects.get(type);\n const config = this.getRectConfig(type);\n\n if (rect) {\n rect.setTranslation(config.x, config.y);\n rect.width = config.width;\n rect.height = config.height;\n if (type === \"CENTER\") {\n rect.color = MARQUEE_BLUE;\n }\n }\n }\n }\n}\n","import { makeObservable, observable, computed, action } from \"mobx\";\nimport { m3 } from \"../util\";\n\ninterface CameraStateOption {\n x: number;\n y: number;\n width: number;\n height: number;\n rotation: number;\n zoom: number;\n}\n\nexport class CameraState {\n x: number;\n y: number;\n width: number;\n height: number;\n rotation: number;\n zoom: number;\n\n constructor(option: Partial<CameraStateOption> = {}) {\n const {\n x = 0,\n y = 0,\n width = 0,\n height = 0,\n rotation = 0,\n zoom = 1,\n } = option;\n\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n this.rotation = rotation;\n this.zoom = zoom;\n\n makeObservable(this, {\n x: observable,\n y: observable,\n width: observable,\n height: observable,\n rotation: observable,\n zoom: observable,\n setX: action,\n setY: action,\n setPosition: action,\n incrementPosition: action,\n setWidth: action,\n setHeight: action,\n setSize: action,\n setZoom: action,\n setRotation: action,\n stateVector: computed,\n });\n }\n\n // Actions\n setX(x: number) {\n this.x = x;\n }\n\n setY(y: number) {\n this.y = y;\n }\n\n setPosition(x: number, y: number) {\n this.x = x;\n this.y = y;\n }\n\n incrementPosition(dx: number, dy: number) {\n this.x += dx;\n this.y += dy;\n }\n\n setWidth(width: number) {\n this.width = width;\n }\n\n setHeight(height: number) {\n this.height = height;\n }\n\n setSize(width: number, height: number) {\n this.width = width;\n this.height = height;\n }\n\n setZoom(zoom: number) {\n this.zoom = zoom;\n }\n\n setRotation(rotation: number) {\n this.rotation = rotation;\n }\n\n get dimension() {\n return [this.width, this.height];\n }\n\n get position() {\n return [this.x, this.y];\n }\n\n get stateVector() {\n return [this.x, this.y, this.width, this.height, this.rotation, this.zoom];\n }\n\n get translationMatrix() {\n return m3.translation(this.x, this.y);\n }\n\n get rotationMatrix() {\n return m3.rotation(this.rotation);\n }\n\n get scaleMatrix() {\n return m3.scaling(this.zoom, this.zoom);\n }\n\n get cameraMatrix() {\n const matrix = m3.multiply(this.translationMatrix, this.rotationMatrix);\n return m3.multiply(matrix, this.scaleMatrix);\n }\n\n get canvasMatrix() {\n return m3.inverse(this.cameraMatrix);\n }\n}\n","import { Rect, Renderable } from \"shapes\";\nimport { Command } from \"../history\";\nimport { MultiBoundingBox } from \"../bounding\";\n\nexport interface FlipSnapshotItem {\n ref: Rect;\n start: FlipSnapshot;\n end?: FlipSnapshot;\n}\n\nexport interface FlipSnapshot {\n x: number;\n y: number;\n sx: number;\n sy: number;\n}\n\nexport type FlipDirection = \"vertical\" | \"horizontal\";\n\nfunction applyFlip(target: Renderable, t: FlipSnapshot) {\n target.setTranslation(t.x, t.y);\n target.setScale(t.sx, t.sy);\n}\n\nexport function makeFlipCommand(\n target: Renderable,\n start: FlipSnapshot,\n end: FlipSnapshot,\n label = \"Flip\",\n): Command {\n return {\n label,\n do() {\n applyFlip(target, end);\n },\n undo() {\n applyFlip(target, start);\n },\n };\n}\n\nexport function makeMultiFlipCommand(\n entries: FlipSnapshotItem[],\n direction: FlipDirection,\n multiBoundingBox?: MultiBoundingBox,\n): Command {\n return {\n label: \"Flip\",\n do() {\n for (const e of entries) applyFlip(e.ref, e.end);\n if (multiBoundingBox) {\n multiBoundingBox.scale[direction === \"horizontal\" ? 0 : 1] *= -1;\n }\n },\n undo() {\n for (const e of entries) applyFlip(e.ref, e.start);\n if (multiBoundingBox) {\n multiBoundingBox.scale[direction === \"horizontal\" ? 0 : 1] *= -1;\n }\n },\n };\n}\n","import { Shape, Renderable } from \"shapes\";\nimport { Command } from \"../history\";\n\nexport interface TransformSnapshotItem {\n ref: Shape;\n start: TransformSnapshot;\n end?: TransformSnapshot;\n}\n\nexport interface TransformSnapshot {\n x: number;\n y: number;\n sx: number;\n sy: number;\n}\n\nfunction applyTransform(target: Renderable, t: TransformSnapshot) {\n target.setTranslation(t.x, t.y);\n target.setScale(t.sx, t.sy);\n}\n\nexport function makeTransformCommand(\n target: any,\n start: TransformSnapshot,\n end: TransformSnapshot,\n label = \"Transform\",\n): Command {\n return {\n label,\n do() {\n applyTransform(target, end);\n },\n undo() {\n applyTransform(target, start);\n },\n };\n}\n\nexport function makeMultiTransformCommand(\n entries: Array<{\n ref: any;\n start: TransformSnapshot;\n end?: TransformSnapshot;\n }>,\n label = \"Transform\",\n): Command {\n return {\n label,\n do() {\n for (const e of entries) applyTransform(e.ref, e.end);\n },\n undo() {\n for (const e of entries) applyTransform(e.ref, e.start);\n },\n };\n}\n","import { BoundingBoxCollisionType, CanvasEvent, oppositeCorner } from \"../util\";\nimport { Rect, Renderable, Shape } from \"../shapes\";\nimport { Canvas } from \"Canvas\";\nimport { Point } from \"bounding/type\";\nimport {\n AABB,\n BoundingBox,\n MarqueeSelectionBox,\n MultiBoundingBox,\n} from \"../bounding\";\nimport { CanvasHistory } from \"../history\";\nimport { makeMultiRemoveChildCommand } from \"./SceneCommand\";\nimport { FlipDirection, makeMultiFlipCommand } from \"./FlipCommand\";\nimport EventEmitter from \"eventemitter3\";\nimport { makeMultiTransformCommand } from \"./TransformCommand\";\n\nexport type AlignDirection = \"top\" | \"bottom\" | \"left\" | \"right\";\nexport type NormalizeOption = \"height\" | \"width\" | \"size\" | \"scale\";\nexport type NormalizeMode = \"first\" | \"average\";\n\nexport class SelectionManager {\n // #canvas: Canvas;\n #history: CanvasHistory;\n\n #selected: Set<Rect> = new Set();\n #boundingBoxes: Set<BoundingBox> = new Set();\n #multiBoundingBox: MultiBoundingBox;\n #marqueeSelectionBox: MarqueeSelectionBox;\n #eventHub: EventEmitter;\n\n get multiBoundingBox() {\n return this.#multiBoundingBox;\n }\n get boundingBoxes() {\n return this.#boundingBoxes;\n }\n\n #renderDirtyFlag = true;\n\n #gl: WebGLRenderingContext;\n #rectProgram: WebGLProgram;\n\n getWorldMatrix: () => number[];\n getCanvasChildren: () => Renderable[];\n getWorldCoords: (x: number, y: number) => number[];\n getMarqueeCoords: (x: number, y: number) => number[];\n\n get selected(): Rect[] {\n return Array.from(this.#selected);\n }\n set selected(shapes: Rect[]) {\n this.#selected.clear();\n\n shapes.forEach((shape) => {\n this.#selected.add(shape);\n this.#boundingBoxes.add(new BoundingBox(shape));\n });\n }\n\n get marqueeBox(): MarqueeSelectionBox {\n return this.#marqueeSelectionBox;\n }\n set marqueeBox(startingPoint: Point) {\n this.#marqueeSelectionBox = new MarqueeSelectionBox(\n startingPoint.x,\n startingPoint.y,\n this.getWorldMatrix(),\n );\n }\n\n constructor(\n history: CanvasHistory,\n eventHub: EventEmitter,\n gl: WebGLRenderingContext,\n basicShapeProgram: WebGLProgram,\n getWorldMatrix: () => number[],\n getCanvasChildren: () => Renderable[],\n getWorldCoords: (x: number, y: number) => number[],\n getMarqueeCoords: (x: number, y: number) => number[],\n ) {\n this.#gl = gl;\n this.#rectProgram = basicShapeProgram;\n this.#history = history;\n this.#eventHub = eventHub;\n this.getWorldMatrix = getWorldMatrix;\n this.getCanvasChildren = getCanvasChildren;\n this.getWorldCoords = getWorldCoords;\n this.getMarqueeCoords = getMarqueeCoords;\n\n const proto = Object.getPrototypeOf(this);\n for (const key of Object.getOwnPropertyNames(proto)) {\n const val = this[key];\n if (typeof val === \"function\" && key !== \"constructor\") {\n this[key] = val.bind(this);\n }\n }\n }\n\n // add, remove selected\n add(shapes: Rect[]) {\n shapes.forEach((shape) => {\n if (!this.#selected.has(shape)) {\n this.#selected.add(shape);\n this.#boundingBoxes.add(new BoundingBox(shape));\n }\n });\n\n if (this.#boundingBoxes.size > 1) {\n this.#boundingBoxes.forEach((box) => box.setPassive());\n\n if (!this.#multiBoundingBox) {\n this.#multiBoundingBox = new MultiBoundingBox([]);\n }\n\n this.selected.forEach((shape) => this.#multiBoundingBox.add(shape));\n }\n }\n\n remove(shapes: Rect[]) {\n shapes.forEach((shape) => {\n if (!this.#selected.has(shape)) return;\n this.#selected.delete(shape);\n const matchingBoundingBox = Array.from(this.#boundingBoxes.values()).find(\n (box) => box.target === shape,\n );\n if (matchingBoundingBox) {\n this.#boundingBoxes.delete(matchingBoundingBox);\n } else {\n console.error(\"No matching bounding box found\");\n }\n\n if (this.#multiBoundingBox) {\n this.#multiBoundingBox.remove(shape);\n }\n });\n\n if (this.#boundingBoxes.size <= 1) {\n this.#boundingBoxes.forEach((box) => box.setActive());\n this.#multiBoundingBox = null;\n }\n }\n\n deleteSelected(canvas: Canvas) {\n const toBeDeleted = [...this.#selected];\n this.remove(toBeDeleted);\n for (const selected of toBeDeleted) {\n selected.destroy();\n }\n\n this.#history.push(makeMultiRemoveChildCommand(canvas, toBeDeleted));\n }\n\n /**\n * Checks first if there is a hit in a multibounding and its handles. If not, check the one bounding box that is active.\n */\n hitTest(wx: number, wy: number): BoundingBoxCollisionType | null {\n if (this.#multiBoundingBox) {\n const ans = this.#multiBoundingBox.hitTest(wx, wy, this.getWorldMatrix());\n if (ans) return ans;\n }\n\n for (const box of this.#boundingBoxes.values()) {\n const ans = box.hitTest(wx, wy, this.getWorldMatrix());\n if (ans) return ans;\n }\n\n return null;\n }\n\n isMultiBoundingBoxHit(wx: number, wy: number) {\n return (\n this.#multiBoundingBox &&\n this.#multiBoundingBox.hitTest(wx, wy, this.getWorldMatrix())\n );\n }\n\n isBoundingBoxHit(wx: number, wy: number) {\n return (\n this.#boundingBoxes.size === 1 &&\n Array.from(this.#boundingBoxes)[0].hitTest(wx, wy, this.getWorldMatrix())\n );\n }\n\n hitTestAdjustedCorner(wx: number, wy: number) {\n if (this.#multiBoundingBox) {\n const ans = this.#multiBoundingBox.hitTest(wx, wy, this.getWorldMatrix());\n if (ans) {\n if (\n this.#multiBoundingBox.scale[0] * this.#multiBoundingBox.scale[1] <\n 0\n ) {\n return oppositeCorner(ans);\n }\n return ans;\n }\n }\n\n for (const box of this.#boundingBoxes.values()) {\n const ans = box.hitTest(wx, wy, this.getWorldMatrix());\n if (ans) {\n if (box.target.sx * box.target.sy < 0) {\n return oppositeCorner(ans);\n }\n return ans;\n }\n }\n }\n\n /**\n * Update the existing bounding boxes\n */\n update() {\n this.#boundingBoxes.forEach((box) => box.update());\n\n if (this.#multiBoundingBox) {\n this.#multiBoundingBox.update();\n }\n }\n\n render(program: WebGLProgram) {\n // Bind program and set z-up front\n if (\n !this.#marqueeSelectionBox &&\n !this.#multiBoundingBox &&\n this.#boundingBoxes.size === 0\n )\n return;\n this.#gl.useProgram(program);\n const uZLoc = this.#gl.getUniformLocation(program, \"u_z\");\n if (uZLoc) this.#gl.uniform1f(uZLoc, 1.0);\n\n // Draw everything using the same bound program\n if (this.#renderDirtyFlag) {\n this.#boundingBoxes.forEach((box) => box.render(this.#gl, program));\n }\n if (this.#multiBoundingBox) {\n this.#multiBoundingBox.render(this.#gl, program);\n }\n if (this.#marqueeSelectionBox) {\n this.#marqueeSelectionBox.render(this.#gl, program);\n }\n }\n\n isRectSelected(shape: Rect) {\n return this.#selected.has(shape);\n }\n\n clear() {\n this.#selected.clear();\n this.#boundingBoxes.clear();\n this.#multiBoundingBox = null;\n }\n\n clearMarquee() {\n if (this.#marqueeSelectionBox) {\n this.#marqueeSelectionBox = null;\n }\n }\n\n move(dx: number, dy: number) {\n if (this.#multiBoundingBox) {\n this.#multiBoundingBox.move(dx, dy);\n } else {\n for (const box of this.#boundingBoxes) {\n box.move(dx, dy);\n }\n }\n this.#eventHub.emit(CanvasEvent.Change);\n }\n\n /**\n * Based on the corner you're dragging and the sign of the scaleX and scaleY values, there are only four possible sets of changes to the target's translation.\n * 1) absolutely no change\n * 2) x translation change only if negative delta\n * 3) y translation change only if negative delta\n * 4) x and y translation change if negative delta\n * The tricky part is to consider the signs of the scale values and determine which corner is going to inhabit which behaviour.\n * @param dx\n * @param dy\n * @param direction\n */\n resize(dx: number, dy: number, direction: BoundingBoxCollisionType) {\n if (this.multiBoundingBox) {\n this.multiBoundingBox.resize(dx, dy, direction, this.getWorldMatrix());\n }\n\n for (const box of this.boundingBoxes) {\n if (this.multiBoundingBox) {\n box.update();\n } else {\n box.resize(dx, dy, direction);\n }\n }\n this.#eventHub.emit(CanvasEvent.Change);\n }\n\n flip(direction: FlipDirection) {\n if (this.multiBoundingBox) {\n const transformArray = this.multiBoundingBox.flip(\n this.getWorldMatrix(),\n direction,\n this.getWorldCoords,\n );\n this.#history.push(\n makeMultiFlipCommand(transformArray, direction, this.multiBoundingBox),\n );\n } else {\n const transformArray = [];\n for (const box of this.boundingBoxes) {\n transformArray.push(box.flip(direction));\n }\n\n this.#history.push(makeMultiFlipCommand(transformArray, direction));\n }\n this.#eventHub.emit(CanvasEvent.Change);\n }\n\n alignSelection(direction: AlignDirection) {\n if (!this.multiBoundingBox) return;\n const transformations = this.multiBoundingBox.align(direction);\n this.#history.push(makeMultiTransformCommand(transformations));\n this.#eventHub.emit(CanvasEvent.Change);\n }\n\n normalize(type: NormalizeOption, mode: NormalizeMode = \"first\") {\n if (!this.multiBoundingBox) return;\n const transformations = this.multiBoundingBox.normalize(type, mode);\n this.#history.push(makeMultiTransformCommand(transformations));\n this.#eventHub.emit(CanvasEvent.Change);\n }\n\n onPointerMove(\n x: number,\n y: number,\n dx: number,\n dy: number,\n resizeDirection: BoundingBoxCollisionType,\n getGlobalClick: () => boolean,\n updateCameraPos: (x: number, y: number) => void,\n getWorldMatrix: () => number[],\n ) {\n if (getGlobalClick()) {\n updateCameraPos(x, y);\n } else if (resizeDirection && resizeDirection !== \"CENTER\") {\n this.resize(dx, dy, resizeDirection);\n } else if (this.marqueeBox) {\n this.marqueeBox.resize(dx, dy, getWorldMatrix());\n\n // use the four corners to check if there are any new entry\n const children = this.getCanvasChildren();\n const marqueeBox = this.marqueeBox.getBoundingBox(this.getMarqueeCoords);\n for (const child of children) {\n const box = (child as Rect).getBoundingBox();\n if (\n AABB.isColliding(box, marqueeBox) &&\n !this.#selected.has(child as Rect)\n ) {\n this.add([child as Rect]);\n } else if (\n !AABB.isColliding(box, marqueeBox) &&\n this.#selected.has(child as Rect)\n ) {\n this.remove([child as Rect]);\n }\n }\n } else {\n this.move(dx, dy);\n }\n }\n\n onSelectionPointerDown(\n isShiftKey: boolean,\n child: Shape,\n wx: number,\n wy: number,\n ) {\n if (child) {\n if (!isShiftKey) {\n this.clear();\n }\n this.add([child as Rect]);\n } else {\n this.clear();\n if (this.marqueeBox) {\n this.clearMarquee();\n } else {\n this.marqueeBox = { x: wx, y: wy };\n }\n }\n }\n\n // keep this for exporting as image in the future\n // async copy() {\n // const images = this.selected as Img[];\n // if (images.length === 0) return;\n\n // let blob: Blob;\n\n // if (images.length === 1 && images[0].src.startsWith('data:image/png')) {\n // // Fast path: already a PNG data URL\n // const [header, base64] = images[0].src.split(',');\n // const binary = atob(base64);\n // const array = new Uint8Array(binary.length);\n // for (let i = 0; i < binary.length; i++) array[i] = binary.charCodeAt(i);\n // blob = new Blob([array], { type: 'image/png' });\n // } else {\n // // Batch draw all images to an offscreen canvas\n // const { mergedCanvas, width, height } = await mergeImagesToCanvas(images);\n // blob = await new Promise<Blob>(resolve => mergedCanvas.toBlob(b => resolve(b), 'image/png'));\n // }\n\n // const storedItem = new ClipboardItem({ [blob.type]: blob });\n // try {\n // await navigator.clipboard.write([storedItem]);\n // } catch (err) {\n // console.error(err);\n // }\n // }\n}\n","import { Img } from \"../shapes/Img\";\nimport { Rect } from \"../shapes/Rect\";\nimport { Renderable } from \"../shapes/Renderable\";\nimport { Shape } from \"../shapes/Shape\";\nimport {\n BoundingBoxCollisionType,\n ContextMenuEvent,\n copy,\n LoaderEvent,\n} from \"../util\";\nimport { PointerEventState } from \"../state\";\nimport { CanvasHistory } from \"../history\";\nimport {\n makeMultiTransformCommand,\n TransformSnapshot,\n} from \"./TransformCommand\";\nimport EventEmitter from \"eventemitter3\";\n\nexport enum PointerMode {\n SELECT,\n PAN,\n}\n\nconst cursorMap: Record<string, string> = {\n TOP: \"ns-resize\",\n BOTTOM: \"ns-resize\",\n LEFT: \"ew-resize\",\n RIGHT: \"ew-resize\",\n TOPLEFT: \"nwse-resize\",\n BOTTOMRIGHT: \"nwse-resize\",\n TOPRIGHT: \"nesw-resize\",\n BOTTOMLEFT: \"nesw-resize\",\n CENTER: \"grab\",\n};\n\ninterface PointerEventManagerDeps {\n history: CanvasHistory;\n eventHub: EventEmitter;\n state: PointerEventState;\n isContextMenuActive: () => boolean;\n getSelected: () => Renderable[];\n getChildren: () => Renderable[];\n getWorldMatrix: () => number[];\n getCanvasGlobalClick: () => boolean;\n setCanvasGlobalClick: (val: boolean) => void;\n getWorldCoords: (x: number, y: number) => number[];\n updateCameraPos: (x: number, y: number) => void;\n onWheel: (e: WheelEvent) => void;\n setCursorStyle: (val: string) => void;\n paste: (x: number, y: number) => Promise<void>;\n closeMarquee: () => void;\n assignEventListener: (\n type: string,\n fn: (() => void) | ((e: any) => void),\n options?: boolean | AddEventListenerOptions,\n ) => void;\n selectionPointerMove: (\n x: number,\n y: number,\n dx: number,\n dy: number,\n resizeDirection: BoundingBoxCollisionType,\n ) => void;\n onSelectionPointerDown: (\n isShiftKey: boolean,\n child: Shape,\n wx: number,\n wy: number,\n ) => void;\n checkIfSelectionHit: (\n x: number,\n y: number,\n ) => BoundingBoxCollisionType | null;\n addSelection: (rects: Rect[]) => void;\n clearSelection: () => void;\n isSelection: (rect: Rect) => boolean;\n hitTestAdjustedCorner: (x: number, y: number) => BoundingBoxCollisionType;\n}\n\nexport class PointerEventManager {\n state: PointerEventState;\n history: CanvasHistory;\n eventHub: EventEmitter;\n\n isContextMenuActive: () => boolean;\n\n getSelected: () => Renderable[];\n onSelectionPointerDown: (\n isShiftKey: boolean,\n child: Shape,\n wx: number,\n wy: number,\n ) => void;\n selectionPointerMove: (\n x: number,\n y: number,\n dx: number,\n dy: number,\n resizingDirection: BoundingBoxCollisionType,\n ) => void;\n checkIfSelectionHit: (\n x: number,\n y: number,\n ) => BoundingBoxCollisionType | null;\n addSelection: (rects: Rect[]) => void;\n clearSelection: () => void;\n isSelection: (rect: Rect) => boolean;\n\n getChildren: () => Renderable[];\n\n setCursorStyle: (s: string) => void;\n setCanvasGlobalClick: (val: boolean) => void;\n getWorldCoords: (x: number, y: number) => number[];\n closeMarquee: () => void;\n hitTestAdjustedCorner: (x: number, y: number) => BoundingBoxCollisionType;\n assignEventListener: (\n type: string,\n fn: (() => void) | ((e: any) => void),\n options?: boolean | AddEventListenerOptions,\n ) => void;\n\n private currentTransform?: {\n targets: Array<{ ref: Rect; start: TransformSnapshot }>;\n };\n\n constructor(deps: Partial<PointerEventManagerDeps>) {\n for (const key in deps) {\n if (key in deps && deps[key] !== undefined) {\n this[key] = deps[key];\n }\n }\n\n // bind methods\n this.onPointerDown = this.onPointerDown.bind(this);\n this.onPointerMoveWhileDown = this.onPointerMoveWhileDown.bind(this);\n this.onPointerUp = this.onPointerUp.bind(this);\n\n // register event listeners\n this.addOnPointerMove();\n this.addOnWheel(deps.onWheel);\n this.addOnPointerDown();\n\n window.addEventListener(\"copy\", async (e) => {\n e.preventDefault();\n if (this.isContextMenuActive()) return;\n\n await copy(this.getSelected() as Img[]);\n });\n\n window.addEventListener(\"paste\", async (e) => {\n e.preventDefault();\n if (this.isContextMenuActive()) return;\n await deps.paste(\n this.state.lastPointerPos.x,\n this.state.lastPointerPos.y,\n );\n });\n }\n\n changeMode() {\n this.state.toggleMode();\n }\n\n // Add events\n private addOnPointerDown() {\n this.assignEventListener(\"pointerdown\", this.onPointerDown);\n }\n\n private addOnPointerMove() {\n this.assignEventListener(\"pointermove\", (e) => {\n [this.state.lastPointerPos.x, this.state.lastPointerPos.y] =\n this.getWorldCoords(e.clientX, e.clientY);\n\n let hit = this.hitTestAdjustedCorner(\n this.state.lastPointerPos.x,\n this.state.lastPointerPos.y,\n );\n this.setCursorStyle(cursorMap[hit] || \"default\");\n });\n }\n\n private addOnWheel(onWheel: (e: WheelEvent) => void) {\n this.assignEventListener(\n \"wheel\",\n (e) => {\n if (!this.isContextMenuActive()) {\n onWheel(e);\n }\n },\n { passive: false },\n );\n }\n\n private onPointerDown(e: PointerEvent) {\n e.stopPropagation();\n e.preventDefault();\n this.eventHub.emit(ContextMenuEvent.Close);\n\n const [wx, wy] = this.getWorldCoords(e.clientX, e.clientY);\n this.state.initialize(wx, wy);\n\n this.currentTransform = undefined;\n\n if (this.state.mode === PointerMode.PAN) {\n this.handlePanPointerDown();\n } else if (this.state.mode === PointerMode.SELECT) {\n this.handleSelectPointerDown(e, wx, wy);\n }\n\n document.addEventListener(\"pointermove\", this.onPointerMoveWhileDown);\n document.addEventListener(\"pointerup\", this.onPointerUp);\n }\n\n private handlePanPointerDown() {\n this.setCanvasGlobalClick(true);\n this.clearSelection();\n }\n\n private handleSelectPointerDown(e: MouseEvent, wx: number, wy: number) {\n this.setCanvasGlobalClick(false);\n const child = this.checkCollidingChild(wx, wy);\n const boundingBoxType = this.checkIfSelectionHit(wx, wy);\n\n if (e.button === 2) {\n if (!boundingBoxType) {\n this.clearSelection();\n }\n\n if (child && !this.isSelection(child as Rect)) {\n this.addSelection([child as Rect]);\n }\n } else {\n if (boundingBoxType) {\n this.state.resizingDirection = boundingBoxType;\n } else {\n this.onSelectionPointerDown(e.shiftKey, child, wx, wy);\n }\n\n const selected = this.getSelected() as Rect[];\n if (selected.length) {\n this.currentTransform = {\n targets: selected.map((ref) => ({\n ref,\n start: { x: ref.x, y: ref.y, sx: ref.sx, sy: ref.sy },\n })),\n };\n }\n }\n }\n\n private onPointerMoveWhileDown(e: PointerEvent) {\n // in move, the buttons property is checked\n if (e.buttons === 2) return;\n const [wx, wy] = this.getWorldCoords(e.clientX, e.clientY);\n const dx = wx - this.state.lastWorldX;\n const dy = wy - this.state.lastWorldY;\n\n this.selectionPointerMove(\n this.state.startWorldX - wx,\n this.state.startWorldY - wy,\n dx,\n dy,\n this.state.resizingDirection,\n );\n\n this.state.updateLastWorldCoord(wx, wy);\n this.setCursorStyle(\"grabbing\");\n }\n\n private onPointerUp() {\n document.removeEventListener(\"pointermove\", this.onPointerMoveWhileDown);\n document.removeEventListener(\"pointerup\", this.onPointerUp);\n this.setCanvasGlobalClick(true);\n this.setCursorStyle(\"default\");\n\n if (this.currentTransform) {\n const entries = this.currentTransform.targets\n .map((t) => ({\n ref: t.ref,\n start: t.start,\n end: { x: t.ref.x, y: t.ref.y, sx: t.ref.sx, sy: t.ref.sy },\n }))\n .filter(\n (e) =>\n e.start.x !== e.end.x ||\n e.start.y !== e.end.y ||\n e.start.sx !== e.end.sx ||\n e.start.sy !== e.end.sy,\n );\n if (entries.length) {\n this.history.push(makeMultiTransformCommand(entries));\n }\n }\n this.currentTransform = undefined;\n this.state.resizingDirection = null;\n\n this.closeMarquee();\n\n this.eventHub.emit(\"save\");\n }\n\n private checkCollidingChild(wx: number, wy: number) {\n const children = this.getChildren();\n for (let i = children.length - 1; i >= 0; i--) {\n const child = children[i];\n if (child instanceof Shape) {\n if (child.hitTest && child.hitTest(wx, wy)) {\n return child;\n }\n }\n }\n return null;\n }\n}\n","import { CanvasEvent } from \"../util\";\nimport { CanvasHistory } from \"../history\";\nimport EventEmitter from \"eventemitter3\";\n\nexport class KeyEventManager {\n history: CanvasHistory;\n assignEventListener: (\n type: string,\n fn: (() => void) | ((e: any) => void),\n options?: boolean | AddEventListenerOptions,\n ) => void;\n deleteSelected: () => void;\n save: () => void;\n\n constructor(\n history: CanvasHistory,\n eventHub: EventEmitter,\n deleteSelected: () => void,\n assignEventListener: (\n type: string,\n fn: (() => void) | ((e: any) => void),\n options?: boolean | AddEventListenerOptions,\n ) => void,\n ) {\n this.history = history;\n this.deleteSelected = deleteSelected;\n this.save = () => eventHub.emit(CanvasEvent.Save);\n this.assignEventListener = assignEventListener;\n\n this.onKeyPressed = this.onKeyPressed.bind(this);\n this.addOnKeyPressed();\n }\n\n private addOnKeyPressed() {\n document.addEventListener(\"keydown\", this.onKeyPressed);\n }\n\n private onKeyPressed(e: KeyboardEvent) {\n if (this.isCtrlZ(e)) {\n e.preventDefault();\n this.history.undo();\n return;\n }\n\n if (this.isCtrlY(e)) {\n e.preventDefault();\n this.history.redo();\n return;\n }\n\n if (this.isDelete(e)) {\n this.deleteSelected();\n return;\n }\n\n if (this.isSave(e)) {\n e.preventDefault();\n this.save();\n return;\n }\n }\n\n private isCtrlZ(e: KeyboardEvent): boolean {\n const key = e.key.toLowerCase();\n return key === \"z\" && (e.ctrlKey || e.metaKey) && !e.shiftKey;\n }\n\n private isCtrlY(e: KeyboardEvent): boolean {\n const key = e.key.toLowerCase();\n return key === \"y\" && (e.ctrlKey || e.metaKey) && !e.shiftKey;\n }\n\n private isDelete(e: KeyboardEvent): boolean {\n return e.key === \"Delete\";\n }\n\n private isSave(e: KeyboardEvent): boolean {\n const key = e.key.toLowerCase();\n return key === \"s\" && e.ctrlKey;\n }\n}\n","import { BoundingBoxCollisionType } from \"../util\";\nimport { ContextMenuEvent } from \"../util/customEventType\";\nimport EventEmitter from \"eventemitter3\";\n\nexport class ContextMenuManager {\n copy: (e: ClipboardEvent) => Promise<void>;\n paste: (e: ClipboardEvent) => Promise<void>;\n customContextMenu: (e: PointerEvent) => void;\n #isMenuActive: boolean = false;\n\n get isActive() {\n return this.#isMenuActive;\n }\n\n constructor(\n eventHub: EventEmitter,\n isMultiBoundingBoxHit: (\n x: number,\n y: number,\n ) => BoundingBoxCollisionType | \"\",\n isBoundingBoxHit: (x: number, y: number) => BoundingBoxCollisionType | \"\",\n getWorldCoords: (x: number, y: number) => number[],\n assignEventListener: (\n type: string,\n fn: (() => void) | ((e: any) => void),\n options?: boolean | AddEventListenerOptions,\n ) => void,\n ) {\n this.customContextMenu = (e: PointerEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n // only show context menu when there is collision with a child object, otherwise clear it\n const [wx, wy] = getWorldCoords(e.clientX, e.clientY);\n\n // show different context menu depending on what is being selected\n if (isMultiBoundingBoxHit(wx, wy)) {\n eventHub.emit(ContextMenuEvent.Open, e.clientX, e.clientY, \"multi\");\n } else if (isBoundingBoxHit(wx, wy)) {\n eventHub.emit(ContextMenuEvent.Open, e.clientX, e.clientY);\n } else {\n eventHub.emit(ContextMenuEvent.Open, e.clientX, e.clientY, \"canvas\");\n }\n };\n\n eventHub.on(ContextMenuEvent.Open, () => {\n this.#isMenuActive = true;\n });\n\n eventHub.on(ContextMenuEvent.Close, () => {\n this.#isMenuActive = false;\n });\n\n assignEventListener(\"contextmenu\", this.customContextMenu);\n }\n}\n","import { Shape, Renderable } from \"shapes\";\nimport { Command } from \"../history\";\n\nexport interface OrderSnapshotItem {\n ref: Shape;\n start: OrderSnapshot;\n end?: OrderSnapshot;\n}\n\nexport interface OrderSnapshot {\n renderOrder: number;\n}\n\nfunction apply(target: Renderable, t: OrderSnapshot) {\n (target as Shape).renderOrder = t.renderOrder;\n}\n\nexport function makeOrderCommand(\n target: Renderable,\n start: OrderSnapshot,\n end: OrderSnapshot,\n label = \"Order\",\n): Command {\n return {\n label,\n do() {\n apply(target, end);\n },\n undo() {\n apply(target, start);\n },\n };\n}\n\nexport function makeMultiOrderCommand(\n entries: Array<{ ref: any; start: OrderSnapshot; end?: OrderSnapshot }>,\n label = \"Order\",\n): Command {\n return {\n label,\n do() {\n for (const e of entries) apply(e.ref, e.end);\n },\n undo() {\n for (const e of entries) apply(e.ref, e.start);\n },\n };\n}\n","import { BoundingBoxCollisionType } from \"../util\";\nimport { PointerMode } from \"../manager\";\nimport { Point } from \"../bounding\";\n\nexport class PointerEventState {\n lastPointerPos: Point = { x: 0, y: 0 };\n startWorldX: number = 0;\n startWorldY: number = 0;\n lastWorldX: number = 0;\n lastWorldY: number = 0;\n\n mode: PointerMode;\n\n resizingDirection: BoundingBoxCollisionType | null = null;\n\n constructor(mode: PointerMode = PointerMode.SELECT) {\n this.mode = mode;\n }\n\n // computed\n get isResizing() {\n return this.resizingDirection !== null;\n }\n\n get dragDXFromStart() {\n return this.lastWorldX - this.startWorldX;\n }\n\n get dragDYFromStart() {\n return this.lastWorldY - this.startWorldY;\n }\n\n // actions\n setMode(mode: PointerMode) {\n this.mode = mode;\n }\n\n toggleMode() {\n this.mode =\n this.mode === PointerMode.PAN ? PointerMode.SELECT : PointerMode.PAN;\n }\n\n setResizingDirection(dir: BoundingBoxCollisionType | null) {\n this.resizingDirection = dir;\n }\n\n clearResizingDirection() {\n this.resizingDirection = null;\n }\n\n // Start an interaction at given world coords\n initialize(worldX: number, worldY: number) {\n this.startWorldX = worldX;\n this.startWorldY = worldY;\n this.lastWorldX = worldX;\n this.lastWorldY = worldY;\n this.resizingDirection = null;\n }\n\n updateLastWorldCoord(x: number, y: number) {\n this.lastWorldX = x;\n this.lastWorldY = y;\n }\n}\n","import { makeObservable, observable, computed, action } from \"mobx\";\nimport { Renderable } from \"../shapes\";\nimport { m3 } from \"../util\";\n\nexport class RenderableState {\n translation: number[] = [0, 0];\n angleRadians: number = 0;\n scale: number[] = [1, 1];\n\n localMatrix: number[] = m3.identity(); // manage local transformation, like rotate, scale and pan\n worldMatrix: number[] = m3.identity(); // holds the transformation combining local transformation and parent transformation\n\n children: Renderable[] = [];\n parent: Renderable | null = null;\n renderDirtyFlag: boolean = true; // reduces constant work to re-render if there are no changes\n\n constructor() {\n makeObservable<this, \"renderDirtyFlag\">(this, {\n translation: observable.struct,\n angleRadians: observable,\n scale: observable.struct,\n localMatrix: observable.ref,\n worldMatrix: observable.ref,\n children: observable.shallow,\n parent: observable.ref,\n renderDirtyFlag: observable,\n\n x: computed,\n y: computed,\n scaleX: computed,\n scaleY: computed,\n dirty: computed,\n\n setTranslation: action,\n setScale: action,\n flipVertical: action,\n setAngle: action,\n getChild: action,\n appendChild: action,\n appendChildren: action,\n removeChild: action,\n clearChildren: action,\n setParent: action,\n markDirty: action,\n clearDirty: action,\n updateLocalMatrix: action,\n updateWorldMatrix: action,\n setWorldMatrix: action,\n });\n this.updateLocalMatrix();\n this.updateWorldMatrix();\n }\n\n // Computed\n get x() {\n return this.translation[0];\n }\n get y() {\n return this.translation[1];\n }\n get scaleX() {\n return this.scale[0];\n }\n get scaleY() {\n return this.scale[1];\n }\n get dirty() {\n return this.renderDirtyFlag;\n }\n\n // Actions\n setTranslation(x: number, y: number) {\n this.translation[0] = x;\n this.translation[1] = y;\n this.markDirty();\n }\n\n updateTranslation(x: number, y: number) {\n this.translation[0] += x;\n this.translation[1] += y;\n this.markDirty();\n }\n\n setScale(sx: number, sy: number) {\n if (sx === this.scale[0] && sy === this.scale[1]) return;\n this.scale[0] = sx;\n this.scale[1] = sy;\n this.markDirty();\n }\n\n updateScale(x: number, y: number) {\n this.scale[0] *= x;\n this.scale[1] *= y;\n this.markDirty();\n }\n\n flipVertical(imageHeight: number) {\n this.translation[1] += this.scale[1] * imageHeight;\n this.scale[1] *= -1;\n this.markDirty();\n }\n\n flipHorizontal(imageWidth: number) {\n this.translation[0] += this.scale[0] * imageWidth;\n this.scale[0] *= -1;\n this.markDirty();\n }\n\n setAngle(rotationDegree: number) {\n const angleInDegrees = 360 - rotationDegree;\n const radians = (angleInDegrees * Math.PI) / 180;\n\n if (radians === this.angleRadians) return;\n this.angleRadians = radians;\n this.markDirty();\n }\n\n getChild(i: number) {\n return this.children[i];\n }\n\n appendChild(child: Renderable) {\n if (this.children.includes(child)) return;\n this.children.push(child);\n this.markDirty();\n }\n\n appendChildren(children: Renderable[]) {\n for (const child of children) {\n if (this.children.includes(child)) return;\n this.children.push(child);\n }\n this.markDirty();\n }\n\n removeChild(child: Renderable) {\n const i = this.children.indexOf(child);\n if (i < 0) return;\n const removedChildren = this.children.splice(i, 1);\n child.state.setParent(null);\n this.markDirty();\n\n return removedChildren[0];\n }\n\n clearChildren() {\n if (this.children) {\n for (const child of this.children) {\n child.destroy();\n }\n this.children = [];\n this.markDirty();\n }\n }\n\n setParent(parent: Renderable | null) {\n if (this.parent === parent) return;\n this.parent = parent;\n this.markDirty();\n }\n\n markDirty() {\n if (!this.renderDirtyFlag) {\n this.renderDirtyFlag = true;\n this.updateLocalMatrix();\n }\n }\n\n clearDirty() {\n if (this.renderDirtyFlag) {\n this.renderDirtyFlag = false;\n this.updateLocalMatrix();\n }\n }\n\n updateLocalMatrix() {\n const t = m3.translation(this.translation[0], this.translation[1]);\n const r = m3.rotation(this.angleRadians);\n const s = m3.scaling(this.scale[0], this.scale[1]);\n // Order: T * R * S (adjust if needed)\n this.localMatrix = m3.multiply(m3.multiply(t, r), s);\n }\n\n updateWorldMatrix(parentWorldMatrix?: number[]) {\n this.worldMatrix = parentWorldMatrix\n ? m3.multiply(parentWorldMatrix, this.localMatrix)\n : this.localMatrix.slice();\n\n const worldMatrix = this.worldMatrix;\n this.children.forEach((child) => {\n child.updateWorldMatrix(worldMatrix);\n });\n }\n\n setWorldMatrix(worldMatrix: number[]) {\n this.worldMatrix = worldMatrix;\n }\n}\n","import EventEmitter from \"eventemitter3\";\nimport { RenderableState } from \"../state\";\n\nexport abstract class Renderable {\n state: RenderableState;\n\n get x() {\n return this.state.x;\n }\n get y() {\n return this.state.y;\n }\n get sx() {\n return this.state.scaleX;\n }\n get sy() {\n return this.state.scaleY;\n }\n get dirty() {\n return this.state.dirty;\n }\n get localMatrix() {\n return this.state.localMatrix;\n }\n get worldMatrix() {\n return this.state.worldMatrix;\n }\n get children() {\n return this.state.children;\n }\n get parent() {\n return this.state.parent;\n }\n get angleRadians() {\n return this.state.angleRadians;\n }\n\n updateTranslation(x: number, y: number) {\n this.state.updateTranslation(x, y);\n }\n setTranslation(x: number, y: number) {\n this.state.setTranslation(x, y);\n }\n updateScale(x: number, y: number) {\n this.state.updateScale(x, y);\n }\n setScale(x: number, y: number) {\n this.state.setScale(x, y);\n }\n setAngle(rotationDegree: number) {\n return this.state.setAngle(rotationDegree);\n }\n flipVertical(height: number) {\n this.state.flipVertical(height);\n }\n flipHorizontal(width: number) {\n this.state.flipHorizontal(width);\n }\n\n markDirty() {\n this.state.markDirty();\n }\n clearDirty() {\n this.state.clearDirty();\n }\n\n updateLocalMatrix() {\n this.state.updateLocalMatrix();\n }\n setWorldMatrix(matrix: number[]) {\n this.state.setWorldMatrix(matrix);\n }\n\n addChild(child: Renderable) {\n this.state.appendChild(child);\n }\n addParent(parent: Renderable | null) {\n return this.state.setParent(parent);\n }\n clearChildren() {\n return this.state.clearChildren();\n }\n\n _emitter: EventEmitter;\n\n constructor() {\n this.state = new RenderableState();\n\n this.setWorldMatrix = this.setWorldMatrix.bind(this);\n this.updateWorldMatrix = this.updateWorldMatrix.bind(this);\n }\n\n appendChild<T extends Renderable>(child: T): T {\n child.setParent(this);\n if (!child._emitter && this._emitter) child._emitter = this._emitter;\n return child;\n }\n\n setParent(parent: Renderable | null) {\n if (this.parent) {\n const i = this.parent.children.indexOf(this);\n if (i >= 0) this.parent.children.splice(i, 1);\n }\n if (parent) parent.addChild(this);\n this.addParent(parent);\n }\n\n updateWorldMatrix(parentWorldMatrix?: number[]) {\n this.updateLocalMatrix();\n this.state.updateWorldMatrix(parentWorldMatrix);\n }\n\n abstract render(gl: WebGLRenderingContext, program: WebGLProgram): void;\n abstract destroy(): void;\n abstract hitTest(x: number, y: number): boolean;\n\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ) {\n const fn =\n typeof listener === \"function\"\n ? (listener as EventListener)\n : (listener as EventListenerObject).handleEvent.bind(listener);\n this._emitter.on(type, fn);\n }\n\n removeEventListener(\n type: string,\n listener?: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ) {}\n\n dispatchEvent(e: Event) {\n this._emitter.emit(e.type, e);\n return !e.defaultPrevented;\n }\n}\n\nexport abstract class WebGLRenderable extends Renderable {\n protected positionBuffer?: WebGLBuffer;\n protected attributeLocation?: number;\n protected initialized = false;\n protected vertexArray?: Float32Array;\n\n protected resolutionLocation?: WebGLUniformLocation;\n protected matrixLocation?: WebGLUniformLocation;\n\n abstract getPositions(): number[] | Float32Array;\n\n updateVertexData(gl: WebGLRenderingContext) {\n const positions = this.getPositions();\n\n if (!this.vertexArray || this.vertexArray.length !== positions.length) {\n this.vertexArray = new Float32Array(positions.length);\n }\n\n this.vertexArray.set(positions);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer!);\n gl.bufferData(gl.ARRAY_BUFFER, this.vertexArray, gl.STATIC_DRAW);\n }\n\n protected setUpVertexData(gl: WebGLRenderingContext, program: WebGLProgram) {\n if (!this.positionBuffer) {\n this.positionBuffer = gl.createBuffer();\n }\n this.attributeLocation = gl.getAttribLocation(program, \"a_position\");\n }\n\n protected setUpUniforms(gl: WebGLRenderingContext, program: WebGLProgram) {\n this.resolutionLocation = gl.getUniformLocation(program, \"u_resolution\");\n this.matrixLocation = gl.getUniformLocation(program, \"u_matrix\");\n }\n\n protected updateUniforms(gl: WebGLRenderingContext) {\n gl.uniform2f(this.resolutionLocation, gl.canvas.width, gl.canvas.height);\n gl.uniformMatrix3fv(this.matrixLocation, false, this.worldMatrix);\n }\n}\n","import { AABB } from \"../bounding/AABB\";\nimport { WebGLRenderable } from \"./Renderable\";\n\nexport interface BoundingVal {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport abstract class Shape extends WebGLRenderable {\n private static _seqCounter = 0;\n private readonly _seq = Shape._seqCounter++;\n\n culled = false;\n\n private _renderOrder: number = 0;\n abstract getVertexCount(): number;\n\n constructor(x: number, y: number, sx: number = 1, sy: number = 1) {\n super();\n this.setTranslation(x, y);\n this.setScale(sx, sy);\n }\n\n get renderOrder() {\n return this._renderOrder;\n }\n set renderOrder(v: number) {\n if (this._renderOrder !== v) {\n this._renderOrder = v;\n this.markDirty();\n }\n }\n\n get seq() {\n return this._seq;\n }\n\n abstract getEdge(): BoundingVal;\n abstract getBoundingBox(): AABB;\n\n getZ(): number {\n const step = 0.0001;\n const z = this.renderOrder * step + 0.5;\n return Math.max(0.0, Math.min(1.0, z));\n }\n\n color: [number, number, number, number] = [1, 0, 0.5, 1];\n\n render(gl: WebGLRenderingContext, program: WebGLProgram): void {\n this.updateWorldMatrix(this.parent ? this.parent.worldMatrix : undefined);\n gl.useProgram(program);\n\n if (this.dirty && !this.culled) {\n if (!this.initialized) {\n this.setUpVertexData(gl, program);\n this.setUpUniforms(gl, program);\n this.initialized = true;\n }\n this.updateVertexData(gl);\n this.clearDirty();\n }\n this.updateUniforms(gl);\n const uColor = gl.getUniformLocation(program, \"u_color\");\n if (uColor) {\n gl.uniform4fv(uColor, this.color);\n }\n if (!this.culled) this.draw(gl);\n }\n\n protected draw(gl: WebGLRenderingContext) {\n gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);\n\n // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)\n const size = 2; // 2 components per iteration since it's a vec2D\n const type = gl.FLOAT; // the data is 32bit floats\n const normalize = false; // don't normalize the data\n const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position\n const offset = 0; // start at the beginning of the buffer\n gl.vertexAttribPointer(\n this.attributeLocation,\n size,\n type,\n normalize,\n stride,\n offset,\n );\n\n gl.enableVertexAttribArray(this.attributeLocation);\n\n gl.drawArrays(gl.TRIANGLES, 0, this.getVertexCount());\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.disableVertexAttribArray(this.attributeLocation);\n }\n\n destroy() {\n if (this.positionBuffer) {\n this.positionBuffer = undefined;\n }\n this.initialized = false;\n }\n}\n","import { AABB } from \"../bounding\";\nimport {\n getScalesFromMatrix,\n applyMatrixToPoint,\n isScalePositive,\n} from \"../util\";\nimport { Shape } from \"./Shape\";\n\nexport class Rect extends Shape {\n // these are not going to change throughout the lifetime as scale is going to be the one changing their visual\n private _width: number;\n private _height: number;\n AABB: AABB;\n\n constructor(\n config: Partial<{\n x: number;\n y: number;\n width: number;\n height: number;\n sx?: number;\n sy?: number;\n }>,\n ) {\n super(config.x, config.y, config.sx, config.sy);\n this._width = config.width ?? 100;\n this._height = config.height ?? 100;\n }\n\n get width() {\n return this._width;\n }\n set width(value: number) {\n if (this._width !== value) {\n this._width = value;\n this.markDirty();\n }\n }\n\n get height() {\n return this._height;\n }\n set height(value: number) {\n if (this._height !== value) {\n this._height = value;\n this.markDirty();\n }\n }\n\n getVertexCount(): number {\n return 6;\n }\n\n getPositions(): number[] {\n const left = 0;\n const top = 0;\n const right = this.width;\n const bottom = this.height;\n\n return [\n left,\n top, // top-left\n left,\n bottom, // bottom-left\n right,\n top, // top-right\n right,\n top, // top-right\n left,\n bottom, // bottom-left\n right,\n bottom, // bottom-right\n ];\n }\n\n /**\n *\n * @returns A bounding box that is not adjusted for world space.\n */\n getBoundingBox() {\n // due to possible flips, the original width could be flipped by the scale value and become lesser the its translation[0]\n const x0 = this.state.translation[0];\n const x1 = x0 + this.width * this.state.scaleX;\n const y0 = this.state.translation[1];\n const y1 = y0 + this.height * this.state.scaleY;\n\n const minX = Math.min(x0, x1);\n const maxX = Math.max(x0, x1);\n const minY = Math.min(y0, y1);\n const maxY = Math.max(y0, y1);\n\n this.AABB = new AABB(minX, minY, maxX, maxY);\n return this.AABB;\n }\n\n getEdge() {\n const x = this.x,\n y = this.y;\n return {\n minX: Math.min(x, x + this.width),\n maxX: Math.max(x, x + this.width),\n minY: Math.min(y, y + this.height),\n maxY: Math.max(y, y + this.height),\n };\n }\n\n hitTest(x: number, y: number): boolean {\n const [scaleX, scaleY] = getScalesFromMatrix(this.worldMatrix);\n const [signX, signY] = isScalePositive(this.worldMatrix);\n\n // Transform the input point to the rectangle's local space\n const [hx, hy] = applyMatrixToPoint(this.parent.worldMatrix, x, y);\n const [cx, cy] = applyMatrixToPoint(this.worldMatrix);\n\n const w = this.width * scaleX * signX;\n const h = this.height * scaleY * signY;\n\n const minX = Math.min(cx, cx + w);\n const maxX = Math.max(cx, cx + w);\n const minY = Math.min(cy, cy + h);\n const maxY = Math.max(cy, cy + h);\n\n return hx >= minX && hx <= maxX && hy >= minY && hy <= maxY;\n }\n}\n","import { AABB } from \"../bounding\";\nimport { Rect } from \"./Rect\";\n\nexport class Img extends Rect {\n private texcoordBuffer?: WebGLBuffer;\n private texcoordLocation?: number;\n private samplerLocation?: WebGLUniformLocation;\n private texture?: WebGLTexture;\n private lowResTexture?: WebGLTexture;\n private gl?: WebGLRenderingContext;\n private program?: WebGLProgram;\n\n private texCoordArray: Float32Array = new Float32Array([\n 0,\n 0, // top-left\n 0,\n 1, // bottom-left\n 1,\n 0, // top-right\n 1,\n 0, // top-right\n 0,\n 1, // bottom-left\n 1,\n 1, // bottom-right\n ]);\n\n // since these won't change over the lifetime of this object, there is no need for a reactive state store\n private _fileId: string | number;\n private _src: string;\n private _image: HTMLImageElement;\n private useLowRes: boolean = false;\n private lowResNeedsRefresh: boolean = true;\n private bitmap: ImageBitmap;\n private lowResBitmap: ImageBitmap;\n\n constructor(\n config: Partial<{\n x: number;\n y: number;\n src: string;\n sx?: number;\n sy?: number;\n width?: number;\n height?: number;\n }>,\n ) {\n super(config);\n this._src = config.src;\n this.loadImage(config.src, config.width, config.height);\n }\n\n get src() {\n return this._src;\n }\n set src(val: string) {\n if (this._src !== val) {\n this._src = val;\n this.updateImageTexture(val);\n this.markDirty();\n }\n }\n\n get fileId() {\n return this._fileId;\n }\n set fileId(val: string | number) {\n this._fileId = val;\n }\n\n determineIfLowRes(\n cameraBoundingBox: AABB,\n zoomFactor: number,\n threshold = 0.1,\n ) {\n // get both starting point and end point of each axis\n // compare that with the bounding box of the container (0 -> edge)\n // see how much space the visible parts of the image takes up\n const cameraArea = cameraBoundingBox.getArea();\n\n const area = this.getBoundingBox().getArea();\n\n // Low-res if area ratio is below threshold\n return area / cameraArea < threshold / zoomFactor;\n }\n\n async setUseLowRes(useLowRes: boolean, gl?: WebGLRenderingContext) {\n // checks for current state to see if we are already using low res so we can avoid doing the extra work\n if (this.useLowRes === useLowRes && !this.lowResNeedsRefresh) return;\n this.useLowRes = useLowRes;\n if ((useLowRes && gl) || this.lowResNeedsRefresh) {\n await this.ensureLowResUploaded(gl);\n }\n this.markDirty();\n this.lowResNeedsRefresh = false;\n }\n\n private loadImage(src: string, width?: number, height?: number) {\n if (this.culled) return;\n this.updateImageTexture(src, width, height);\n }\n\n private updateImageTexture(src: string, width?: number, height?: number) {\n this._image = new Image();\n this._image.crossOrigin = \"anonymous\";\n this._image.onload = async () => {\n this.width = width ?? this._image.naturalWidth;\n this.height = height ?? this._image.naturalHeight;\n\n try {\n if (this.bitmap) {\n try {\n this.bitmap.close();\n } catch (e) {}\n this.bitmap = undefined;\n }\n if (typeof createImageBitmap === \"function\") {\n this.bitmap = await createImageBitmap(this._image);\n }\n } catch (err) {\n console.warn(\n \"createImageBitmap failed, falling back to HTMLImageElement\",\n err,\n );\n this.bitmap = undefined;\n }\n\n if (this.gl && this.program) {\n try {\n if (this.texture && this.gl) {\n this.gl.deleteTexture(this.texture);\n this.texture = undefined;\n }\n this.initialiseTexture();\n this.initialized = true;\n this.markDirty();\n } catch (err) {\n console.error(\"Failed to initialise texture on image load\", err);\n }\n }\n\n // only trigger regeneration of the low res once the image has been updated\n this.lowResNeedsRefresh = true;\n };\n this._image.onerror = (error) => {\n console.error(\"Failed to load image:\", src, error);\n };\n this._image.src = src;\n }\n\n private async ensureLowResUploaded(gl: WebGLRenderingContext) {\n if (this.lowResTexture && !this.lowResNeedsRefresh) return;\n if (!this._image || !this._image.complete) return;\n\n try {\n const targetMaxSide = 256;\n const naturalW = this._image.naturalWidth;\n const naturalH = this._image.naturalHeight;\n const scale = Math.min(\n 1,\n targetMaxSide / Math.max(1, Math.max(naturalW, naturalH)),\n );\n const w = Math.max(1, Math.round(naturalW * scale));\n const h = Math.max(1, Math.round(naturalH * scale));\n\n let canvas: HTMLCanvasElement | OffscreenCanvas;\n if (typeof OffscreenCanvas !== \"undefined\") {\n canvas = new OffscreenCanvas(w, h);\n } else {\n canvas = document.createElement(\"canvas\");\n canvas.width = w;\n canvas.height = h;\n }\n\n const ctx = (canvas as HTMLCanvasElement).getContext(\"2d\") as\n | CanvasRenderingContext2D\n | OffscreenCanvasRenderingContext2D;\n ctx.clearRect(0, 0, w, h);\n\n const ratio = Math.min(w / naturalW, h / naturalH);\n const dw = Math.round(naturalW * ratio);\n const dh = Math.round(naturalH * ratio);\n const dx = Math.round((w - dw) / 2);\n const dy = Math.round((h - dh) / 2);\n\n ctx.drawImage(this._image, 0, 0, naturalW, naturalH, dx, dy, dw, dh);\n\n this.lowResBitmap = await createImageBitmap(canvas as any);\n this.setLowResTextureFromBitmap(gl, this.lowResBitmap);\n } catch (err) {\n console.error(\"Failed to create/upload low-res image\", err);\n }\n }\n\n private setLowResTextureFromBitmap(\n gl: WebGLRenderingContext,\n bitmap: ImageBitmap,\n ) {\n if (this.lowResTexture) {\n try {\n gl.deleteTexture(this.lowResTexture);\n } catch (e) {}\n this.lowResTexture = undefined;\n }\n\n this.lowResTexture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this.lowResTexture);\n\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);\n gl.bindTexture(gl.TEXTURE_2D, null);\n\n this.markDirty();\n }\n\n // data upload\n private initialiseTexture() {\n if (!this.gl || !this.program) return;\n if (!this._image || !this._image.complete || this._image.naturalWidth === 0)\n return;\n\n this.setUpVertexData(this.gl, this.program);\n this.setUpTexData(this.gl, this.program);\n this.setTexture(this.gl);\n\n super.setUpUniforms(this.gl, this.program);\n this.samplerLocation = this.gl.getUniformLocation(this.program, \"u_image\");\n if (this.samplerLocation) this.gl.uniform1i(this.samplerLocation, 0);\n }\n\n private setUpTexData(gl: WebGLRenderingContext, program: WebGLProgram) {\n if (!this.texcoordBuffer) {\n this.texcoordBuffer = gl.createBuffer();\n }\n this.texcoordLocation = gl.getAttribLocation(program, \"a_texCoord\");\n }\n\n private setTexture(gl: WebGLRenderingContext) {\n if (this.texture) {\n try {\n try {\n gl.deleteTexture(this.texture);\n } catch (e) {}\n } catch (e) {}\n this.texture = undefined;\n }\n\n this.texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\n\n // Set the parameters so we can render any size image.\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\n // Upload the image into the texture.\n const srcForTex = this.bitmap ?? this._image;\n if (srcForTex) {\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n srcForTex,\n );\n }\n gl.bindTexture(gl.TEXTURE_2D, null);\n }\n\n updateVertexData(gl: WebGLRenderingContext) {\n super.updateVertexData(gl);\n\n // Upload texture coordinates\n gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, this.texCoordArray, gl.STATIC_DRAW);\n }\n\n getVertexCount(): number {\n return 6;\n }\n\n render(gl: WebGLRenderingContext, program: WebGLProgram): void {\n if (this.dirty && !this.culled) {\n this.updateWorldMatrix(this.parent ? this.parent.worldMatrix : undefined);\n\n if (!this.initialized) {\n this.gl = gl;\n this.program = program;\n this.initialiseTexture();\n\n // Only create texture if image is loaded\n if (this._image.complete && this._image.naturalWidth > 0) {\n this.initialized = true;\n } else {\n // Image not ready yet, skip initialization\n return;\n }\n }\n\n this.updateVertexData(gl);\n this.clearDirty();\n }\n super.updateUniforms(gl);\n if (!this.culled) this.draw(gl);\n }\n\n protected draw(gl: WebGLRenderingContext) {\n gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);\n\n const size = 2; // 2 components per iteration since it's a vec2D\n const type = gl.FLOAT; // the data is 32bit floats\n const normalize = false; // don't normalize the data\n const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position\n const offset = 0; // start at the beginning of the buffer\n\n gl.vertexAttribPointer(\n this.attributeLocation,\n size,\n type,\n normalize,\n stride,\n offset,\n );\n gl.enableVertexAttribArray(this.attributeLocation);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);\n gl.vertexAttribPointer(\n this.texcoordLocation,\n size,\n type,\n normalize,\n stride,\n offset,\n );\n gl.enableVertexAttribArray(this.texcoordLocation);\n\n gl.activeTexture(gl.TEXTURE0);\n\n try {\n const tex =\n this.useLowRes && this.lowResTexture\n ? this.lowResTexture\n : this.texture;\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.drawArrays(gl.TRIANGLES, 0, this.getVertexCount());\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.disableVertexAttribArray(this.attributeLocation);\n gl.disableVertexAttribArray(this.texcoordLocation);\n } catch (err) {\n console.error(err);\n }\n }\n\n destroy() {\n if (this.texcoordBuffer) {\n try {\n this.gl.deleteBuffer(this.texcoordBuffer);\n } catch (e) {}\n this.texcoordBuffer = undefined;\n }\n if (this.texture) {\n try {\n this.gl.deleteTexture(this.texture);\n } catch (e) {}\n this.texture = undefined;\n }\n if (this.lowResTexture) {\n try {\n this.gl.deleteTexture(this.lowResTexture);\n } catch (e) {}\n this.lowResTexture = undefined;\n }\n\n if (this.bitmap) {\n try {\n this.bitmap.close();\n } catch (e) {}\n this.bitmap = undefined;\n }\n if (this.lowResBitmap) {\n try {\n this.lowResBitmap.close();\n } catch (e) {}\n this.lowResBitmap = undefined;\n }\n\n this.texcoordLocation = undefined;\n this.samplerLocation = undefined;\n try {\n super.destroy();\n } catch (e) {}\n }\n}\n","import { m3 } from \"../util\";\nimport { WebGLRenderable } from \"./Renderable\";\n\nexport enum GRID_TYPE {\n NONE,\n GRID,\n}\n\nexport class Grid extends WebGLRenderable {\n private buffer: WebGLBuffer | null = null;\n private vertexCount = 0;\n\n viewProjectionInvLocation: WebGLUniformLocation;\n zoomScaleLocation: WebGLUniformLocation;\n checkboardStyleLocation: WebGLUniformLocation;\n\n gridType: GRID_TYPE = GRID_TYPE.GRID;\n zoom: number = 1;\n\n // Fullscreen big-triangle in clip space: covers [-1,1] without seams\n getPositions() {\n // x,y pairs in clip space\n return new Float32Array([-1.0, -1.0, 3.0, -1.0, -1.0, 3.0]);\n }\n\n changeGridType(type: GRID_TYPE) {\n this.gridType = type;\n }\n\n render(gl: WebGLRenderingContext, program: WebGLProgram): void {\n if (!this.buffer) {\n this.buffer = gl.createBuffer();\n if (!this.buffer) throw new Error(\"Failed to create grid buffer\");\n const data = this.getPositions();\n this.vertexCount = data.length / 2;\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);\n } else {\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);\n }\n\n if (!this.initialized) {\n this.setUpVertexData(gl, program);\n this.setUpUniforms(gl, program);\n this.initialized = true;\n }\n\n // Convert clip [-1,1] to pixel coords using the current drawing buffer size\n const w = gl.drawingBufferWidth;\n const h = gl.drawingBufferHeight;\n\n const invP = m3.inverse(m3.projection(w, h)); // clip to pixel space\n const invView = m3.inverse(this.worldMatrix); // camera/view -> world\n const invVP = m3.multiply(invView, invP); // clip -> world\n\n if (this.viewProjectionInvLocation)\n gl.uniformMatrix3fv(\n this.viewProjectionInvLocation,\n false,\n new Float32Array(invVP),\n );\n if (this.zoomScaleLocation) gl.uniform1f(this.zoomScaleLocation, this.zoom);\n if (this.checkboardStyleLocation)\n gl.uniform1f(this.checkboardStyleLocation, this.gridType);\n\n // a_Position is clip-space position (vec2)\n const loc = gl.getAttribLocation(program, \"a_Position\");\n if (loc === -1) {\n throw new Error(\"Attribute a_Position not found in grid program\");\n }\n\n gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);\n gl.enableVertexAttribArray(loc);\n\n // Draw the fullscreen triangle\n gl.drawArrays(gl.TRIANGLES, 0, this.vertexCount);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, null);\n gl.disableVertexAttribArray(loc);\n }\n\n destroy(): void {\n if (this.buffer) {\n this.buffer = null;\n }\n }\n\n hitTest(x: number, y: number): boolean {\n return false;\n }\n\n protected setUpUniforms(\n gl: WebGLRenderingContext,\n program: WebGLProgram,\n ): void {\n const I3 = new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);\n this.viewProjectionInvLocation = gl.getUniformLocation(\n program,\n \"u_ViewProjectionInvMatrix\",\n );\n this.zoomScaleLocation = gl.getUniformLocation(program, \"u_ZoomScale\");\n this.checkboardStyleLocation = gl.getUniformLocation(\n program,\n \"u_CheckboardStyle\",\n );\n\n gl.uniformMatrix3fv(this.viewProjectionInvLocation, false, I3);\n gl.uniform1f(this.zoomScaleLocation, this.zoom);\n gl.uniform1f(this.checkboardStyleLocation, 1.0);\n }\n}\n","import { CameraState } from \"../state\";\nimport { reaction } from \"mobx\";\nimport { AABB } from \"../bounding\";\n\nexport const ZOOM_MIN = 0.02;\nexport const ZOOM_MAX = 20;\n\nexport class Camera {\n state: CameraState;\n // these are the origin of the camera viewport\n viewportX: number = 0;\n viewportY: number = 0;\n private updateReaction: () => void;\n getWorldCoords: (x: number, y: number) => number[];\n setWorldMatrix: (matrix: number[]) => void;\n updateWorldMatrix: () => void;\n\n constructor(\n state: CameraState,\n setWorldMatrix: (matrix: number[]) => void,\n updateWorldMatrix: () => void,\n getWorldCoords: (x: number, y: number) => number[],\n ) {\n this.state = state;\n\n this.updateCameraPos = this.updateCameraPos.bind(this);\n this.updateZoom = this.updateZoom.bind(this);\n this.onWheel = this.onWheel.bind(this);\n this.worldToCamera = this.worldToCamera.bind(this);\n\n this.getWorldCoords = getWorldCoords;\n this.setWorldMatrix = setWorldMatrix;\n this.updateWorldMatrix = updateWorldMatrix;\n\n this.updateReaction = reaction(\n () => this.state.stateVector,\n () => this.updateViewMatrix(),\n );\n\n // reaction does not auto run the function when assigned\n this.updateViewMatrix();\n }\n\n /**\n * Called once to update the `worldMatrix` of the attached canvas, which is the view matrix.\n */\n private updateViewMatrix() {\n this.setWorldMatrix(this.state.canvasMatrix);\n this.updateWorldMatrix();\n }\n\n setViewPortDimension(width: number, height: number) {\n if (this.state.width !== width) this.state.setWidth(width);\n if (this.state.height !== height) this.state.setHeight(height);\n }\n\n getBoundingBox() {\n const [minX, minY] = this.getWorldCoords(this.viewportX, this.viewportY);\n const [maxX, maxY] = this.getWorldCoords(\n this.state.width + this.viewportX,\n this.state.height + this.viewportY,\n );\n return new AABB(minX, minY, maxX, maxY);\n }\n\n onWheel(e: WheelEvent) {\n e.preventDefault();\n\n const ZOOM_SPEED = 0.003;\n const scale = Math.exp(-e.deltaY * ZOOM_SPEED);\n this.updateZoom(e.clientX, e.clientY, scale);\n }\n\n updateCameraPos(dx: number, dy: number) {\n this.state.incrementPosition(dx, dy);\n }\n\n /**\n * Pass in the center position to resolve the scaling around\n */\n updateZoom(x: number, y: number, scale: number) {\n const [wx0, wy0] = this.getWorldCoords(x, y);\n this.state.setZoom(\n Math.min(ZOOM_MAX, Math.max(ZOOM_MIN, this.state.zoom * scale)),\n );\n\n const [wx1, wy1] = this.getWorldCoords(x, y);\n\n this.state.incrementPosition(wx0 - wx1, wy0 - wy1);\n }\n\n worldToCamera(wx: number, wy: number) {\n const m = this.state.cameraMatrix;\n const x = m[0] * wx + m[1] * wy + m[2];\n const y = m[3] * wx + m[4] * wy + m[5];\n return [x, y];\n }\n\n dispose() {\n if (this.updateReaction) {\n this.updateReaction();\n this.updateReaction = undefined;\n }\n }\n}\n","import { ImageFileMetadata } from \"storage\";\nimport { Canvas } from \"../Canvas\";\nimport { Renderable, Rect, Img, Grid } from \"../shapes\";\nimport { hashStringToId, performanceTest } from \"../util\";\n\n/**\n * What should be exposed?\n * the images created - their position, scale and src - maintain the order they have been saved\n *\n * grid state should be tracked to decide if grid lines are there or not - TO BE IMPLEMENTED\n *\n * Should camera position be tracked\n *\n * How often should we write to the chosen method fo storage? When initialising the exporter, we can decide between indexdb and an actual db\n * is there anyway to force a save when the app closes? In what circumstances will that not work? An ungraceful shutdown?\n */\n\nconst PLACEHOLDER_IMAGE_SRC =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjYjNiM2IzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xLjUgNmEyLjI1IDIuMjUgMCAwIDEgMi4yNS0yLjI1aDE2LjVBMi4yNSAyLjI1IDAgMCAxIDIyLjUgNnYxMmEyLjI1IDIuMjUgMCAwIDEtMi4yNSAyLjI1SDMuNzVBMi4yNSAyLjI1IDAgMCAxIDEuNSAxOHpNMyAxNi4wNlYxOGMwIC40MTQuMzM2Ljc1Ljc1Ljc1aDE2LjVBLjc1Ljc1IDAgMCAwIDIxIDE4di0xLjk0bC0yLjY5LTIuNjg5YTEuNSAxLjUgMCAwIDAtMi4xMiAwbC0uODguODc5bC45Ny45N2EuNzUuNzUgMCAxIDEtMS4wNiAxLjA2bC01LjE2LTUuMTU5YTEuNSAxLjUgMCAwIDAtMi4xMiAwem0xMC4xMjUtNy44MWExLjEyNSAxLjEyNSAwIDEgMSAyLjI1IDBhMS4xMjUgMS4xMjUgMCAwIDEtMi4yNSAwIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=\";\nconst PLACEHOLDER_IMAGE_SIZE = 240;\n\nexport type SerializedTransform = {\n x: number;\n y: number;\n sx: number;\n sy: number;\n};\n\nexport type SerializedNodeBase = {\n id?: number;\n type: string;\n transform?: SerializedTransform;\n children?: SerializedNode[];\n layer?: number;\n renderOrder?: number;\n};\n\nexport type SerializedRect = SerializedNodeBase & {\n type: \"Rect\";\n width: number;\n height: number;\n color: [number, number, number, number];\n};\n\nexport type SerializedImg = SerializedNodeBase & {\n type: \"Img\";\n width: number;\n height: number;\n fileId: number | string;\n};\n\nexport type SerializedGrid = SerializedNodeBase & {\n type: \"Grid\";\n style?: number;\n};\n\nexport type SerializedNode =\n | SerializedRect\n | SerializedImg\n | SerializedGrid\n | SerializedNodeBase;\n\nexport type SerializedCamera = {\n zoom: number;\n x: number;\n y: number;\n};\n\nexport type SerializedCanvas = {\n version: 1;\n canvas: {\n width: number;\n height: number;\n dpr: number;\n };\n camera?: SerializedCamera;\n root: SerializedNode;\n files?: ImageFileMetadata[];\n};\n\nfunction transformOf(node: Renderable): SerializedTransform {\n return {\n x: node.x ?? 0,\n y: node.y ?? 0,\n sx: node.sx ?? 1,\n sy: node.sy ?? 1,\n };\n}\n\nfunction serializeChildren(node: Renderable): SerializedNode[] {\n return node.children.map(serializeNode);\n}\n\nexport function serializeNode(node: Renderable): SerializedNode {\n if (node instanceof Img) {\n const base: SerializedImg = {\n type: \"Img\",\n id: (node as Img).seq,\n renderOrder: (node as Img).renderOrder,\n transform: transformOf(node),\n width: (node as Img).width,\n height: (node as Img).height,\n fileId: (node as Img).fileId,\n children: node.children?.length ? serializeChildren(node) : undefined,\n };\n return base;\n }\n\n if (node instanceof Rect) {\n const base: SerializedRect = {\n type: \"Rect\",\n id: (node as Rect).seq,\n renderOrder: (node as Rect).renderOrder,\n transform: transformOf(node),\n width: (node as Rect).width,\n height: (node as Rect).height,\n color: (node as Rect).color,\n children: node.children?.length ? serializeChildren(node) : undefined,\n };\n return base;\n }\n\n if (node instanceof Grid) {\n const base: SerializedGrid = {\n type: \"Grid\",\n style: (node as Grid).gridType,\n };\n return base;\n }\n\n const generic: SerializedNodeBase = {\n type: \"Renderable\",\n children: node.children?.length ? serializeChildren(node) : undefined,\n };\n return generic;\n}\n\nexport function serializeCanvas(\n canvas: Canvas,\n files?: ImageFileMetadata[],\n): SerializedCanvas {\n const { gl } = canvas;\n return {\n version: 1,\n canvas: {\n width: gl.canvas.width,\n height: gl.canvas.height,\n dpr: window.devicePixelRatio || 1,\n },\n camera: {\n x: canvas.camera.state.x,\n y: canvas.camera.state.y,\n zoom: canvas.camera.state.zoom,\n },\n root: serializeNode(canvas),\n files,\n };\n}\n\nexport async function deserializeCanvas(\n data: SerializedCanvas,\n canvas: Canvas,\n getFile: (id: string | number) => Promise<ImageFileMetadata>,\n writeFileToDatabase?: (data: string) => void,\n) {\n canvas.children.length = 0;\n\n if (data.camera) {\n canvas.camera.state.setZoom(data.camera.zoom);\n canvas.camera.state.setX(data.camera.x);\n canvas.camera.state.setY(data.camera.y);\n }\n\n async function build(node: SerializedNode, parent: Canvas | Renderable) {\n let instance: Renderable;\n switch (node.type) {\n case \"Rect\":\n instance = new Rect({\n x: node.transform.x,\n y: node.transform.y,\n width: (node as SerializedRect).width,\n height: (node as SerializedRect).height,\n });\n instance.setScale(node.transform.sx, node.transform.sy);\n canvas.appendChild(instance);\n break;\n case \"Img\":\n let src: string;\n try {\n src = (() => {\n if (data.files && Array.isArray(data.files)) {\n const fileMeta = data.files.find(\n (e) => e.id === (node as SerializedImg).fileId,\n );\n return fileMeta?.dataURL ?? PLACEHOLDER_IMAGE_SRC;\n }\n return PLACEHOLDER_IMAGE_SRC;\n })();\n\n if (writeFileToDatabase) {\n writeFileToDatabase(src);\n }\n\n const width = (node as SerializedImg).width;\n const height = (node as SerializedImg).height;\n const framedPlaceholder = await framePlaceholder(\n src,\n width * node.transform.sx,\n height * node.transform.sy,\n );\n\n instance = new Img({\n x: node.transform.x,\n y: node.transform.y,\n src: framedPlaceholder,\n width,\n height,\n });\n\n getFile((node as SerializedImg).fileId)\n .then((file) => {\n (instance as Img).src = file.dataURL;\n })\n .catch((err) => console.error(\"Image not loaded\", err));\n\n // skip hashing if it already has a file ID\n (instance as Img).fileId =\n (node as SerializedImg).fileId ?? (await hashStringToId(src));\n instance.setScale(node.transform.sx, node.transform.sy);\n canvas.appendChild(instance);\n if (typeof (node as SerializedImg).renderOrder === \"number\") {\n (instance as Img).renderOrder = (node as SerializedImg).renderOrder;\n }\n } catch (err) {\n // delete node from storage? It won't be saved in the next instance, so perhaps it's fine?\n console.error(`Failed to match image to restore with source: ${src}`);\n } finally {\n break;\n }\n case \"Grid\":\n if (parent instanceof Canvas) {\n parent.grid.gridType = (node as SerializedGrid).style;\n }\n break;\n default:\n break;\n }\n\n if (node.children) {\n for (const child of node.children) await build(child, instance);\n }\n }\n\n await build(data.root, canvas);\n return canvas;\n}\n\nasync function loadImageElement(src: string): Promise<HTMLImageElement> {\n const img = new Image();\n img.crossOrigin = \"anonymous\";\n return new Promise((resolve, reject) => {\n img.onload = () => resolve(img);\n img.onerror = (err) => reject(err);\n img.src = src;\n });\n}\n\nasync function framePlaceholder(\n srcOrBlob: string | Blob,\n tw?: number,\n th?: number,\n bg: string = \"#d6d6d6ff\",\n): Promise<string> {\n let objectUrl: string | null = null;\n let src: string;\n\n if (srcOrBlob instanceof Blob) {\n objectUrl = URL.createObjectURL(srcOrBlob);\n src = objectUrl;\n } else {\n src = srcOrBlob;\n }\n\n try {\n let img: HTMLImageElement | null = null;\n try {\n img = await loadImageElement(src);\n } catch (e) {\n // Swallow in order to proceed with a background-only placeholder\n }\n\n const targetW =\n tw && tw > 0 ? tw : (img?.naturalWidth ?? PLACEHOLDER_IMAGE_SIZE);\n const targetH =\n th && th > 0 ? th : (img?.naturalHeight ?? PLACEHOLDER_IMAGE_SIZE);\n\n const canvas = document.createElement(\"canvas\");\n canvas.width = targetW;\n canvas.height = targetH;\n const ctx = canvas.getContext(\"2d\")!;\n\n ctx.fillStyle = bg;\n ctx.fillRect(0, 0, targetW, targetH);\n\n if (img) {\n // if any of the sides is less than the placeholder image size, then use the natural ratio\n const ratio = Math.min(\n targetW / img.naturalWidth,\n targetH / img.naturalHeight,\n );\n const ratioedHeight = img.naturalHeight * ratio;\n const ratioedWidth = img.naturalWidth * ratio;\n\n let dw = PLACEHOLDER_IMAGE_SIZE;\n let dh = PLACEHOLDER_IMAGE_SIZE;\n\n if (\n PLACEHOLDER_IMAGE_SIZE > ratioedHeight ||\n PLACEHOLDER_IMAGE_SIZE > ratioedWidth\n ) {\n dw = ratioedWidth;\n dh = ratioedHeight;\n }\n\n const dx = Math.round((targetW - dw) / 2);\n const dy = Math.round((targetH - dh) / 2);\n\n ctx.drawImage(\n img,\n 0,\n 0,\n img.naturalWidth,\n img.naturalHeight,\n dx,\n dy,\n dw,\n dh,\n );\n }\n\n return canvas.toDataURL(\"image/png\");\n } finally {\n if (objectUrl) {\n URL.revokeObjectURL(objectUrl);\n }\n }\n}\n","import {\n BoundingBoxCollisionType,\n CanvasEvent,\n convertToPNG,\n createProgram,\n getWorldCoords,\n paste,\n} from \"./util\";\nimport {\n shapeVert,\n shapeFrag,\n imageFrag,\n imageVert,\n gridVert,\n gridFrag,\n} from \"./shaders\";\nimport { Shape, Img, Renderable, Grid, GRID_TYPE } from \"./shapes\";\nimport {\n SelectionManager,\n PointerEventManager,\n KeyEventManager,\n ContextMenuManager,\n makeMultiOrderCommand,\n} from \"./manager\";\nimport { Camera } from \"./camera\";\nimport { CameraState, PointerEventState } from \"./state\";\nimport { CanvasHistory } from \"./history\";\nimport {\n deserializeCanvas,\n serializeCanvas,\n SerializedCanvas,\n} from \"./serializer\";\nimport EventEmitter from \"eventemitter3\";\nimport { ImageFileMetadata } from \"./storage\";\nimport { AABB } from \"./bounding\";\n\nexport class Canvas extends Renderable {\n #canvas: HTMLCanvasElement;\n #eventHub: EventEmitter;\n #history: CanvasHistory;\n #camera: Camera;\n\n #gl: WebGLRenderingContext;\n #basicShapeProgram: WebGLProgram;\n #imageProgram: WebGLProgram;\n #gridProgram: WebGLProgram;\n #grid: Grid;\n\n #isGlobalClick = true;\n\n #selectionManager: SelectionManager;\n #pointerEventManager: PointerEventManager;\n #keyPressManager: KeyEventManager;\n #contextMenuManager: ContextMenuManager;\n\n writeToStorage: () => void;\n saveImgFileToStorage: (data: string) => Promise<string | number | null>;\n getContainerDimension: () => number[];\n getWorldsCoordsFromCanvas: (x: number, y: number) => number[];\n\n private orderDirty = true;\n private renderList: Shape[] = [];\n\n // Call this whenever children/layers/z-order change\n markOrderDirty() {\n this.orderDirty = true;\n }\n\n get gl() {\n return this.#gl;\n }\n get grid() {\n return this.#grid;\n }\n get history() {\n return this.#history;\n }\n get eventHub() {\n return this.#eventHub;\n }\n get pointerEventManager() {\n return this.#pointerEventManager;\n }\n get selectionManager() {\n return this.#selectionManager;\n }\n get contextMenuManager() {\n return this.#contextMenuManager;\n }\n get canvas() {\n return this.#canvas;\n }\n get camera() {\n return this.#camera;\n }\n get isGlobalClick() {\n return this.#isGlobalClick;\n }\n set isGlobalClick(val: boolean) {\n this.#isGlobalClick = val;\n }\n get basicShapeProgram() {\n return this.#basicShapeProgram;\n }\n\n constructor(\n canvas: HTMLCanvasElement,\n history: CanvasHistory,\n eventHub: EventEmitter,\n writeToStorage: () => void,\n saveImgFileToStorage: (data: string) => Promise<string | number | null>,\n getContainerDimension: () => number[],\n ) {\n super();\n this.#canvas = canvas;\n this.#eventHub = eventHub;\n this.#history = history;\n\n this.#grid = new Grid();\n this.#gl = canvas.getContext(\"webgl\", {\n alpha: true,\n premultipliedAlpha: false,\n });\n this.#gl.enable(this.#gl.BLEND);\n this.#gl.blendFunc(this.#gl.SRC_ALPHA, this.#gl.ONE_MINUS_SRC_ALPHA);\n\n this.#gl.getExtension(\"OES_standard_derivatives\"); // required to enable fwidth\n\n this.#gl.enable(this.#gl.DEPTH_TEST);\n this.#gl.depthFunc(this.#gl.LEQUAL);\n\n this.#basicShapeProgram = createProgram(this.#gl, shapeVert, shapeFrag);\n this.#imageProgram = createProgram(this.#gl, imageVert, imageFrag);\n this.#gridProgram = createProgram(this.#gl, gridVert, gridFrag);\n\n this.writeToStorage = writeToStorage;\n this.saveImgFileToStorage = saveImgFileToStorage;\n this.getContainerDimension = getContainerDimension;\n\n this.engine = this.engine.bind(this);\n this.getBoundingClientRect = this.getBoundingClientRect.bind(this);\n this.appendChild = this.appendChild.bind(this);\n this.addImageToCanvas = this.addImageToCanvas.bind(this);\n this.setShapeZOrder = this.setShapeZOrder.bind(this);\n\n this.toggleGrid = this.toggleGrid.bind(this);\n this.changeMode = this.changeMode.bind(this);\n this.getSelected = this.getSelected.bind(this);\n this.updateZoomByFixedAmount = this.updateZoomByFixedAmount.bind(this);\n\n this.assignEventListener = this.assignEventListener.bind(this);\n this.getWorldsCoordsFromCanvas = (x: number, y: number) =>\n getWorldCoords(x, y, this);\n\n // marquee coordinates are calculated based on viewport, so we need to adjust it by camera viewport spawn point\n const getMarqueeCoords = (x: number, y: number) =>\n getWorldCoords(\n x + this.camera.viewportX,\n y + this.camera.viewportY,\n this,\n );\n\n this.exportState = this.exportState.bind(this);\n this.importState = this.importState.bind(this);\n this.clearChildren = this.clearChildren.bind(this);\n\n this.#selectionManager = new SelectionManager(\n history,\n eventHub,\n this.gl,\n this.#basicShapeProgram,\n () => this.worldMatrix,\n () => this.children,\n this.getWorldsCoordsFromCanvas,\n getMarqueeCoords,\n );\n\n const cameraState = new CameraState({});\n this.#camera = new Camera(\n cameraState,\n this.setWorldMatrix,\n this.updateWorldMatrix,\n this.getWorldsCoordsFromCanvas,\n );\n\n this.#keyPressManager = new KeyEventManager(\n history,\n eventHub,\n () => this.selectionManager.deleteSelected(this),\n this.assignEventListener,\n );\n\n this.#contextMenuManager = new ContextMenuManager(\n eventHub,\n this.selectionManager.isMultiBoundingBoxHit,\n this.selectionManager.isBoundingBoxHit,\n this.getWorldsCoordsFromCanvas,\n this.assignEventListener,\n );\n\n const pointerEventState = new PointerEventState();\n\n const pointerManagerDeps = {\n history,\n eventHub,\n state: pointerEventState,\n isContextMenuActive: () => this.#contextMenuManager.isActive,\n getSelected: () => this.#selectionManager.selected,\n getChildren: () => this.children,\n getWorldMatrix: () => this.worldMatrix,\n getCanvasGlobalClick: () => this.isGlobalClick,\n setCanvasGlobalClick: (val: boolean) => (this.isGlobalClick = val),\n getWorldCoords: this.getWorldsCoordsFromCanvas,\n updateCameraPos: this.camera.updateCameraPos,\n onWheel: this.camera.onWheel,\n setCursorStyle: (val: string) => (canvas.style.cursor = val),\n paste: (x: number, y: number) => paste(x, y, this, history),\n assignEventListener: this.assignEventListener,\n closeMarquee: this.#selectionManager.clearMarquee,\n selectionPointerMove: (\n x: number,\n y: number,\n dx: number,\n dy: number,\n resizeDirection: BoundingBoxCollisionType,\n ) =>\n this.#selectionManager.onPointerMove(\n x,\n y,\n dx,\n dy,\n resizeDirection,\n () => this.isGlobalClick,\n this.camera.updateCameraPos,\n () => this.worldMatrix,\n ),\n onSelectionPointerDown: this.selectionManager.onSelectionPointerDown,\n checkIfSelectionHit: this.selectionManager.hitTest,\n addSelection: this.selectionManager.add,\n clearSelection: this.selectionManager.clear,\n isSelection: this.selectionManager.isRectSelected,\n hitTestAdjustedCorner: this.selectionManager.hitTestAdjustedCorner,\n };\n\n this.#pointerEventManager = new PointerEventManager(pointerManagerDeps);\n\n this.#eventHub.on(\"save\", this.writeToStorage);\n }\n\n engine() {\n return this;\n }\n\n get totalNumberOfChildren() {\n return this.children.length;\n }\n\n get numberOfChildrenRendered() {\n return this.renderList.length;\n }\n\n appendChild<T extends Renderable>(child: T): T {\n super.appendChild(child);\n if (child instanceof Shape) {\n const orders = (this.children as Shape[]).map((s) => s.renderOrder);\n const maxOrder = orders.length ? Math.max(...orders) : 0;\n\n child.renderOrder = maxOrder + 1;\n }\n this.markOrderDirty();\n return child;\n }\n\n removeChild(child: Renderable): void {\n this.state.removeChild(child);\n if (this.#selectionManager) {\n this.#selectionManager.remove([child as any]);\n }\n child.destroy();\n this.markOrderDirty();\n }\n\n getChild(id: number): Renderable {\n return this.state.getChild(id);\n }\n\n updateWorldMatrix() {\n this.#grid.updateWorldMatrix(this.worldMatrix);\n this.children.forEach((child) => {\n child.updateWorldMatrix(this.worldMatrix);\n });\n this.#selectionManager.update();\n }\n\n render() {\n this.#gl.clearColor(0, 0, 0, 0);\n this.#gl.clear(this.#gl.COLOR_BUFFER_BIT | this.#gl.DEPTH_BUFFER_BIT);\n this.#gl.viewport(0, 0, this.#gl.canvas.width, this.#gl.canvas.height);\n\n const parentBoundingBox = this.canvas.parentElement.getBoundingClientRect();\n this.camera.setViewPortDimension(\n parentBoundingBox.width,\n parentBoundingBox.height,\n );\n\n this.#gl.useProgram(this.#gridProgram);\n const uZGrid = this.#gl.getUniformLocation(this.#gridProgram, \"u_z\");\n this.#gl.uniform1f(uZGrid, 0.0);\n this.#grid.render(this.#gl, this.#gridProgram);\n\n const cameraBoundingBox = this.camera.getBoundingBox();\n let totalRenderable = 0;\n let rendered = 0;\n this.renderList = [];\n\n for (const renderable of this.children as Shape[]) {\n totalRenderable++;\n\n if (!AABB.isColliding(cameraBoundingBox, renderable.getBoundingBox())) {\n renderable.culled = true;\n } else {\n rendered++;\n this.renderList.push(renderable);\n renderable.culled = false;\n }\n }\n\n // should set low res based on what screen area it has taken up\n const [sww, swh] = getWorldCoords(0, 0, this);\n const [ww, wh] = getWorldCoords(\n window.screen.width,\n window.screen.height,\n this,\n );\n const screenAABB = new AABB(sww, swh, ww, wh);\n this.renderList.forEach((child) => {\n if (child instanceof Img) {\n const useLowRes = (child as Img).determineIfLowRes(\n screenAABB,\n this.camera.state.zoom,\n );\n\n (child as Img).setUseLowRes(useLowRes, this.gl);\n }\n });\n\n for (const renderable of this.renderList) {\n let program: WebGLProgram;\n\n if (renderable instanceof Img) {\n program = this.#imageProgram;\n } else if (renderable instanceof Shape) {\n program = this.#basicShapeProgram;\n }\n\n this.#gl.useProgram(program);\n\n const uZLoc = this.#gl.getUniformLocation(program, \"u_z\");\n this.#gl.uniform1f(uZLoc, renderable.getZ());\n renderable.render(this.#gl, program);\n }\n\n this.#selectionManager.render(this.#basicShapeProgram);\n }\n\n destroy() {\n // Clean up programs\n this.#gl.deleteProgram(this.#basicShapeProgram);\n this.#gl.deleteProgram(this.#imageProgram);\n\n // Clean up all renderables\n this.children.forEach((child) => {\n if (\"destroy\" in child) {\n child.destroy();\n }\n });\n\n this.clearChildren();\n }\n\n getDOM() {\n return this.#canvas;\n }\n\n assignEventListener(\n type: string,\n fn: (() => void) | ((e: any) => void),\n options?: boolean | AddEventListenerOptions,\n ) {\n this.#canvas.addEventListener(type, fn, options);\n }\n\n hitTest(x: number, y: number) {\n this.#isGlobalClick = true;\n return this.#isGlobalClick;\n }\n\n async addImageToCanvas(\n src: string,\n x: number,\n y: number,\n sx: number = 1,\n sy: number = 1,\n center: boolean = false,\n ) {\n const newImg = new Img({ x: x, y: y, src, sx, sy });\n this.saveImgFileToStorage(src).then((id) => (newImg.fileId = id));\n\n if (center) {\n const preview = new Image();\n preview.src = !src.startsWith(\"data:image/png\")\n ? await convertToPNG(src)\n : src;\n\n preview.onload = () => {\n const w = preview.naturalWidth || preview.width || 0;\n const h = preview.naturalHeight || preview.height || 0;\n if (w || h) newImg.updateTranslation(-w / 2, -h / 2);\n newImg.src = preview.src;\n this.appendChild(newImg);\n };\n }\n\n this.#eventHub.emit(\"save\");\n this.#eventHub.emit(CanvasEvent.Change);\n return newImg;\n }\n\n exportState() {\n return serializeCanvas(this);\n }\n\n async importState(\n data: SerializedCanvas,\n getFile: (fileId: string | number) => Promise<ImageFileMetadata>,\n ) {\n return await deserializeCanvas(data, this, getFile);\n }\n\n clearChildren() {\n this.selectionManager.clear();\n this.state.clearChildren(); // should clear history?\n this.#history.clear();\n }\n\n toggleGrid() {\n this.#grid.changeGridType(\n this.#grid.gridType === GRID_TYPE.GRID ? GRID_TYPE.NONE : GRID_TYPE.GRID,\n );\n }\n\n getSelected() {\n return this.#selectionManager.selected as Img[];\n }\n\n setShapeZOrder(toFront: boolean = true) {\n if (\n this.#selectionManager.multiBoundingBox ||\n this.#selectionManager.boundingBoxes.size != 1\n )\n return;\n\n const child = Array.from(this.#selectionManager.boundingBoxes)[0].target;\n\n const snapShotItem = {\n ref: child,\n start: {\n renderOrder: child.renderOrder,\n },\n };\n\n // Compute new renderOrder based on current scene\n const orders = (this.children as Shape[]).map((s) => s.renderOrder);\n\n if (orders.length === 0) {\n throw new Error(\"Order unexpected missing.\");\n }\n\n const maxOrder = Math.max(...orders);\n const minOrder = Math.min(...orders);\n\n child.renderOrder = toFront ? maxOrder + 1 : minOrder - 1;\n\n snapShotItem[\"end\"] = {\n renderOrder: child.renderOrder,\n };\n\n this.markOrderDirty();\n this.#history.push(makeMultiOrderCommand([snapShotItem]));\n this.#eventHub.emit(CanvasEvent.Change);\n }\n\n changeMode() {\n this.#pointerEventManager.changeMode();\n this.#selectionManager.clear();\n }\n\n updateZoomByFixedAmount(direction: 1 | -1 = 1) {\n this.#camera.updateZoom(\n this.#canvas.width / 2,\n this.#canvas.height / 2,\n Math.exp(0.5 * 0.3 * direction),\n );\n }\n\n getBoundingClientRect() {\n return this.#canvas.getBoundingClientRect();\n }\n\n private static webglStats = {\n buffersCreated: 0,\n buffersDeleted: 0,\n programsCreated: 0,\n programsDeleted: 0,\n texturesCreated: 0,\n texturesDeleted: 0,\n shadersCreated: 0,\n shadersDeleted: 0,\n };\n\n private wrapWebGLContext(gl: WebGLRenderingContext) {\n const originalCreateTexture = gl.createTexture.bind(gl);\n gl.createTexture = () => {\n Canvas.webglStats.texturesCreated++;\n console.log(`Textures created: ${Canvas.webglStats.texturesCreated}`);\n return originalCreateTexture();\n };\n const originalDeleteTexture = gl.deleteTexture.bind(gl);\n gl.deleteTexture = (texture: WebGLTexture | null) => {\n if (texture) {\n Canvas.webglStats.texturesDeleted++;\n console.log(`Textures deleted: ${Canvas.webglStats.texturesDeleted}`);\n }\n return originalDeleteTexture(texture);\n };\n const originalCreateShader = gl.createShader.bind(gl);\n gl.createShader = (type: number) => {\n Canvas.webglStats.shadersCreated++;\n console.log(`Shaders created: ${Canvas.webglStats.shadersCreated}`);\n return originalCreateShader(type);\n };\n const originalDeleteShader = gl.deleteShader.bind(gl);\n gl.deleteShader = (shader: WebGLShader | null) => {\n if (shader) {\n Canvas.webglStats.shadersDeleted++;\n console.log(`Shaders deleted: ${Canvas.webglStats.shadersDeleted}`);\n }\n return originalDeleteShader(shader);\n };\n\n return gl;\n }\n\n static getWebGLStats() {\n return {\n ...Canvas.webglStats,\n buffersLeaked:\n Canvas.webglStats.buffersCreated - Canvas.webglStats.buffersDeleted,\n programsLeaked:\n Canvas.webglStats.programsCreated - Canvas.webglStats.programsDeleted,\n texturesLeaked:\n Canvas.webglStats.texturesCreated - Canvas.webglStats.texturesDeleted,\n shadersLeaked:\n Canvas.webglStats.shadersCreated - Canvas.webglStats.shadersDeleted,\n };\n }\n}\n","export interface Command {\n label?: string;\n do(): void;\n undo(): void;\n}\n\nconst MAX_HISTORY = 25;\n\nexport class CanvasHistory {\n private _undoStack: Command[][] = [];\n private _redoStack: Command[][] = [];\n private _openGroup: Command[] | null = null;\n private _openLabel?: string;\n\n get undoStack() {\n return this._undoStack;\n }\n\n begin(label?: string) {\n if (this._openGroup) throw new Error(\"History group already open\");\n this._openGroup = [];\n this._openLabel = label;\n }\n\n push(cmd: Command) {\n if (this._openGroup) {\n this._openGroup.push(cmd);\n } else {\n while (this._undoStack.length >= MAX_HISTORY) {\n this._undoStack.shift();\n }\n\n this._undoStack.push([cmd]);\n cmd.do();\n this._redoStack.length = 0;\n }\n }\n\n commit() {\n if (!this._openGroup) return;\n const group = this._openGroup;\n this._openGroup = null;\n for (const c of group) c.do();\n\n while (this._undoStack.length >= MAX_HISTORY) {\n this._undoStack.shift();\n }\n\n this._undoStack.push(group);\n this._redoStack.length = 0;\n this._openLabel = undefined;\n }\n\n cancel() {\n // Drop current group without executing\n this._openGroup = null;\n this._openLabel = undefined;\n }\n\n canUndo() {\n return this._undoStack.length > 0;\n }\n canRedo() {\n return this._redoStack.length > 0;\n }\n\n undo() {\n const group = this._undoStack.pop();\n if (!group) return;\n\n for (let i = group.length - 1; i >= 0; i--) group[i].undo();\n this._redoStack.push(group);\n }\n\n redo() {\n const group = this._redoStack.pop();\n if (!group) return;\n for (const c of group) c.do();\n this._undoStack.push(group);\n }\n\n clear() {\n this._undoStack.length = 0;\n this._redoStack.length = 0;\n this._openGroup = null;\n this._openLabel = undefined;\n }\n}\n\n// Helpers ------------------------------------------------------------\nexport function setNumberProp<T extends object>(\n target: T,\n key: keyof T,\n next: number,\n label?: string,\n): Command {\n const k = key as keyof any;\n const prev = (target as any)[k] as number;\n return {\n label,\n do() {\n (target as any)[k] = next;\n },\n undo() {\n (target as any)[k] = prev;\n },\n };\n}\n\nexport function setBooleanProp<T extends object>(\n target: T,\n key: keyof T,\n next: boolean,\n label?: string,\n): Command {\n const k = key as keyof any;\n const prev = (target as any)[k] as boolean;\n return {\n label,\n do() {\n (target as any)[k] = next;\n },\n undo() {\n (target as any)[k] = prev;\n },\n };\n}\n\n// Move (x,y) as one atomic command\nexport function setXY(\n target: {\n x: number;\n y: number;\n setTranslation?: (x: number, y: number) => void;\n },\n toX: number,\n toY: number,\n label = \"Move\",\n): Command {\n const fromX = target.x;\n const fromY = target.y;\n const setter = target.setTranslation?.bind(target);\n return {\n label,\n do() {\n setter ? setter(toX, toY) : ((target.x = toX), (target.y = toY));\n },\n undo() {\n setter ? setter(fromX, fromY) : ((target.x = fromX), (target.y = fromY));\n },\n };\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=t=>(e,o)=>{void 0!==o?o.addInitializer((()=>{customElements.define(t,e)})):customElements.define(t,e)};export{t as customElement};\n//# sourceMappingURL=custom-element.js.map\n","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&\"adoptedStyleSheets\"in Document.prototype&&\"replace\"in CSSStyleSheet.prototype,s=Symbol(),o=new WeakMap;class n{constructor(t,e,o){if(this._$cssResult$=!0,o!==s)throw Error(\"CSSResult is not constructable. Use `unsafeCSS` or `css` instead.\");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const s=this.t;if(e&&void 0===t){const e=void 0!==s&&1===s.length;e&&(t=o.get(s)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&o.set(s,t))}return t}toString(){return this.cssText}}const r=t=>new n(\"string\"==typeof t?t:t+\"\",void 0,s),i=(t,...e)=>{const o=1===t.length?t[0]:e.reduce(((e,s,o)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if(\"number\"==typeof t)return t;throw Error(\"Value passed to 'css' function must be a 'css' function result: \"+t+\". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.\")})(s)+t[o+1]),t[0]);return new n(o,t,s)},S=(s,o)=>{if(e)s.adoptedStyleSheets=o.map((t=>t instanceof CSSStyleSheet?t:t.styleSheet));else for(const e of o){const o=document.createElement(\"style\"),n=t.litNonce;void 0!==n&&o.setAttribute(\"nonce\",n),o.textContent=e.cssText,s.appendChild(o)}},c=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e=\"\";for(const s of t.cssRules)e+=s.cssText;return r(e)})(t):t;export{n as CSSResult,S as adoptStyles,i as css,c as getCompatibleStyle,e as supportsAdoptingStyleSheets,r as unsafeCSS};\n//# sourceMappingURL=css-tag.js.map\n","import{getCompatibleStyle as t,adoptStyles as s}from\"./css-tag.js\";export{CSSResult,css,supportsAdoptingStyleSheets,unsafeCSS}from\"./css-tag.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{is:i,defineProperty:e,getOwnPropertyDescriptor:h,getOwnPropertyNames:r,getOwnPropertySymbols:o,getPrototypeOf:n}=Object,a=globalThis,c=a.trustedTypes,l=c?c.emptyScript:\"\",p=a.reactiveElementPolyfillSupport,d=(t,s)=>t,u={toAttribute(t,s){switch(s){case Boolean:t=t?l:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,s){let i=t;switch(s){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},f=(t,s)=>!i(t,s),b={attribute:!0,type:String,converter:u,reflect:!1,useDefault:!1,hasChanged:f};Symbol.metadata??=Symbol(\"metadata\"),a.litPropertyMetadata??=new WeakMap;class y extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,s=b){if(s.state&&(s.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((s=Object.create(s)).wrapped=!0),this.elementProperties.set(t,s),!s.noAccessor){const i=Symbol(),h=this.getPropertyDescriptor(t,i,s);void 0!==h&&e(this.prototype,t,h)}}static getPropertyDescriptor(t,s,i){const{get:e,set:r}=h(this.prototype,t)??{get(){return this[s]},set(t){this[s]=t}};return{get:e,set(s){const h=e?.call(this);r?.call(this,s),this.requestUpdate(t,h,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(d(\"elementProperties\")))return;const t=n(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(d(\"finalized\")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(d(\"properties\"))){const t=this.properties,s=[...r(t),...o(t)];for(const i of s)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const s=litPropertyMetadata.get(t);if(void 0!==s)for(const[t,i]of s)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,s]of this.elementProperties){const i=this._$Eu(t,s);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(s){const i=[];if(Array.isArray(s)){const e=new Set(s.flat(1/0).reverse());for(const s of e)i.unshift(t(s))}else void 0!==s&&i.push(t(s));return i}static _$Eu(t,s){const i=s.attribute;return!1===i?void 0:\"string\"==typeof i?i:\"string\"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise((t=>this.enableUpdating=t)),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach((t=>t(this)))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,s=this.constructor.elementProperties;for(const i of s.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const t=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return s(t,this.constructor.elementStyles),t}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach((t=>t.hostConnected?.()))}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach((t=>t.hostDisconnected?.()))}attributeChangedCallback(t,s,i){this._$AK(t,i)}_$ET(t,s){const i=this.constructor.elementProperties.get(t),e=this.constructor._$Eu(t,i);if(void 0!==e&&!0===i.reflect){const h=(void 0!==i.converter?.toAttribute?i.converter:u).toAttribute(s,i.type);this._$Em=t,null==h?this.removeAttribute(e):this.setAttribute(e,h),this._$Em=null}}_$AK(t,s){const i=this.constructor,e=i._$Eh.get(t);if(void 0!==e&&this._$Em!==e){const t=i.getPropertyOptions(e),h=\"function\"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:u;this._$Em=e;const r=h.fromAttribute(s,t.type);this[e]=r??this._$Ej?.get(e)??r,this._$Em=null}}requestUpdate(t,s,i){if(void 0!==t){const e=this.constructor,h=this[t];if(i??=e.getPropertyOptions(t),!((i.hasChanged??f)(h,s)||i.useDefault&&i.reflect&&h===this._$Ej?.get(t)&&!this.hasAttribute(e._$Eu(t,i))))return;this.C(t,s,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,s,{useDefault:i,reflect:e,wrapped:h},r){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,r??s??this[t]),!0!==h||void 0!==r)||(this._$AL.has(t)||(this.hasUpdated||i||(s=void 0),this._$AL.set(t,s)),!0===e&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,s]of this._$Ep)this[t]=s;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[s,i]of t){const{wrapped:t}=i,e=this[s];!0!==t||this._$AL.has(s)||void 0===e||this.C(s,void 0,i,e)}}let t=!1;const s=this._$AL;try{t=this.shouldUpdate(s),t?(this.willUpdate(s),this._$EO?.forEach((t=>t.hostUpdate?.())),this.update(s)):this._$EM()}catch(s){throw t=!1,this._$EM(),s}t&&this._$AE(s)}willUpdate(t){}_$AE(t){this._$EO?.forEach((t=>t.hostUpdated?.())),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach((t=>this._$ET(t,this[t]))),this._$EM()}updated(t){}firstUpdated(t){}}y.elementStyles=[],y.shadowRootOptions={mode:\"open\"},y[d(\"elementProperties\")]=new Map,y[d(\"finalized\")]=new Map,p?.({ReactiveElement:y}),(a.reactiveElementVersions??=[]).push(\"2.1.1\");export{y as ReactiveElement,s as adoptStyles,u as defaultConverter,t as getCompatibleStyle,f as notEqual};\n//# sourceMappingURL=reactive-element.js.map\n","// a style for the context menu should be set at the top level context menu and it should trickle down or looked up recurisvely?\n\nexport type ContextMenuType = \"single\" | \"multi\" | \"canvas\";\n\ntype ContextMenuElCoreOption = {\n text: string;\n parent?: ContextMenuGroup;\n style?: CSSStyleDeclaration;\n subMenu?: ContextMenuProps;\n};\n\ntype ContextMenuElOption =\n | (ContextMenuElCoreOption & {\n onClick?: (e?: MouseEvent) => void;\n onHover?: (e?: MouseEvent) => void;\n })\n | (ContextMenuElCoreOption & { childOptions: ContextMenuElOption[] });\n\nexport type ContextMenuProps = {\n options: ContextMenuGroupProps[];\n};\n\nexport type ContextMenuGroupProps = {\n childOptions: ContextMenuElOption[];\n};\n\n/**\n * When a context menu is opened, its children are displayed\n */\nexport class ContextMenu {\n _el: HTMLDivElement;\n options: ContextMenuGroup[] = [];\n rootNode: DocumentFragment | HTMLElement;\n\n get el() {\n return this._el;\n }\n\n constructor(\n option: ContextMenuProps,\n rootNode: DocumentFragment | HTMLElement,\n ) {\n this.rootNode = rootNode;\n this._el = document.createElement(\"div\");\n this._el.classList.add(\"context-menu\");\n\n option.options.forEach((o, idx) => {\n this.createOptionGroup(o);\n if (idx !== option.options.length - 1) {\n this.addDivider();\n }\n });\n\n this._el.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n });\n }\n\n attachToParent(parent: Node) {\n parent.appendChild(this.el);\n }\n\n private createOptionGroup(option: ContextMenuGroupProps) {\n const element = new ContextMenuGroup(option, this.rootNode);\n this.options.push(element);\n this.el.appendChild(element.el);\n }\n\n private addDivider() {\n // const divider = document.createElement('div');\n const divider = document.createElement(\"hr\");\n divider.classList.add(\"context-menu-divider\");\n this.el.appendChild(divider);\n }\n}\n\nexport class ContextMenuGroup {\n _el: HTMLDivElement;\n childOptions: ContextMenuElement[] = [];\n rootNode: DocumentFragment | HTMLElement;\n\n get el() {\n return this._el;\n }\n\n constructor(\n option: ContextMenuGroupProps,\n rootNode: DocumentFragment | HTMLElement,\n ) {\n this.rootNode = rootNode;\n this._el = document.createElement(\"div\");\n this.createOptionElement = this.createOptionElement.bind(this);\n\n option.childOptions.forEach((o) => this.createOptionElement(o));\n }\n\n attachToParent(parent: Node) {\n parent.appendChild(this.el);\n }\n\n private createOptionElement(option: ContextMenuElOption) {\n option.parent = this;\n const element = new ContextMenuElement(option, this.rootNode);\n this.childOptions.push(element);\n }\n}\n\n/**\n * An element MAY have a submenu that will open up if they are selected (we will consider this in the future)\n * Otherwise, trigger the onclick function instead.\n * In its construction, either a sub menu has to be passed or an onclick must be added\n */\nexport class ContextMenuElement {\n displayText: string;\n _el: HTMLButtonElement;\n parent: ContextMenuGroup;\n subMenu?: ContextMenu;\n rootNode: DocumentFragment | HTMLElement;\n\n get el() {\n return this._el;\n }\n\n constructor(\n option: ContextMenuElOption,\n rootNode: DocumentFragment | HTMLElement,\n ) {\n this.displayText = option.text;\n this.rootNode = rootNode;\n this.parent = option.parent;\n this._el = document.createElement(\"button\");\n this._el.textContent = option.text;\n this._el.classList.add(\"context-menu-option\");\n\n this.parent.el.appendChild(this._el);\n\n if (\"onClick\" in option) {\n this._el.addEventListener(\"click\", option.onClick);\n }\n\n this._el.addEventListener(\"pointerenter\", (e: PointerEvent) =>\n onpointerenter(e, option, this._el, this.rootNode),\n );\n\n this._el.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n });\n }\n}\n\nfunction onpointerenter(\n e: PointerEvent,\n parentOption: ContextMenuElOption,\n parentEl: Node,\n rootNode: DocumentFragment | HTMLElement,\n) {\n if (!rootNode) return;\n const oldMenu = rootNode.querySelector(\".sub-context-menu\");\n if (oldMenu) oldMenu.remove();\n\n if (parentOption.subMenu) {\n const newMenu = new ContextMenu(parentOption.subMenu, this);\n rootNode.appendChild(newMenu.el);\n\n newMenu.el.id = `${parentOption.text}-context-menu`;\n newMenu.el.classList.add(\"sub-context-menu\");\n\n // calculate proper position\n const hostRect = (rootNode as any).getBoundingClientRect();\n const parentBoundingBox = (\n parentEl as HTMLDivElement\n ).getBoundingClientRect();\n const menuRect = newMenu.el.getBoundingClientRect();\n\n const hostWidth = hostRect.right - hostRect.left;\n const hostHeight = hostRect.bottom - hostRect.top;\n\n const menuWidth = parentBoundingBox.right + menuRect.width;\n const menuHeight = parentBoundingBox.top + menuRect.height;\n\n if (menuHeight > hostHeight) {\n newMenu._el.style.top = `${parentBoundingBox.bottom - menuRect.height}px`;\n } else {\n newMenu._el.style.top = `${parentBoundingBox.top}px`;\n }\n\n if (menuWidth > hostWidth) {\n newMenu._el.style.left = `${parentBoundingBox.left - menuRect.width}px`;\n } else {\n newMenu._el.style.left = `${parentBoundingBox.right}px`;\n }\n }\n}\n","import { ContextMenuEvent } from \"../util\";\nimport {\n ContextMenu,\n ContextMenuGroupProps,\n ContextMenuType,\n} from \"./ContextMenu\";\n\nconst PADDING = 5;\n\nfunction withContextMenuClear<T extends (...args: any[]) => any>(fn: T): T {\n const self = this;\n return function (this: any, ...args: Parameters<T>): ReturnType<T> {\n const result = fn.apply(self, args);\n self.clearContextMenu();\n return result;\n } as T;\n}\n\nexport function addContextMenu(\n x: number,\n y: number,\n type: ContextMenuType = \"single\",\n) {\n // Create new menu\n const menu = new ContextMenu(\n type === \"single\"\n ? this.singleImageMenuOptions\n : type === \"multi\"\n ? this.multiImageMenuOptions\n : this.canvasImageMenuOptions,\n this.rootDiv,\n );\n if (!this.rootDiv) {\n console.error(\"Can't add to parent div\");\n return;\n }\n\n menu.attachToParent(this.rootDiv as HTMLElement);\n\n // Position the menu\n const hostRect = this.getBoundingClientRect();\n\n const relX = x - hostRect.left; // relative x to the client\n const relY = y - hostRect.top; // relative y to the client\n\n // determine the width and height of the bound rect\n const hostWidth = hostRect.right - hostRect.left;\n const hostHeight = hostRect.bottom - hostRect.top;\n // place the menu according to the four quarters so it is always in view\n const menuRect = menu.el.getBoundingClientRect();\n\n // only flip the position of the menu if leaving it where it would have been, would lead to the menu being out of view\n const direction: number[] = [\n relX + menuRect.width > hostWidth ? 1 : 0,\n relY + menuRect.height > hostHeight ? 1 : 0,\n ];\n\n const menuHeight = menuRect.height * direction[1];\n const menuWidth = menuRect.width * direction[0];\n\n if (menuHeight > hostHeight) {\n const newHeight = hostHeight - 2 * PADDING;\n menu._el.style.height = `${newHeight}px`;\n menu._el.style.top = `${PADDING}px`;\n } else {\n menu._el.style.top = `${relY - menuHeight}px`;\n }\n\n if (menuWidth > hostWidth) {\n menu._el.style.width = `${hostWidth - 2 * PADDING}px`;\n menu._el.style.left = `${PADDING}px`;\n } else {\n menu._el.style.left = `${relX - menuWidth}px`;\n }\n}\n\nexport function clearContextMenu() {\n const oldMenu = this.renderRoot.querySelector(\".context-menu\");\n if (oldMenu) {\n oldMenu.remove();\n this.eventHub.emit(ContextMenuEvent.Close);\n }\n}\n\nexport function isContextMenuActive() {\n return this.renderRoot.querySelector(\".context-menu\") !== null;\n}\n\nexport function createBasicImageMenuOptions() {\n const withClear = withContextMenuClear.bind(this);\n return {\n options: [\n {\n childOptions: [\n {\n text: \"Cut\",\n onClick: async () => {\n await this.copyImage.bind(this)();\n withClear(this.deleteSelectedImages.bind(this))();\n },\n },\n {\n text: \"Copy\",\n onClick: withClear(this.copyImage.bind(this)),\n },\n {\n text: \"Paste\",\n onClick: (e: PointerEvent) =>\n withClear(this.pasteImage.bind(this))(e),\n },\n {\n text: \"Delete\",\n onClick: withClear(this.deleteSelectedImages.bind(this)),\n },\n ],\n },\n {\n childOptions: [\n {\n text: \"Flip Horizontal\",\n onClick: withClear(this.flipHorizontal.bind(this)),\n },\n {\n text: \"Flip Vertical\",\n onClick: withClear(this.flipVertical.bind(this)),\n },\n ],\n },\n ],\n };\n}\n\nexport function createSingleImageMenuOptions(base?: ContextMenuGroupProps[]) {\n const withClear = withContextMenuClear.bind(this);\n return {\n options: [\n ...(base ?? []),\n {\n childOptions: [\n {\n text: \"Send to Front\",\n onClick: () =>\n withClear(this.sendShapeToNewZOrder.bind(this))(true),\n },\n {\n text: \"Send to Back\",\n onClick: () =>\n withClear(this.sendShapeToNewZOrder.bind(this))(false),\n },\n ],\n },\n ],\n };\n}\n\nexport function createMultiImageMenuOptions(base?: ContextMenuGroupProps[]) {\n const withClear = withContextMenuClear.bind(this);\n return {\n options: [\n ...(base ?? []),\n {\n childOptions: [\n {\n text: \"Align\",\n onHover: () => {},\n subMenu: {\n options: [\n {\n childOptions: [\n {\n text: \"Align Left\",\n onClick: () => withClear(this.align.bind(this))(\"left\"),\n },\n {\n text: \"Align Right\",\n onClick: () => withClear(this.align.bind(this))(\"right\"),\n },\n {\n text: \"Align Top\",\n onClick: () => withClear(this.align.bind(this))(\"top\"),\n },\n {\n text: \"Align Bottom\",\n onClick: () => withClear(this.align.bind(this))(\"bottom\"),\n },\n ],\n },\n ],\n },\n },\n {\n text: \"Normalize by First\",\n onHover: () => {},\n subMenu: {\n options: [\n {\n childOptions: [\n {\n text: \"Height\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"height\",\n \"first\",\n ),\n },\n {\n text: \"Width\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"width\",\n \"first\",\n ),\n },\n {\n text: \"Size\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"size\",\n \"first\",\n ),\n },\n {\n text: \"Scale\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"scale\",\n \"first\",\n ),\n },\n ],\n },\n ],\n },\n },\n {\n text: \"Normalize by Average\",\n onHover: () => {},\n subMenu: {\n options: [\n {\n childOptions: [\n {\n text: \"Height\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"height\",\n \"average\",\n ),\n },\n {\n text: \"Width\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"width\",\n \"average\",\n ),\n },\n {\n text: \"Size\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"size\",\n \"average\",\n ),\n },\n {\n text: \"Scale\",\n onClick: () =>\n withClear(this.normalizeSelection.bind(this))(\n \"scale\",\n \"average\",\n ),\n },\n ],\n },\n ],\n },\n },\n ],\n },\n ],\n };\n}\n\nexport function createCanvasImageMenuOptions(base?: ContextMenuGroupProps[]) {\n const withClear = withContextMenuClear.bind(this);\n return {\n options: [\n ...(base ?? []),\n {\n childOptions: [\n {\n text: \"Change mode\",\n onClick: () => withClear(this.togglePointerMode.bind(this))(),\n },\n {\n text: \"Toggle Grid\",\n onClick: () => withClear(this.toggleGrid.bind(this))(),\n },\n ],\n },\n {\n childOptions: [\n {\n text: \"Save\",\n onClick: () => withClear(this.saveToCanvasStorage.bind(this))(),\n },\n {\n text: \"Paste\",\n onClick: (e: PointerEvent) =>\n withClear(this.pasteImage.bind(this))(e),\n },\n ],\n },\n ],\n };\n}\n","import { SerializedCanvas } from \"serializer\";\nimport { getMimeType, hashStringToId } from \"../util\";\n\nexport class ImageFileMetadata {\n private _id: string | number;\n private _dataURL: string;\n private _mimetype: string;\n private _created: number;\n private _lastRetrieved: number;\n\n private _touch() {\n this._lastRetrieved = Date.now();\n }\n\n get id() {\n this._touch();\n return this._id;\n }\n\n get dataURL() {\n this._touch();\n return this._dataURL;\n }\n\n get mimetype() {\n this._touch();\n return this._mimetype;\n }\n\n get created() {\n this._touch();\n return this._created;\n }\n\n get lastRetrieved() {\n return this._lastRetrieved;\n }\n\n constructor(dataURL: string) {\n this._dataURL = dataURL;\n this._mimetype = getMimeType(dataURL);\n this._created = Date.now();\n this._lastRetrieved = Date.now();\n }\n\n static async create(dataURL: string): Promise<ImageFileMetadata> {\n const entry = new ImageFileMetadata(dataURL);\n entry._id = await hashStringToId(dataURL);\n return entry;\n }\n}\n\nexport abstract class FileStorage {\n abstract write(data: string): Promise<string | number>;\n abstract readAll(): Promise<ImageFileMetadata[]>;\n abstract readPage(\n offset: number,\n limit: number,\n ): Promise<ImageFileMetadata[]>;\n abstract read(id: string): Promise<ImageFileMetadata>;\n abstract delete(id: string): Promise<ImageFileMetadata>;\n abstract update(newVersion: ImageFileMetadata): Promise<ImageFileMetadata>;\n abstract checkIfImageStored(id: string): Promise<string | number | null>;\n}\n\nexport type CanvasStorageEntry = SerializedCanvas;\n\n/**\n * Writes the canvas data into storage\n */\nexport abstract class CanvasStorage {\n abstract write(value: CanvasStorageEntry): Promise<void>;\n abstract read(): Promise<string>;\n abstract delete(): Promise<void>;\n abstract update(value: CanvasStorageEntry): Promise<void>;\n}\n","/**\n * This class allows you to use UUID primary keys in Dexie by defining them in the store using two dollar signs ($$), eg:\n *\n * db.version(1).stores({\n * orders: '$$id, price',\n * order_products: '$$id, product, order_id'\n * });\n *\n * Parts are adapted from dexie-observable.js.\n * Sourced from https://gist.github.com/SabatinoMasala/c5e1700fc89751d0bf8c868e5ff86abd\n * Original code extracted by sabatino.dev\n */\n\nimport Dexie from \"dexie\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/**\n * DexieUUIDPrimaryKey plugin\n * @param db\n * @constructor\n */\nfunction DexieUUIDPrimaryKey(db) {\n // Override the _parseStoresSpec method with our own implementation\n db.Version.prototype._parseStoresSpec = Dexie.override(\n db.Version.prototype._parseStoresSpec,\n overrideParseStoresSpec,\n );\n // Override the open method with our own implementation\n db.open = Dexie.override(db.open, prepareOverrideOpen(db));\n}\n\n/**\n * This function overrides the parseStoresSpec method of Dexie to allow for UUID primary keys.\n * @param origFunc\n * @returns {(function(*, *): void)|*}\n */\nfunction overrideParseStoresSpec(origFunc) {\n return function (stores, dbSchema) {\n origFunc.call(this, stores, dbSchema);\n Object.keys(dbSchema).forEach(function (tableName) {\n let schema = dbSchema[tableName];\n if (schema.primKey.name.indexOf(\"$$\") === 0) {\n schema.primKey.uuid = true;\n schema.primKey.name = schema.primKey.name.substr(2);\n schema.primKey.keyPath = schema.primKey.keyPath.substr(2);\n }\n });\n };\n}\n\n/**\n * This function prepares the hook that will trigger on creation of a new record\n * @param table\n * @returns {function(*, *): undefined}\n */\nfunction initCreatingHook(table) {\n return function creatingHook(primKey, obj) {\n let rv = undefined;\n if (primKey === undefined && table.schema.primKey.uuid) {\n primKey = rv = uuidv4();\n if (table.schema.primKey.keyPath) {\n Dexie.setByKeyPath(obj, table.schema.primKey.keyPath, primKey);\n }\n }\n\n return rv;\n };\n}\n\n/**\n * This function prepares the hook that will trigger on opening the database and will loop through all tables to add the creating hook.\n * @param db\n * @returns {function(*): function(): *}\n */\nfunction prepareOverrideOpen(db) {\n return function overrideOpen(origOpen) {\n return function () {\n Object.keys(db._allTables).forEach((tableName) => {\n let table = db._allTables[tableName];\n table.hook(\"creating\").subscribe(initCreatingHook(table));\n });\n return origOpen.apply(this, arguments);\n };\n };\n}\n\n// Register addon:\nDexie.UUIDPrimaryKey = DexieUUIDPrimaryKey;\nDexie.addons.push(DexieUUIDPrimaryKey);\n\nexport default Dexie.UUIDPrimaryKey;\n","import \"./dexie-primary-key.js\";\nimport Dexie, { DexieConstructor, EntityTable } from \"dexie\";\nimport {\n ImageFileMetadata,\n FileStorage,\n CanvasStorage,\n CanvasStorageEntry,\n} from \"./storage\";\n\nconst dbVersion1 = {\n files: \"$$id, mimetype, created, lastRetrieved\",\n};\n\nconst DB_LIMITS = {\n MAX_IMAGE_ENTRIES: 1000,\n} as const;\n\ntype DexieConstructorWithUUID = DexieConstructor & {\n UUIDPrimaryKey: Function;\n};\n\ninterface IndexDb extends Dexie {\n files: EntityTable<ImageFileMetadata, \"id\">;\n}\n\nexport class DefaultIndexedDbStorage extends FileStorage {\n private dbQueue = new DatabaseQueue();\n private dbPromise: Promise<IndexDb>;\n private cache = new Map<string | number, ImageFileMetadata>();\n private CACHE_LIMIT = 500;\n\n constructor() {\n super();\n this.dbQueue = new DatabaseQueue();\n this.dbPromise = this.initDb();\n }\n\n private async initDb(): Promise<IndexDb> {\n return handleQuotaError(async (): Promise<IndexDb> => {\n let db = new Dexie(\"InfiniteCanvas\") as IndexDb;\n (Dexie as DexieConstructorWithUUID).UUIDPrimaryKey(db);\n db.version(1).stores(dbVersion1);\n await db.open();\n return db;\n });\n }\n\n private async getIndexDb(): Promise<IndexDb> {\n return this.dbPromise;\n }\n\n /**\n * Writes to indexedDB\n * @param data\n * @param mimetype\n * @returns the file ID\n */\n async write(data: string): Promise<string | number> {\n const file: ImageFileMetadata = await ImageFileMetadata.create(data);\n const blob = dataUrlToBlob(file.dataURL);\n\n return this.dbQueue.add(() =>\n handleQuotaError(async (): Promise<string | number> => {\n const db: IndexDb = await this.getIndexDb();\n\n return await db\n .transaction(\"rw\", db.files, async () => {\n await checkImageLimit(db);\n\n return await db.files.add({\n id: file.id,\n blob,\n dataURL: file.dataURL,\n mimetype: file.mimetype,\n created: file.created,\n lastRetrieved: file.lastRetrieved,\n } as any);\n })\n .catch((error) => {\n console.error(\"Failed to save image blob to local DB:\", error);\n throw error;\n });\n }),\n );\n }\n\n async readAll(): Promise<ImageFileMetadata[]> {\n return handleQuotaError(async (): Promise<ImageFileMetadata[]> => {\n const db: IndexDb = await this.getIndexDb();\n return await db.files.toArray();\n });\n }\n\n async readPage(offset: number, limit: number): Promise<ImageFileMetadata[]> {\n return handleQuotaError(async (): Promise<ImageFileMetadata[]> => {\n const db: IndexDb = await this.getIndexDb();\n return await db.files.offset(offset).limit(limit).toArray();\n });\n }\n\n async read(id: string | number): Promise<ImageFileMetadata> {\n return handleQuotaError(async (): Promise<ImageFileMetadata> => {\n const db: IndexDb = await this.getIndexDb();\n\n if (this.cache.has(id)) {\n return this.cache.get(id) as ImageFileMetadata;\n }\n\n const entry = await db.files.get(id);\n\n if (!entry) return null;\n this.dbQueue\n .add(async () => {\n try {\n await db.files.update(id, { lastRetrieved: Date.now() });\n } catch (e) {\n console.error(\"Failed to update lastRetrieved\", e);\n }\n })\n .catch(() => {});\n\n this.cache.set(id, entry);\n if (this.cache.size > this.CACHE_LIMIT) {\n const firstKey = this.cache.keys().next().value;\n this.cache.delete(firstKey);\n }\n\n return entry;\n });\n }\n\n async delete(id: string): Promise<ImageFileMetadata> {\n return this.dbQueue.add(() =>\n handleQuotaError(async (): Promise<ImageFileMetadata> => {\n const db: IndexDb = await this.getIndexDb();\n\n return await db\n .transaction(\"rw\", db.files, async () => {\n const entry = await db.files.where(\"id\").equals(id).first();\n await db.files.delete(entry.id);\n return entry;\n })\n .catch((error) => {\n console.error(\"Failed to save image blob to local DB:\", error);\n throw error;\n });\n }),\n );\n }\n\n async update(newVersion: ImageFileMetadata): Promise<ImageFileMetadata> {\n return this.dbQueue.add(() =>\n handleQuotaError(async (): Promise<ImageFileMetadata> => {\n const db: IndexDb = await this.getIndexDb();\n\n await db.transaction(\"rw\", db.files, async () => {\n await db.files.update(newVersion.id, {\n dataURL: newVersion.dataURL,\n mimetype: newVersion.mimetype,\n lastRetrieved: Date.now(),\n });\n });\n\n const updated = await db.files\n .where(\"id\")\n .equals(newVersion.id)\n .first();\n return updated;\n }),\n );\n }\n\n async checkIfImageStored(id: string): Promise<string | number | null> {\n return handleQuotaError(async (): Promise<string | number | null> => {\n const db: IndexDb = await this.getIndexDb();\n const entry = await db.files.where(\"id\").equals(id).first();\n return entry ? entry.id : null;\n });\n }\n}\n\nexport class DefaultLocalStorage extends CanvasStorage {\n key: string = \"infinite_canvas\";\n\n constructor(key: string) {\n super();\n this.key = key;\n }\n\n async write(value: CanvasStorageEntry): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n localStorage.setItem(this.key, JSON.stringify(value));\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n }\n\n async read(): Promise<string> {\n return new Promise((resolve, reject) => {\n try {\n resolve(localStorage.getItem(this.key));\n } catch (err) {\n reject(err);\n }\n });\n }\n\n async delete(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n localStorage.removeItem(this.key);\n resolve();\n } catch (err) {\n reject(err);\n }\n });\n }\n\n async update(value: CanvasStorageEntry): Promise<void> {\n return this.write(value);\n }\n}\n\nclass QuotaExceededError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"QuotaExceededError\";\n }\n}\n\nclass DatabaseLimitError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"DatabaseLimitError\";\n }\n}\n\nclass DatabaseQueue {\n private queue: Promise<any> = Promise.resolve();\n\n async add<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.queue.then(() => operation());\n this.queue = result.catch(() => {}); // Keep queue moving even on errors\n return result;\n }\n}\n\nconst handleQuotaError = async <T>(operation: () => Promise<T>): Promise<T> => {\n try {\n return await operation();\n } catch (err) {\n if (err instanceof DOMException && err.name === \"QuotaExceededError\") {\n throw new QuotaExceededError(\n \"Storage quota exceeded. Please free up space.\",\n );\n }\n if (err instanceof Dexie.QuotaExceededError) {\n throw new QuotaExceededError(\n \"Database quota exceeded. Please free up space.\",\n );\n }\n throw err;\n }\n};\n\nasync function checkImageLimit(db: IndexDb): Promise<void> {\n const count = await db.files.count();\n if (count >= DB_LIMITS.MAX_IMAGE_ENTRIES) {\n throw new DatabaseLimitError(\n `Cannot save image: limit of ${DB_LIMITS.MAX_IMAGE_ENTRIES} reached`,\n );\n }\n}\n\nexport function dataUrlToBlob(dataUrl: string): Blob {\n const parts = dataUrl.split(\",\");\n const meta = parts[0];\n const base64 = parts[1];\n const mimeMatch = meta.match(/:(.*?);/);\n const mime = mimeMatch ? mimeMatch[1] : \"application/octet-stream\";\n const binary = atob(base64);\n const len = binary.length;\n const u8 = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n u8[i] = binary.charCodeAt(i);\n }\n return new Blob([u8], { type: mime });\n}\n","export type LoaderType = \"spinner\" | \"message\";\n\nexport type LoaderProps = {\n type: LoaderType;\n message?: string;\n};\n\nexport class Loader {\n _el: HTMLDivElement;\n type: LoaderType;\n message?: string;\n progress?: number;\n\n get el() {\n return this._el;\n }\n\n constructor(props: LoaderProps) {\n this.type = props.type;\n this.message = props.message;\n\n this._el = document.createElement(\"div\");\n this._el.classList.add(\"canvas-loader\");\n\n this.render();\n }\n\n private render() {\n this._el.innerHTML = \"\";\n\n if (this.type === \"spinner\") {\n const spinner = document.createElement(\"div\");\n spinner.classList.add(\"canvas-loader-spinner\");\n this._el.appendChild(spinner);\n if (this.message) {\n const msg = document.createElement(\"div\");\n msg.classList.add(\"canvas-loader-message\");\n msg.textContent = this.message;\n this._el.appendChild(msg);\n }\n } else if (this.type === \"message\") {\n const msg = document.createElement(\"div\");\n msg.classList.add(\"canvas-loader-message\");\n msg.textContent = this.message ?? \"\";\n this._el.appendChild(msg);\n }\n }\n\n setMessage(message: string) {\n this.message = message;\n this.render();\n }\n\n setProgress(progress: number) {\n this.progress = progress;\n this.render();\n }\n\n attachToParent(parent: Node) {\n parent.appendChild(this.el);\n }\n\n remove() {\n if (this._el.parentNode) {\n this._el.parentNode.removeChild(this._el);\n }\n }\n}\n","import { Loader, LoaderType } from \"./Loader\";\n\nexport function showLoader(type: LoaderType, message?: string) {\n const loader = new Loader({ type, message });\n loader.attachToParent(this.renderRoot as HTMLElement);\n\n const hostRect = this.getBoundingClientRect();\n loader.el.style.width = `${hostRect.right}px`;\n loader.el.style.height = `${hostRect.bottom}px`;\n loader._el.style.top = `${-hostRect.bottom}px`;\n\n return loader;\n}\n\nexport function hideLoader() {\n const oldLoader = this.renderRoot.querySelector(\".canvas-loader\");\n if (oldLoader) {\n oldLoader.remove();\n }\n}\n","import { CanvasHistory } from \"./history\";\nimport { Canvas } from \"./Canvas\";\nimport { LitElement, PropertyValues, css } from \"lit\";\nimport { customElement } from \"lit/decorators.js\";\nimport {\n CanvasEvent,\n ContextMenuEvent,\n copy,\n getWorldCoords,\n addImages as innerAddImages,\n LoaderEvent,\n paste,\n SaveEvent,\n} from \"./util\";\nimport { downloadJSON, hashStringToId, readJSONFile } from \"./util/files\";\nimport {\n serializeCanvas,\n deserializeCanvas,\n SerializedCanvas,\n} from \"./serializer\";\nimport {\n AlignDirection,\n makeMultiAddChildCommand,\n makeRemoveChildCommand,\n NormalizeMode,\n NormalizeOption,\n} from \"./manager\";\nimport {\n addContextMenu,\n clearContextMenu,\n ContextMenuProps,\n ContextMenuType,\n createBasicImageMenuOptions,\n createCanvasImageMenuOptions,\n createMultiImageMenuOptions,\n createSingleImageMenuOptions,\n isContextMenuActive,\n} from \"./contextMenu\";\nimport {\n CanvasStorage,\n DefaultIndexedDbStorage,\n DefaultLocalStorage,\n FileStorage,\n ImageFileMetadata,\n} from \"./storage\";\nimport EventEmitter from \"eventemitter3\";\nimport { hideLoader, showLoader } from \"./loader\";\nimport Stats from \"stats.js\";\n\ntype CanvasDisplayMode = \"fullscreen\" | \"windowed\";\n\n@customElement(\"infinite-canvas\")\nexport class InfiniteCanvasElement extends LitElement {\n static properties = {\n name: { type: String, reflect: true },\n width: { type: String, reflect: true },\n height: { type: String, reflect: true },\n displayMode: { type: String, reflect: true },\n };\n\n /** The name for the canvas instance. If you are using the default local storage option for your data, this is what the entry will be stored under in your local storage. */\n name: string = \"Reffy\";\n /** The expected width of the canvas container. If there is no specific unit specified, 'px' will be automatically appended. */\n width: string;\n /** The expected height of the canvas container. If there is no specific unit specified, 'px' will be automatically appended. */\n height: string;\n /** There are two acceptable options: fullscreen (default) and windowed. Fullscreen mode will ignore the width and height you inputed. */\n displayMode: CanvasDisplayMode = \"fullscreen\";\n\n static styles = css`\n :host {\n position: relative;\n overflow: hidden;\n }\n\n .context-menu {\n position: absolute;\n background: white;\n min-width: 180px;\n background: var(--menu-bg, #fff);\n border-radius: 6px;\n border: 1px solid var(--menu-border, #9f9f9fff);\n box-sizing: border-box;\n padding: 6px 0;\n display: flex;\n gap: 2px;\n flex-direction: column;\n font-family: system-ui, sans-serif;\n animation: fadeInMenu 0.13s cubic-bezier(0.4, 0, 0.2, 1);\n overflow: scroll;\n }\n\n @keyframes fadeInMenu {\n from {\n opacity: 0;\n transform: translateY(8px);\n }\n to {\n opacity: 1;\n transform: none;\n }\n }\n\n .context-menu button {\n all: unset;\n display: flex;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n padding: 8px 18px;\n font-size: 15px;\n color: var(--menu-fg, #222);\n background: none;\n cursor: pointer;\n transition:\n background 0.1s,\n color 0.1s;\n user-select: none;\n outline: none;\n }\n\n .context-menu button:hover,\n .context-menu button:focus-visible {\n background: var(--menu-hover, #c7d5eaff);\n color: var(--menu-accent, #155290ff);\n }\n\n .context-menu button:active {\n background: var(--menu-active, #e3eaf3);\n }\n\n .context-menu button[disabled] {\n color: #aaa;\n cursor: not-allowed;\n background: none;\n }\n\n .context-menu-divider {\n height: 1px;\n background: var(--menu-divider, #c7d5eaff);\n margin: 6px 12px;\n border: none;\n }\n\n canvas {\n width: 100%;\n height: 100%;\n outline: none;\n padding: 0;\n margin: 0;\n touch-action: none;\n display: block;\n }\n\n .canvas-loader {\n position: absolute;\n top: 0;\n left: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.7);\n z-index: 1000;\n pointer-events: all;\n }\n\n .canvas-loader-spinner {\n width: 48px;\n height: 48px;\n border: 6px solid #e0e0e0;\n border-top: 6px solid #1976d2;\n border-radius: 50%;\n animation: canvas-loader-spin 1s linear infinite;\n margin-bottom: 16px;\n }\n\n @keyframes canvas-loader-spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n }\n\n .canvas-loader-message {\n font-size: 1.1rem;\n color: #333;\n background: rgba(255, 255, 255, 0.9);\n padding: 8px 16px;\n border-radius: 4px;\n margin-top: 8px;\n text-align: center;\n max-width: 80%;\n word-break: break-word;\n }\n `;\n\n #canvas: Canvas;\n #eventHub: EventEmitter;\n #resizeObserver?: ResizeObserver;\n #history: CanvasHistory;\n #fileStorage: FileStorage;\n #canvasStorage: CanvasStorage;\n #saveFrequency = 300000;\n #timeoutId: number | null;\n #intervalId: number | null;\n #onViewportResize: () => void;\n\n #rootDiv: HTMLDivElement;\n\n #onChange?: () => void;\n\n #singleImageMenuOptions: ContextMenuProps;\n #multiImageMenuOptions: ContextMenuProps;\n #canvasImageMenuOptions: ContextMenuProps;\n private addContextMenu: (x: number, y: number, type: ContextMenuType) => void;\n private clearContextMenu: () => void;\n private isContextMenuActive: () => boolean;\n\n get singleImageMenuOptions() {\n return this.#singleImageMenuOptions;\n }\n get multiImageMenuOptions() {\n return this.#multiImageMenuOptions;\n }\n get canvasImageMenuOptions() {\n return this.#canvasImageMenuOptions;\n }\n\n get canvas() {\n return this.#canvas;\n }\n\n get onCanvasChange() {\n return this.#onChange;\n }\n set onCanvasChange(fn: () => void) {\n this.#onChange = fn;\n }\n get eventHub() {\n return this.#eventHub;\n }\n get rootDiv() {\n return this.#rootDiv;\n }\n\n // Lifecycle\n connectedCallback() {\n super.connectedCallback();\n this.handleGlobalPointerDown = this.handleGlobalPointerDown.bind(this);\n document.addEventListener(\n \"pointerdown\",\n this.handleGlobalPointerDown,\n true,\n );\n }\n disconnectedCallback() {\n document.removeEventListener(\n \"pointerdown\",\n this.handleGlobalPointerDown,\n true,\n );\n window.removeEventListener(\"resize\", this.#onViewportResize);\n this.#resizeObserver?.disconnect();\n this.#resizeObserver = undefined;\n this.#canvas.destroy();\n super.disconnectedCallback();\n }\n\n protected firstUpdated(_changedProperties: PropertyValues): void {\n try {\n this.initCanvas();\n } catch (err) {\n console.error(err);\n throw err;\n }\n }\n\n protected updated(changed: PropertyValues) {\n const sizeChanged =\n changed.has(\"width\") ||\n changed.has(\"height\") ||\n changed.has(\"displayMode\");\n\n if (!sizeChanged) return;\n\n const container = this.#rootDiv;\n const canvasEl = this.renderRoot.querySelector(\n \"canvas\",\n ) as HTMLCanvasElement | null;\n\n if (container && canvasEl) {\n this.resizeCanvas(container, canvasEl);\n }\n }\n\n private async initCanvas() {\n await this.warmUpStorage();\n this.#history = new CanvasHistory();\n this.#eventHub = new EventEmitter();\n\n const div = document.createElement(\"div\");\n div.style.overflow = \"hidden\";\n\n this.renderRoot.appendChild(div);\n this.#rootDiv = div;\n\n const canvas = document.createElement(\"canvas\");\n\n // persistent state set up\n this.assignFileStorage = this.assignFileStorage.bind(this);\n this.getImageFileMetadata = this.getImageFileMetadata.bind(this);\n this.getAllImageFileMetdata = this.getAllImageFileMetdata.bind(this);\n this.saveImageFileMetadata = this.saveImageFileMetadata.bind(this);\n\n this.restoreStateFromCanvasStorage =\n this.restoreStateFromCanvasStorage.bind(this);\n this.assignCanvasStorage = this.assignCanvasStorage.bind(this);\n this.saveToCanvasStorage = this.saveToCanvasStorage.bind(this);\n this.debounceSaveToCanvasStorage =\n this.debounceSaveToCanvasStorage.bind(this);\n\n // import and export\n this.importCanvas = this.importCanvas.bind(this);\n this.exportCanvas = this.exportCanvas.bind(this);\n\n // context menu set up\n this.addContextMenu = addContextMenu.bind(this);\n this.clearContextMenu = clearContextMenu.bind(this);\n this.isContextMenuActive = isContextMenuActive.bind(this);\n\n this.getContainerSize = this.getContainerSize.bind(this);\n\n if (!div.contains(canvas)) {\n div.appendChild(canvas);\n }\n\n this.registerSignal();\n\n this.#canvas = new Canvas(\n canvas,\n this.#history,\n this.#eventHub,\n this.debounceSaveToCanvasStorage,\n this.saveImageFileMetadata,\n this.getContainerSize,\n );\n\n try {\n await this.restoreStateFromCanvasStorage();\n } catch (err) {\n console.error(\"Failed to restore canvas\");\n }\n\n // resize canvas to start\n this.resizeCanvas(div, canvas);\n this.#onViewportResize = () => this.resizeCanvas(div, canvas);\n window.addEventListener(\"resize\", this.#onViewportResize);\n\n const basicImageMenuOptions = createBasicImageMenuOptions.bind(this)();\n this.#singleImageMenuOptions = createSingleImageMenuOptions.bind(this)(\n basicImageMenuOptions.options,\n );\n this.#canvasImageMenuOptions = createCanvasImageMenuOptions.bind(this)();\n this.#multiImageMenuOptions = createMultiImageMenuOptions.bind(this)(\n basicImageMenuOptions.options,\n );\n\n this.dispatchEvent(new Event(\"load\"));\n\n const stats = new Stats();\n stats.showPanel(0);\n\n if (!this.renderRoot.contains(stats.dom)) {\n this.renderRoot.appendChild(stats.dom);\n }\n\n const animate = () => {\n if (stats) {\n stats.update();\n }\n this.#canvas.render();\n requestAnimationFrame(animate);\n };\n\n animate();\n }\n\n private normalizeCssSize(value: string): string {\n if (!value) return value;\n const trimmed = String(value).trim();\n // If it's purely numeric (e.g., \"600\"), use px by default\n if (/^\\d+$/.test(trimmed)) return `${trimmed}px`;\n return trimmed;\n }\n\n private resizeCanvas(container: HTMLDivElement, canvas: HTMLCanvasElement) {\n // set up the container div to limit the extent of the canvas that is visible\n container.style.width =\n this.displayMode === \"fullscreen\"\n ? `100vw`\n : this.normalizeCssSize(this.width);\n container.style.height =\n this.displayMode === \"fullscreen\"\n ? `100vh`\n : this.normalizeCssSize(this.height);\n container.style.overflow = \"hidden\";\n const dpr = window.devicePixelRatio || 1;\n\n // set the canvas to be as big as possible so there will never be a flickering resize problem\n let w = window.screen.width;\n let h = window.screen.height;\n\n const rect = container.getBoundingClientRect();\n\n const targetWidthPx = Math.round(w * dpr);\n const targetHeightPx = Math.round(h * dpr);\n\n if (canvas.width !== targetWidthPx || canvas.height !== targetHeightPx) {\n canvas.width = targetWidthPx;\n canvas.height = targetHeightPx;\n }\n\n canvas.style.width = `${w}px`;\n canvas.style.height = `${h}px`;\n\n // sets up camera dimensions\n this.canvas.camera.viewportX = rect.x;\n this.canvas.camera.viewportY = rect.y;\n this.canvas.camera.state.setHeight(rect.height);\n this.canvas.camera.state.setWidth(rect.width);\n }\n\n // Register signal\n private registerSignal() {\n this.#eventHub.on(LoaderEvent.start, showLoader.bind(this), \"spinner\");\n this.#eventHub.on(LoaderEvent.done, hideLoader.bind(this));\n this.#eventHub.on(ContextMenuEvent.Open, this.addContextMenu);\n this.#eventHub.on(ContextMenuEvent.Close, this.clearContextMenu);\n this.#eventHub.on(CanvasEvent.Change, () => {\n if (this.#onChange) this.#onChange();\n });\n this.#eventHub.on(SaveEvent.Save, this.saveToCanvasStorage);\n this.#eventHub.on(SaveEvent.SaveCompleted, () => {});\n this.#eventHub.on(SaveEvent.SaveFailed, () =>\n console.error(\"Failed to Save!\"),\n );\n }\n\n // need to check if this is good practice\n private async warmUpStorage() {\n if (!this.#fileStorage) {\n this.#fileStorage = new DefaultIndexedDbStorage();\n }\n try {\n await this.#fileStorage.readAll();\n } catch (err) {\n console.error(\"Storage warm-up failed\", err);\n }\n }\n\n /**\n * @returns An array containing the width and height of the container\n */\n getContainerSize() {\n if (!this.#rootDiv) return;\n const rect = this.#rootDiv.getBoundingClientRect();\n\n return [rect.width, rect.height];\n }\n\n // Storage & Persistence\n /**\n * @param storage Canvas storage stores the positions of all the renderables\n * @param saveFrequency How often should auto save execute\n */\n assignCanvasStorage(\n storage: CanvasStorage,\n saveFrequency: number = this.#saveFrequency,\n ) {\n this.#canvasStorage = storage;\n this.#saveFrequency = saveFrequency;\n this.#intervalId && clearInterval(this.#intervalId);\n this.#intervalId = setInterval(\n this.saveToCanvasStorage,\n this.#saveFrequency,\n );\n }\n\n /**\n * @param storage File storage captures the information about the image data that has previously been added. Made more efficient by using SHA of the image data for storage.\n */\n assignFileStorage(storage: FileStorage) {\n this.#fileStorage = storage;\n }\n\n /**\n * Duplicate images will not be written to the database\n * @param dataURL\n * @returns The unique ID that the image has been logged with. This is a hashed version of the image data URL\n */\n async saveImageFileMetadata(\n dataURL: string,\n ): Promise<string | number | null> {\n if (!this.#fileStorage) {\n this.#fileStorage = new DefaultIndexedDbStorage();\n }\n try {\n const id = await hashStringToId(dataURL);\n if (!(await this.#fileStorage.checkIfImageStored(id))) {\n return await this.#fileStorage.write(dataURL);\n } else {\n return id;\n }\n } catch (err) {\n console.error(err);\n }\n }\n\n /**\n * @param fileId Retrieves the file metadata\n * @returns\n */\n async getImageFileMetadata(fileId: string): Promise<ImageFileMetadata> {\n if (!this.#fileStorage) {\n this.#fileStorage = new DefaultIndexedDbStorage();\n }\n try {\n return await this.#fileStorage.read(fileId);\n } catch (err) {\n console.error(err);\n }\n }\n\n /**\n * @returns All file metadata saved in connected storage\n */\n async getAllImageFileMetdata(): Promise<ImageFileMetadata[]> {\n if (!this.#fileStorage) {\n this.#fileStorage = new DefaultIndexedDbStorage();\n }\n\n try {\n return await this.#fileStorage.readAll();\n } catch (err) {\n console.error(err);\n }\n }\n\n /**\n * Schedule the auto save to the canvas storage based on timer\n */\n debounceSaveToCanvasStorage(timeout: number = 1000) {\n if (!this.#canvasStorage) {\n this.#canvasStorage = new DefaultLocalStorage(this.name);\n }\n clearTimeout(this.#timeoutId);\n this.#timeoutId = setTimeout(this.saveToCanvasStorage, timeout);\n }\n\n async saveToCanvasStorage() {\n if (!this.#canvasStorage) {\n this.#canvasStorage = new DefaultLocalStorage(this.name);\n }\n this.#canvasStorage\n .write(serializeCanvas(this.#canvas))\n .then(() => this.#eventHub.emit(SaveEvent.SaveCompleted))\n .catch(() => this.#eventHub.emit(SaveEvent.SaveFailed));\n }\n\n async restoreStateFromCanvasStorage() {\n if (!this.#canvasStorage) {\n this.#canvasStorage = new DefaultLocalStorage(this.name);\n }\n const dataAsString = await this.#canvasStorage.read();\n const data = JSON.parse(dataAsString) as SerializedCanvas;\n if (data) {\n await deserializeCanvas(data, this.#canvas, this.getImageFileMetadata);\n }\n }\n\n // Canvas API\n togglePointerMode() {\n if (!this.#canvas) return;\n this.#canvas.changeMode();\n }\n\n toggleGrid() {\n if (!this.#canvas) return;\n this.#canvas.toggleGrid();\n }\n\n zoomIn() {\n if (!this.#canvas) return;\n this.#canvas.updateZoomByFixedAmount(-1);\n }\n\n zoomOut() {\n if (!this.#canvas) return;\n this.#canvas.updateZoomByFixedAmount();\n }\n\n async addImages(fileList: FileList) {\n if (!this.#canvas) return;\n\n const rect = this.#canvas.getBoundingClientRect();\n const clientX = rect.left + rect.width / 2;\n const clientY = rect.top + rect.height / 2;\n\n const [wx, wy] = getWorldCoords(clientX, clientY, this.#canvas);\n\n const newImages = await innerAddImages(fileList, (src: string) =>\n this.#canvas.addImageToCanvas(src, wx, wy, 1, 1, true),\n );\n this.#history.push(makeMultiAddChildCommand(this.#canvas, newImages));\n }\n\n async removeImage(id: number) {\n if (!this.#canvas) return;\n\n const child = this.#canvas.getChild(id);\n this.#canvas.removeChild(child);\n this.#history.push(makeRemoveChildCommand(this.#canvas, child));\n }\n\n /**\n * @param url Currently only accept base64 url and the image is automatically added to screen center\n */\n async addImageFromUrl(url: string) {\n if (!this.#canvas) return;\n\n const rect = this.#canvas.getBoundingClientRect();\n const clientX = rect.left + rect.width / 2;\n const clientY = rect.top + rect.height / 2;\n\n const [wx, wy] = getWorldCoords(clientX, clientY, this.#canvas);\n\n const img = await this.#canvas.addImageToCanvas(url, wx, wy, 1, 1, true);\n this.#history.push(makeMultiAddChildCommand(this.#canvas, [img]));\n }\n\n async copyImage() {\n if (!this.#canvas) return;\n await copy(this.#canvas.getSelected());\n }\n\n async pasteImage(e: PointerEvent) {\n if (!this.#canvas) return;\n await paste(e.clientX, e.clientY, this.#canvas, this.#history, false);\n }\n\n flipVertical() {\n if (!this.#canvas) return;\n this.#canvas.selectionManager.flip(\"vertical\");\n }\n\n flipHorizontal() {\n if (!this.#canvas) return;\n this.#canvas.selectionManager.flip(\"horizontal\");\n }\n\n align(direction: AlignDirection) {\n if (!this.#canvas) return;\n this.#canvas.selectionManager.alignSelection(direction);\n }\n\n normalizeSelection(type: NormalizeOption, mode: NormalizeMode) {\n if (!this.#canvas) return;\n this.#canvas.selectionManager.normalize(type, mode);\n }\n\n sendShapeToNewZOrder(toFront: boolean) {\n if (!this.#canvas) return;\n this.#canvas.setShapeZOrder(toFront);\n }\n\n deleteSelectedImages() {\n if (!this.#canvas) return;\n this.#canvas.selectionManager.deleteSelected(this.#canvas);\n }\n\n async exportCanvas(filename = \"infinite-canvas.json\") {\n if (!this.#canvas) return;\n this.#eventHub.emit(LoaderEvent.start, \"spinner\");\n const files = await this.getAllImageFileMetdata();\n const data = serializeCanvas(this.#canvas, files);\n downloadJSON(filename, data);\n this.#eventHub.emit(LoaderEvent.done);\n }\n\n async importCanvas(fileList: FileList) {\n this.#eventHub.emit(LoaderEvent.start, \"spinner\");\n if (!this.#canvas) return;\n if (!fileList || fileList.length !== 1) return;\n const file = fileList[0];\n if (\n !file.type ||\n (!file.type.includes(\"json\") &&\n !file.name.toLowerCase().endsWith(\".json\"))\n )\n return;\n const data = await readJSONFile<SerializedCanvas>(file);\n await deserializeCanvas(\n data,\n this.#canvas,\n this.getImageFileMetadata,\n this.saveImageFileMetadata,\n );\n this.#eventHub.emit(SaveEvent.Save);\n this.#eventHub.emit(LoaderEvent.done);\n }\n\n clearCanvas() {\n if (!this.#canvas) return;\n this.#canvas.clearChildren();\n }\n\n /**\n * A non-reactive method that captures the number of images added to the canvas\n */\n getTotalNumberOfChildren() {\n if (!this.#canvas) return;\n return this.#canvas.totalNumberOfChildren;\n }\n\n /**\n * A non-reactive method that captures the number of images that are in camera\n */\n getNumberOfChildrenRendered() {\n if (!this.#canvas) return;\n return this.#canvas.numberOfChildrenRendered;\n }\n\n // Global helper\n private handleGlobalPointerDown = (e: PointerEvent) => {\n if (\n !this.contains(e.target as Node) &&\n !this.renderRoot.contains(e.target as Node)\n ) {\n this.clearContextMenu();\n }\n };\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"infinite-canvas\": InfiniteCanvasElement;\n }\n}\n","import { CanvasStorage } from \"./storage\";\nimport { InfiniteCanvasElement } from \"./Component\";\n\nexport class InfiniteCanvasAPI {\n private el: InfiniteCanvasElement;\n\n constructor(el: InfiniteCanvasElement) {\n if (!el) throw new Error(\"InfiniteCanvasElement is required\");\n this.el = el;\n\n this.assignCanvasStorage = this.assignCanvasStorage.bind(this);\n this.zoomIn = this.zoomIn.bind(this);\n this.zoomOut = this.zoomOut.bind(this);\n this.toggleMode = this.toggleMode.bind(this);\n this.addImageFromLocal = this.addImageFromLocal.bind(this);\n this.exportCanvas = this.exportCanvas.bind(this);\n this.importCanvas = this.importCanvas.bind(this);\n this.clearCanvas = this.clearCanvas.bind(this);\n }\n\n static async forElement(\n selectorOrElement: string | InfiniteCanvasElement,\n ): Promise<InfiniteCanvasAPI> {\n let el: InfiniteCanvasElement | null;\n if (typeof selectorOrElement === \"string\") {\n await customElements.whenDefined(\"infinite-canvas\");\n el = document.querySelector(\n selectorOrElement,\n ) as InfiniteCanvasElement | null;\n } else {\n el = selectorOrElement;\n }\n if (!el) throw new Error(\"infinite-canvas element not found\");\n if (!el.canvas) {\n await new Promise<void>((res) =>\n el.addEventListener(\"load\", () => res(), { once: true }),\n );\n }\n return new InfiniteCanvasAPI(el);\n }\n\n /**\n * Without assigning storage, the canvas will not save any data\n * @param storage\n * @param saveFrequency How often auto save occurs in ms\n */\n assignCanvasStorage(storage: CanvasStorage, saveFrequency: number = 3000) {\n this.el.assignCanvasStorage(storage, saveFrequency);\n return this;\n }\n\n async zoomIn() {\n console.log(\"zooming\");\n this.el.zoomIn();\n }\n\n async zoomOut() {\n this.el.zoomOut();\n }\n\n async toggleMode() {\n this.el.togglePointerMode();\n }\n\n async addImageFromLocal(fileList: FileList) {\n // Validate all files are images before proceeding\n if (!fileList || fileList.length === 0) return;\n for (let i = 0; i < fileList.length; i++) {\n const file = fileList[i];\n if (!file || !file.type || !file.type.startsWith(\"image/\")) {\n throw new Error(\n \"Only specific image files are supported. Please select image files only.\",\n );\n }\n }\n\n await this.el.addImages(fileList);\n }\n\n async exportCanvas(filename?: string) {\n this.el.exportCanvas(filename);\n }\n\n async importCanvas(fileList: FileList) {\n if (!fileList || fileList.length !== 1) return;\n await this.el.importCanvas(fileList);\n }\n\n async clearCanvas() {\n this.el.clearCanvas();\n }\n}\n"],"names":["sides","corners","cornerMap","oppositeCorner","c","HANDLEPX","BORDERPX","m3","tx","ty","angleInRadians","s","sx","sy","a","b","a00","a01","a02","a10","a11","a12","a20","a21","a22","b00","b01","b02","b10","b11","b12","b20","b21","b22","matrix","dst","m00","m01","m02","m10","m11","m12","m20","m21","m22","invDet","width","height","m","v","v0","v1","d","createProgram","gl","vert","frag","vertShader","createShader","fragShader","program","type","source","shader","screenToWorld","clientX","clientY","w","h","canvas","worldMatrix","rect","dpr","x","y","xClip","yClip","proj","pv","invPV","wx","wy","getWorldCoords","innerCanvas","applyMatrixToPoint","px","py","getScaleXFromMatrix","getScaleYFromMatrix","getScalesFromMatrix","isPositive","num","isScalePositive","normalizeSign","EPS","willFlip","current","factor","next","previewImage","file","resolve","reject","reader","e","PERMISSIBLE_IMAGE_TYPES","isPermissibleImageType","fileType","hashStringToId","str","data","hashBuffer","getMimeType","match","addImages","files","addToCanvas","images","src","downloadJSON","filename","text","blob","url","readJSONFile","convertToPNG","quality","img","ctx","pngDataUrl","BASE_BLUE","LIGHT_BLUE","MARQUEE_BLUE","makeMultiAddChildCommand","parent","children","label","child","makeRemoveChildCommand","idx","makeMultiRemoveChildCommand","positions","target","i","acceptedPasteMimeType","probablySupportsClipboardWriteText","copy","selected","clipboardEvent","dataStored","json","clipboardItem","err","copyTextViaExecCommand","isRTL","textarea","yPosition","success","error","paste","history","isWorldCoord","items","types","allowed","minX","minY","el","element","base64","svgText","ContextMenuEvent","CanvasEvent","LoaderEvent","SaveEvent","gridVert","gridFrag","BoundingBoxMode","BoundingBox","mode","edge","scaleX","scaleY","borderSize","signX","signY","boxSize","hx","hy","HIT_MARGIN","corner","side","maxX","maxY","key","handle","_","dx","dy","direction","Rect","baseW","baseH","aspectRatio","curSX","curSY","prevWorldW","prevWorldH","changeInXScale","changeInYScale","min","nextW","nextH","anchor","newOrigin","r","config","HANDLE_TYPES","MultiBoundingBox","shapes","shape","parentMatrix","prevW","prevH","isTop","isBottom","isLeft","isRight","anchorX","anchorY","worldScaleX","worldScaleY","wtx","wty","newWtx","newWty","dWx","dWy","sX","sY","dLx","dLy","transformArray","transform","scaleH","scaleW","dir","aim","k","box","aabb","reference","goal","center","currH","scale","currw","currentArea","newCenter","bx1","bx2","by1","by2","arr","startX","startY","endX","endY","AABB","RECT_TYPES","MarqueeSelectionBox","wW","wH","CameraState","option","rotation","zoom","makeObservable","observable","action","computed","applyFlip","makeMultiFlipCommand","entries","multiBoundingBox","applyTransform","makeMultiTransformCommand","SelectionManager","#history","#selected","#boundingBoxes","#multiBoundingBox","#marqueeSelectionBox","#eventHub","#renderDirtyFlag","#gl","#rectProgram","startingPoint","eventHub","basicShapeProgram","getWorldMatrix","getCanvasChildren","getMarqueeCoords","proto","val","matchingBoundingBox","toBeDeleted","ans","uZLoc","transformations","resizeDirection","getGlobalClick","updateCameraPos","marqueeBox","isShiftKey","PointerMode","cursorMap","PointerEventManager","deps","hit","onWheel","boundingBoxType","ref","t","Shape","KeyEventManager","deleteSelected","assignEventListener","ContextMenuManager","#isMenuActive","isMultiBoundingBoxHit","isBoundingBoxHit","apply","makeMultiOrderCommand","PointerEventState","worldX","worldY","RenderableState","imageHeight","imageWidth","rotationDegree","radians","removedChildren","parentWorldMatrix","Renderable","listener","options","fn","WebGLRenderable","_Shape","z","uColor","size","value","right","bottom","x0","x1","y0","y1","cx","cy","Img","cameraBoundingBox","zoomFactor","threshold","cameraArea","useLowRes","naturalW","naturalH","ratio","dw","dh","bitmap","srcForTex","normalize","stride","offset","tex","GRID_TYPE","Grid","invP","invView","invVP","loc","I3","ZOOM_MIN","ZOOM_MAX","Camera","state","setWorldMatrix","updateWorldMatrix","reaction","wx0","wy0","wx1","wy1","PLACEHOLDER_IMAGE_SRC","PLACEHOLDER_IMAGE_SIZE","transformOf","node","serializeChildren","serializeNode","serializeCanvas","deserializeCanvas","getFile","writeFileToDatabase","build","instance","framedPlaceholder","framePlaceholder","Canvas","loadImageElement","srcOrBlob","tw","th","bg","objectUrl","targetW","targetH","ratioedHeight","ratioedWidth","_Canvas","writeToStorage","saveImgFileToStorage","getContainerDimension","__privateAdd","_canvas","_eventHub","_history","_camera","_gl","_basicShapeProgram","_imageProgram","_gridProgram","_grid","_isGlobalClick","_selectionManager","_pointerEventManager","_keyPressManager","_contextMenuManager","__privateSet","__privateGet","shapeVert","shapeFrag","imageVert","imageFrag","cameraState","pointerEventState","pointerManagerDeps","orders","maxOrder","id","parentBoundingBox","uZGrid","renderable","sww","swh","ww","wh","screenAABB","newImg","preview","toFront","snapShotItem","minOrder","originalCreateTexture","originalDeleteTexture","texture","originalCreateShader","originalDeleteShader","MAX_HISTORY","CanvasHistory","cmd","group","o","n$1","n","S","l","p","u","f","ContextMenu","rootNode","ContextMenuGroup","divider","ContextMenuElement","onpointerenter","parentOption","parentEl","oldMenu","newMenu","hostRect","menuRect","hostWidth","hostHeight","menuWidth","PADDING","withContextMenuClear","self","args","result","addContextMenu","menu","relX","relY","menuHeight","newHeight","clearContextMenu","isContextMenuActive","createBasicImageMenuOptions","withClear","createSingleImageMenuOptions","base","createMultiImageMenuOptions","createCanvasImageMenuOptions","ImageFileMetadata","dataURL","entry","FileStorage","CanvasStorage","DexieUUIDPrimaryKey","db","Dexie","overrideParseStoresSpec","prepareOverrideOpen","origFunc","stores","dbSchema","tableName","schema","initCreatingHook","table","primKey","obj","rv","uuidv4","origOpen","dbVersion1","DB_LIMITS","DefaultIndexedDbStorage","DatabaseQueue","handleQuotaError","dataUrlToBlob","checkImageLimit","limit","firstKey","newVersion","DefaultLocalStorage","QuotaExceededError","message","DatabaseLimitError","operation","dataUrl","parts","meta","mimeMatch","mime","binary","len","u8","Loader","props","spinner","msg","progress","showLoader","loader","hideLoader","oldLoader","_resizeObserver","_fileStorage","_canvasStorage","_saveFrequency","_timeoutId","_intervalId","_onViewportResize","_rootDiv","_onChange","_singleImageMenuOptions","_multiImageMenuOptions","_canvasImageMenuOptions","InfiniteCanvasElement","LitElement","_changedProperties","changed","container","canvasEl","EventEmitter","div","basicImageMenuOptions","stats","Stats","animate","trimmed","targetWidthPx","targetHeightPx","storage","saveFrequency","fileId","timeout","dataAsString","fileList","newImages","innerAddImages","css","__decorateClass","customElement","InfiniteCanvasAPI","selectorOrElement","res"],"mappings":"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","x_google_ignoreList":[37,38,39]}
|