@elixpo/lixsketch 5.5.14 → 5.5.15
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/react/{CopyPaste-UTU5MPKY.js → CopyPaste-7HWM3IMY.js} +2 -2
- package/dist/react/{Frame-6UR5XPAX.js → Frame-WPQZQLNT.js} +2 -2
- package/dist/react/{SceneSerializer-34VQFJN7.js → SceneSerializer-7UACFCRF.js} +2 -2
- package/dist/react/{SketchEngine-P3XNZA56.js → SketchEngine-UYMJJEVW.js} +4 -4
- package/dist/react/{chunk-BU4D2WYQ.js → chunk-2AYTBFV5.js} +19 -1
- package/dist/react/{chunk-BU4D2WYQ.js.map → chunk-2AYTBFV5.js.map} +2 -2
- package/dist/react/index.js +2 -2
- package/package.json +1 -1
- package/src/shapes/Frame.js +22 -0
- /package/dist/react/{CopyPaste-UTU5MPKY.js.map → CopyPaste-7HWM3IMY.js.map} +0 -0
- /package/dist/react/{Frame-6UR5XPAX.js.map → Frame-WPQZQLNT.js.map} +0 -0
- /package/dist/react/{SceneSerializer-34VQFJN7.js.map → SceneSerializer-7UACFCRF.js.map} +0 -0
- /package/dist/react/{SketchEngine-P3XNZA56.js.map → SketchEngine-UYMJJEVW.js.map} +0 -0
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-JQ3IRFDP.js";
|
|
11
11
|
import {
|
|
12
12
|
Frame
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2AYTBFV5.js";
|
|
14
14
|
import {
|
|
15
15
|
FreehandStroke
|
|
16
16
|
} from "./chunk-HKYUJUD7.js";
|
|
@@ -570,4 +570,4 @@ export {
|
|
|
570
570
|
initCopyPaste,
|
|
571
571
|
pasteClipboard
|
|
572
572
|
};
|
|
573
|
-
//# sourceMappingURL=CopyPaste-
|
|
573
|
+
//# sourceMappingURL=CopyPaste-7HWM3IMY.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
Frame
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2AYTBFV5.js";
|
|
5
5
|
import "./chunk-BZE4CEBG.js";
|
|
6
6
|
import "./chunk-L5OARZJ7.js";
|
|
7
7
|
export {
|
|
8
8
|
Frame
|
|
9
9
|
};
|
|
10
|
-
//# sourceMappingURL=Frame-
|
|
10
|
+
//# sourceMappingURL=Frame-WPQZQLNT.js.map
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "./chunk-JQ3IRFDP.js";
|
|
11
11
|
import {
|
|
12
12
|
Frame
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2AYTBFV5.js";
|
|
14
14
|
import {
|
|
15
15
|
FreehandStroke
|
|
16
16
|
} from "./chunk-HKYUJUD7.js";
|
|
@@ -736,4 +736,4 @@ export {
|
|
|
736
736
|
uploadScene,
|
|
737
737
|
validateScene
|
|
738
738
|
};
|
|
739
|
-
//# sourceMappingURL=SceneSerializer-
|
|
739
|
+
//# sourceMappingURL=SceneSerializer-7UACFCRF.js.map
|
|
@@ -169,7 +169,7 @@ var SketchEngine = class {
|
|
|
169
169
|
import("./CodeShape-TE74XP5V.js"),
|
|
170
170
|
import("./ImageShape-CHHGBXUQ.js"),
|
|
171
171
|
import("./IconShape-KMIA6T2H.js"),
|
|
172
|
-
import("./Frame-
|
|
172
|
+
import("./Frame-WPQZQLNT.js"),
|
|
173
173
|
import("./FreehandStroke-BOWDNAVC.js")
|
|
174
174
|
]);
|
|
175
175
|
window.Rectangle = Rectangle;
|
|
@@ -243,7 +243,7 @@ var SketchEngine = class {
|
|
|
243
243
|
import("./UndoRedo-M2JZUBKN.js"),
|
|
244
244
|
import("./Selection-XLRY6VYO.js"),
|
|
245
245
|
import("./ZoomPan-NYPDJBD5.js"),
|
|
246
|
-
import("./CopyPaste-
|
|
246
|
+
import("./CopyPaste-7HWM3IMY.js"),
|
|
247
247
|
import("./EraserTrail-PA6IQLQN.js"),
|
|
248
248
|
import("./ResizeShapes-LKEQTITP.js"),
|
|
249
249
|
import("./ResizeCode-WAMDTKSW.js")
|
|
@@ -262,7 +262,7 @@ var SketchEngine = class {
|
|
|
262
262
|
eventDispatcher.initEventDispatcher(this.svg);
|
|
263
263
|
}
|
|
264
264
|
window.__sketchInteractionReady = true;
|
|
265
|
-
const sceneSerializer = await import("./SceneSerializer-
|
|
265
|
+
const sceneSerializer = await import("./SceneSerializer-7UACFCRF.js");
|
|
266
266
|
if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
|
|
267
267
|
await Promise.all([
|
|
268
268
|
import("./eraserTool-2GS2LQCS.js"),
|
|
@@ -414,4 +414,4 @@ export {
|
|
|
414
414
|
SketchEngine,
|
|
415
415
|
SketchEngine_default as default
|
|
416
416
|
};
|
|
417
|
-
//# sourceMappingURL=SketchEngine-
|
|
417
|
+
//# sourceMappingURL=SketchEngine-UYMJJEVW.js.map
|
|
@@ -999,6 +999,24 @@ var Frame = class {
|
|
|
999
999
|
shape.y = this.y + relTY * this.height;
|
|
1000
1000
|
break;
|
|
1001
1001
|
}
|
|
1002
|
+
case "freehandStroke": {
|
|
1003
|
+
if (Array.isArray(shape.points)) {
|
|
1004
|
+
shape.points = shape.points.map((point) => {
|
|
1005
|
+
if (!Array.isArray(point) || point.length < 2) return point;
|
|
1006
|
+
const relPX = (point[0] - oldX) / oldW;
|
|
1007
|
+
const relPY = (point[1] - oldY) / oldH;
|
|
1008
|
+
return [
|
|
1009
|
+
this.x + relPX * this.width,
|
|
1010
|
+
this.y + relPY * this.height,
|
|
1011
|
+
point[2] || 0.5
|
|
1012
|
+
];
|
|
1013
|
+
});
|
|
1014
|
+
shape._moveOffsetX = 0;
|
|
1015
|
+
shape._moveOffsetY = 0;
|
|
1016
|
+
if (typeof shape.draw === "function") shape.draw();
|
|
1017
|
+
}
|
|
1018
|
+
break;
|
|
1019
|
+
}
|
|
1002
1020
|
}
|
|
1003
1021
|
if (typeof shape.updateAttachedArrows === "function") {
|
|
1004
1022
|
shape.updateAttachedArrows();
|
|
@@ -1210,4 +1228,4 @@ var Frame = class {
|
|
|
1210
1228
|
export {
|
|
1211
1229
|
Frame
|
|
1212
1230
|
};
|
|
1213
|
-
//# sourceMappingURL=chunk-
|
|
1231
|
+
//# sourceMappingURL=chunk-2AYTBFV5.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/shapes/Frame.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable */\n// Frame shape class - extracted from frameHolder.js\n// Depends on globals: svg, shapes, currentShape, currentZoom\n\nimport { cleanupAttachments } from '../tools/arrowTool.js';\n\nfunction getSVGCoordsFromMouse(e) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n const svgX = viewBox.x + (mouseX / rect.width) * viewBox.width;\n const svgY = viewBox.y + (mouseY / rect.height) * viewBox.height;\n return { x: svgX, y: svgY };\n}\n\nlet dragOldPosFrame = null;\n\nclass Frame {\n constructor(x, y, width, height, options = {}) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n this.rotation = options.rotation || 0;\n this.frameName = options.frameName || \"Frame\";\n this.fillStyle = options.fillStyle || \"transparent\"; // 'transparent' | 'solid' | 'grid'\n this.fillColor = options.fillColor || \"#1e1e28\";\n this.gridSize = options.gridSize || 20;\n // Issue #38 follow-up: read the grid stroke from a CSS custom\n // property so the frame grid stays visible in both themes. The\n // var is defined in globals.css for both `body.canvas-mode`\n // (dark-on-light) and `body.canvas-mode.theme-dark` (light-on-dark).\n // The literal here is the dark-theme fallback for environments\n // (tests, embeds) without the canvas-mode CSS in scope.\n this.gridColor = options.gridColor || \"var(--lixsketch-grid-fine, rgba(255,255,255,0.06))\";\n this.options = {\n stroke: options.stroke || \"#555\",\n strokeWidth: options.strokeWidth || 1,\n fill: options.fill || \"transparent\",\n opacity: options.opacity || 1,\n ...options\n };\n\n this.element = null;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.isSelected = false;\n this.anchors = [];\n this.shapeName = \"frame\";\n this.shapeID = `frame-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n this.group.setAttribute('id', this.shapeID);\n\n // Create clipping group for contained shapes\n this.clipGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.clipPath = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath');\n this.clipRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n \n // Set up clipping\n this.clipId = `clip-${this.shapeID}`;\n this.clipPath.setAttribute('id', this.clipId);\n this.clipPath.appendChild(this.clipRect);\n this.clipGroup.setAttribute('clip-path', `url(#${this.clipId})`);\n \n // Add clip path to defs\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n defs.appendChild(this.clipPath);\n\n // Array to hold shapes inside this frame\n this.containedShapes = [];\n\n svg.appendChild(this.group);\n svg.appendChild(this.clipGroup);\n this.draw();\n this.updateClipPath();\n }\n\n draw() {\n // Clear previous elements\n while (this.group.firstChild) {\n this.group.removeChild(this.group.firstChild);\n }\n this.anchors = [];\n\n // Ensure defs exists for grid pattern\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n\n // Determine fill based on fillStyle\n let fillValue = \"transparent\";\n if (this.fillStyle === 'solid') {\n fillValue = this.fillColor;\n } else if (this.fillStyle === 'grid') {\n // Create or update a grid pattern unique to this frame\n const patternId = `frame-grid-${this.shapeID}`;\n let pattern = defs.querySelector(`#${patternId}`);\n if (!pattern) {\n pattern = document.createElementNS('http://www.w3.org/2000/svg', 'pattern');\n pattern.setAttribute('id', patternId);\n pattern.setAttribute('patternUnits', 'userSpaceOnUse');\n defs.appendChild(pattern);\n }\n // Update pattern attributes\n pattern.setAttribute('x', this.x);\n pattern.setAttribute('y', this.y);\n pattern.setAttribute('width', this.gridSize);\n pattern.setAttribute('height', this.gridSize);\n // Clear and rebuild pattern content\n while (pattern.firstChild) pattern.removeChild(pattern.firstChild);\n // Background fill\n const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n bgRect.setAttribute('width', this.gridSize);\n bgRect.setAttribute('height', this.gridSize);\n bgRect.setAttribute('fill', this.fillColor);\n pattern.appendChild(bgRect);\n // Grid lines\n const gridPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n gridPath.setAttribute('d', `M ${this.gridSize} 0 L 0 0 0 ${this.gridSize}`);\n gridPath.setAttribute('fill', 'none');\n gridPath.setAttribute('stroke', this.gridColor);\n gridPath.setAttribute('stroke-width', '0.5');\n pattern.appendChild(gridPath);\n fillValue = `url(#${patternId})`;\n }\n\n // Create the frame rectangle\n const frameRect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n frameRect.setAttribute(\"x\", this.x);\n frameRect.setAttribute(\"y\", this.y);\n frameRect.setAttribute(\"width\", this.width);\n frameRect.setAttribute(\"height\", this.height);\n frameRect.setAttribute(\"stroke\", this.options.stroke);\n frameRect.setAttribute(\"stroke-width\", this.options.strokeWidth);\n frameRect.setAttribute(\"fill\", fillValue);\n frameRect.setAttribute(\"opacity\", this.options.opacity);\n frameRect.setAttribute(\"stroke-dasharray\", \"5,5\");\n frameRect.classList.add(\"frame-rect\");\n\n // Apply rotation\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n frameRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.element = frameRect;\n this.group.appendChild(this.element);\n\n // Add label\n this.addFrameLabel();\n\n // Re-attach frame image if present\n if (this._frameImageURL) {\n this.setImageFromURL(this._frameImageURL, this._frameImageFit || 'cover');\n }\n\n // Add selection anchors if selected\n if (this.isSelected) {\n this.addAnchors();\n }\n\n // Update clip path\n this.updateClipPath();\n }\n\n updateAttachedArrows() {\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(shape => {\n if (shape.shapeName === 'arrow') {\n let needsUpdate = false;\n \n // Check if arrow is attached to this frame\n if (shape.attachedToStart && shape.attachedToStart.shape === this) {\n needsUpdate = true;\n }\n if (shape.attachedToEnd && shape.attachedToEnd.shape === this) {\n needsUpdate = true;\n }\n \n if (needsUpdate) {\n shape.updateAttachments();\n }\n }\n });\n }\n }\n\n updateClipPath() {\n // Update the clipping rectangle to match frame dimensions\n this.clipRect.setAttribute(\"x\", this.x);\n this.clipRect.setAttribute(\"y\", this.y);\n this.clipRect.setAttribute(\"width\", this.width);\n this.clipRect.setAttribute(\"height\", this.height);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this.clipRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this.clipRect.removeAttribute(\"transform\");\n }\n }\n\n addShapeToFrame(shape) {\n if (shape && !this.containedShapes.includes(shape)) {\n const oldFrame = shape.parentFrame;\n\n // Remove from other frames first\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(otherFrame => {\n if (otherFrame.shapeName === 'frame' && otherFrame !== this) {\n otherFrame.removeShapeFromFrame(shape);\n }\n });\n }\n\n this.containedShapes.push(shape);\n shape.parentFrame = this;\n\n // Only move to clipped group if not currently being dragged\n const el = shape.group || shape.element;\n if (el && el.parentNode && !shape.isDraggedOutTemporarily) {\n el.parentNode.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup into our clipGroup\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n this.clipGroup.appendChild(shape.clipGroup);\n }\n }\n}\n\n removeShapeFromFrame(shape) {\n const index = this.containedShapes.indexOf(shape);\n if (index > -1) {\n this.containedShapes.splice(index, 1);\n if (shape.parentFrame === this) {\n shape.parentFrame = null;\n }\n\n // Move shape's group/element back to main SVG if it's in the clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup back to main SVG\n if (shape.shapeName === 'frame' && shape.clipGroup && shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n svg.appendChild(shape.clipGroup);\n }\n\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n // Check if a point is inside the frame bounds\n isPointInFrame(x, y) {\n // Simple bounding box check (can be enhanced for rotation)\n return x >= this.x && x <= this.x + this.width &&\n y >= this.y && y <= this.y + this.height;\n }\n\n // Check if a shape overlaps with this frame\n isShapeInFrame(shape) {\n if (!shape || shape === this) return false;\n \n const shapeX = shape.x || 0;\n const shapeY = shape.y || 0;\n const shapeWidth = shape.width || 0;\n const shapeHeight = shape.height || 0;\n \n // Check if the center of the shape is inside the frame (for better UX)\n const shapeCenterX = shapeX + shapeWidth / 2;\n const shapeCenterY = shapeY + shapeHeight / 2;\n \n return shapeCenterX >= this.x && shapeCenterX <= this.x + this.width &&\n shapeCenterY >= this.y && shapeCenterY <= this.y + this.height;\n}\n\nupdateContainedShapes(applyClipping = true) {\n // Check all shapes to see if they should be in this frame\n if (typeof shapes === 'undefined' || !Array.isArray(shapes)) return;\n shapes.forEach(shape => {\n if (shape !== this) {\n // Skip frames that are larger than or equal to this frame (prevent parent containing child loops)\n if (shape.shapeName === 'frame') {\n const shapeArea = (shape.width || 0) * (shape.height || 0);\n const thisArea = (this.width || 0) * (this.height || 0);\n if (shapeArea >= thisArea) return;\n }\n const isInFrame = this.isShapeInFrame(shape);\n const isAlreadyContained = this.containedShapes.includes(shape);\n\n if (isInFrame && !isAlreadyContained) {\n this.addShapeToFrame(shape);\n // Don't apply clipping if we're not supposed to\n if (!applyClipping) {\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n shape.isDraggedOutTemporarily = true;\n }\n }\n } else if (!isInFrame && isAlreadyContained) {\n this.removeShapeFromFrame(shape);\n }\n }\n });\n \n // Update clip path\n this.updateClipPath();\n}\n\nhighlightFrame() {\n if (this.element) {\n this.element.setAttribute('stroke', '#5B57D1');\n this.element.setAttribute('stroke-width', '3');\n this.element.setAttribute('opacity', '0.7');\n }\n}\n\n// Remove frame highlight\nremoveHighlight() {\n if (this.element) {\n this.element.setAttribute('stroke', this.options.stroke);\n this.element.setAttribute('stroke-width', this.options.strokeWidth);\n this.element.setAttribute('opacity', this.options.opacity);\n }\n}\n \n\nmove(dx, dy) {\n this.x += dx;\n this.y += dy;\n\n // Move all contained shapes with the frame\n this.containedShapes.forEach(shape => {\n if (shape) {\n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n\n // Use shape's own move method for proper handling of all shape types\n if (typeof shape.move === 'function') {\n shape.move(dx, dy);\n } else {\n shape.x += dx;\n shape.y += dy;\n }\n\n // Force redraw for shapes whose move() doesn't auto-redraw\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n\n // Update bounding box for freehand strokes\n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n\n // Remove the flag after movement\n delete shape.isBeingMovedByFrame;\n }\n });\n\n // Update arrows attached to this frame\n this.updateAttachedArrows();\n\n this.draw();\n this.updateClipPath();\n}\n\n handleResizeLegacy(anchorIndex, currentPos, startPos, initialFrame) {\n // Legacy version - superseded by the handleResize below with contained shapes scaling\n const dx = currentPos.x - startPos.x;\n const dy = currentPos.y - startPos.y;\n\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + dx; this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 1: this.y = initialFrame.y + dy; this.height = Math.max(10, initialFrame.height - dy); break;\n case 2: this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 3: this.width = Math.max(10, initialFrame.width + dx); break;\n case 4: this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 5: this.height = Math.max(10, initialFrame.height + dy); break;\n case 6: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 7: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); break;\n }\n this.updateAttachedArrows();\n this.updateContainedShapes();\n}\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n addFrameLabel() {\n const labelText = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n labelText.setAttribute(\"x\", this.x + 5);\n labelText.setAttribute(\"y\", this.y - 10);\n labelText.setAttribute(\"font-size\", `${16 / currentZoom}px`);\n labelText.setAttribute(\"fill\", this.options.stroke);\n labelText.setAttribute(\"font-family\", \"lixFont\");\n labelText.textContent = this.frameName || \"Frame\";\n labelText.style.cursor = \"pointer\";\n labelText.style.userSelect = \"none\";\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n labelText.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Add double-click event for renaming\n labelText.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n this.startLabelEdit(labelText);\n });\n \n this.group.appendChild(labelText);\n this.labelElement = labelText;\n}\n\nstartLabelEdit(labelElement) {\n // Create a foreignObject to hold an HTML input\n const foreignObject = document.createElementNS(\"http://www.w3.org/2000/svg\", \"foreignObject\");\n foreignObject.setAttribute(\"x\", this.x + 5);\n foreignObject.setAttribute(\"y\", this.y - 20);\n foreignObject.setAttribute(\"width\", Math.max(100, this.width - 10));\n foreignObject.setAttribute(\"height\", 20);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n foreignObject.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Create input element\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = this.frameName || \"Frame\";\n const oldName = this.frameName; // Store old name for undo\n \n input.style.cssText = `\n position: absolute;\n width: 100%;\n height: 20px;\n border: 1px solid #5B57D1;\n background: transparent;\n color: ${this.options.stroke};\n font-family: \"lixFont\";\n font-size: ${15 / currentZoom}px;\n padding: 2px 10px;\n margin: 0;\n outline: none;\n border-radius: 2px;\n box-sizing: border-box;\n `;\n \n foreignObject.appendChild(input);\n this.group.appendChild(foreignObject);\n \n // Hide the original label\n labelElement.style.display = \"none\";\n \n // Focus and select the text\n setTimeout(() => {\n input.focus();\n input.select();\n }, 10);\n \n const finishEdit = () => {\n const newName = input.value.trim() || \"Frame\";\n \n // Track name change in undo system if it actually changed\n if (newName !== oldName) {\n pushTransformAction(this, \n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: oldName \n },\n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: newName \n }\n );\n }\n \n this.frameName = newName;\n \n // Remove the input\n this.group.removeChild(foreignObject);\n \n // Show and update the label\n labelElement.style.display = \"block\";\n labelElement.textContent = this.frameName;\n \n this.labelElement = labelElement;\n };\n \n // Handle input events\n input.addEventListener('blur', finishEdit);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n finishEdit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n // Cancel edit - restore original name\n this.group.removeChild(foreignObject);\n labelElement.style.display = \"block\";\n }\n });\n \n // Prevent the input from interfering with other interactions\n input.addEventListener('pointerdown', (e) => e.stopPropagation());\n input.addEventListener('pointermove', (e) => e.stopPropagation());\n input.addEventListener('pointerup', (e) => e.stopPropagation());\n}\n selectFrame() {\n this.isSelected = true;\n this.draw();\n this._showSidebar();\n }\n\n _showSidebar() {\n // React sidebar bridge\n if (window.__showSidebarForShape) {\n window.__showSidebarForShape('frame');\n }\n\n const sidebar = document.getElementById('frameSideBar');\n const renameInput = document.getElementById('frameRenameInput');\n const resizeBtn = document.getElementById('frameResizeToFit');\n if (!sidebar) return;\n\n sidebar.classList.remove('hidden');\n\n if (renameInput) {\n renameInput.value = this.frameName || 'Frame';\n // Replace old listener by cloning\n const newInput = renameInput.cloneNode(true);\n renameInput.parentNode.replaceChild(newInput, renameInput);\n newInput.addEventListener('input', () => {\n const val = newInput.value.trim() || 'Frame';\n this.frameName = val;\n if (this.labelElement) this.labelElement.textContent = val;\n });\n newInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') newInput.blur();\n });\n newInput.addEventListener('pointerdown', (e) => e.stopPropagation());\n }\n\n if (resizeBtn) {\n const newBtn = resizeBtn.cloneNode(true);\n resizeBtn.parentNode.replaceChild(newBtn, resizeBtn);\n newBtn.addEventListener('click', () => this.resizeToFit());\n }\n }\n\n resizeToFit() {\n if (this.containedShapes.length === 0) return;\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n this.containedShapes.forEach(shape => {\n if (shape.shapeName === 'arrow' || shape.shapeName === 'line') {\n [shape.startPoint, shape.endPoint].filter(Boolean).forEach(p => {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n });\n } else if (typeof shape.x === 'number' && typeof shape.y === 'number') {\n const w = shape.width || 0;\n const h = shape.height || 0;\n minX = Math.min(minX, shape.x);\n minY = Math.min(minY, shape.y);\n maxX = Math.max(maxX, shape.x + w);\n maxY = Math.max(maxY, shape.y + h);\n }\n });\n\n if (!isFinite(minX)) return;\n\n const padding = 20;\n const oldState = { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation };\n\n this.x = minX - padding;\n this.y = minY - padding;\n this.width = (maxX - minX) + padding * 2;\n this.height = (maxY - minY) + padding * 2;\n\n pushTransformAction(this, oldState, { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation });\n this.draw();\n this.updateClipPath();\n this.updateContainedShapes();\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode) {\n anchor.parentNode.removeChild(anchor);\n }\n });\n this.anchors = [];\n this.isSelected = false;\n this.draw();\n const sidebar = document.getElementById('frameSideBar');\n if (sidebar) sidebar.classList.add('hidden');\n }\n\n addAnchors() {\n const anchorSize = 8 / currentZoom;\n const anchorStrokeWidth = 2 / currentZoom;\n\n // Calculate anchor positions (corners + midpoints + rotation handle)\n const anchorPositions = [\n { x: this.x, y: this.y, cursor: 'nw-resize', type: 'corner' }, // Top-left\n { x: this.x + this.width / 2, y: this.y, cursor: 'n-resize', type: 'edge' }, // Top-middle\n { x: this.x + this.width, y: this.y, cursor: 'ne-resize', type: 'corner' }, // Top-right\n { x: this.x + this.width, y: this.y + this.height / 2, cursor: 'e-resize', type: 'edge' }, // Right-middle\n { x: this.x + this.width, y: this.y + this.height, cursor: 'se-resize', type: 'corner' }, // Bottom-right\n { x: this.x + this.width / 2, y: this.y + this.height, cursor: 's-resize', type: 'edge' }, // Bottom-middle\n { x: this.x, y: this.y + this.height, cursor: 'sw-resize', type: 'corner' }, // Bottom-left\n { x: this.x, y: this.y + this.height / 2, cursor: 'w-resize', type: 'edge' }, // Left-middle\n ];\n\n // Add rotation handle\n const rotationHandleDistance = 30 / currentZoom;\n const rotationHandle = {\n x: this.x + this.width / 2,\n y: this.y - rotationHandleDistance,\n cursor: 'grab',\n type: 'rotation'\n };\n anchorPositions.push(rotationHandle);\n\n // Create selection outline first (behind anchors)\n const outline = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n outline.setAttribute('x', this.x);\n outline.setAttribute('y', this.y);\n outline.setAttribute('width', this.width);\n outline.setAttribute('height', this.height);\n outline.setAttribute('fill', 'none');\n outline.setAttribute('stroke', '#5B57D1');\n outline.setAttribute('stroke-width', 1.5);\n outline.setAttribute('vector-effect', 'non-scaling-stroke');\n outline.setAttribute('stroke-dasharray', '4 2');\n outline.setAttribute('style', 'pointer-events: none;');\n\n // Apply rotation to outline if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n outline.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.group.appendChild(outline);\n this.selectionOutline = outline;\n\n anchorPositions.forEach((position, index) => {\n let anchor;\n \n if (position.type === 'rotation') {\n // Create rotation handle (circle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n anchor.setAttribute(\"cx\", position.x);\n anchor.setAttribute(\"cy\", position.y);\n anchor.setAttribute(\"r\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Add rotation line\n const rotationLine = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n rotationLine.setAttribute(\"x1\", this.x + this.width / 2);\n rotationLine.setAttribute(\"y1\", this.y);\n rotationLine.setAttribute(\"x2\", position.x);\n rotationLine.setAttribute(\"y2\", position.y);\n rotationLine.setAttribute(\"stroke\", \"#5B57D1\"); \n rotationLine.setAttribute(\"stroke-width\", anchorStrokeWidth);\n rotationLine.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Apply rotation to rotation line if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n rotationLine.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n this.group.appendChild(rotationLine);\n } else {\n // Create resize handle (rectangle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n anchor.setAttribute(\"x\", position.x - anchorSize / 2);\n anchor.setAttribute(\"y\", position.y - anchorSize / 2);\n anchor.setAttribute(\"width\", anchorSize);\n anchor.setAttribute(\"height\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n }\n\n // Apply rotation to anchor if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n anchor.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n anchor.style.cursor = position.cursor;\n anchor.addEventListener('pointerdown', (e) => this.startAnchorDrag(e, index));\n \n this.anchors.push(anchor);\n this.group.appendChild(anchor);\n });\n }\n\n startAnchorDrag(e, index) {\n e.stopPropagation();\n e.preventDefault();\n\n // Store initial state for undo\n dragOldPosFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const startMousePos = getSVGCoordsFromMouse(e);\n const initialFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const onPointerMove = (event) => {\n const currentMousePos = getSVGCoordsFromMouse(event);\n \n if (index === 8) { // Rotation handle\n this.handleRotation(currentMousePos, initialFrame);\n } else {\n this.handleResize(index, currentMousePos, startMousePos, initialFrame);\n }\n \n this.draw();\n this.updateContainedShapes();\n };\n\n const onPointerUp = () => {\n if (dragOldPosFrame) {\n const newPos = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n pushTransformAction(this, dragOldPosFrame, newPos);\n dragOldPosFrame = null;\n }\n \n svg.removeEventListener('pointermove', onPointerMove);\n svg.removeEventListener('pointerup', onPointerUp);\n svg.style.cursor = 'default';\n };\n\n svg.addEventListener('pointermove', onPointerMove);\n svg.addEventListener('pointerup', onPointerUp);\n }\n\n handleRotation(mousePos, initialFrame) {\n const centerX = initialFrame.x + initialFrame.width / 2;\n const centerY = initialFrame.y + initialFrame.height / 2;\n \n const angle = Math.atan2(mousePos.y - centerY, mousePos.x - centerX);\n const newRotation = (angle * 180 / Math.PI + 90) % 360;\n const angleDiff = newRotation - this.rotation;\n const angleRad = angleDiff * Math.PI / 180;\n const cosAngle = Math.cos(angleRad);\n const sinAngle = Math.sin(angleRad);\n \n // Store the rotation center for contained shapes\n const rotationCenter = { x: centerX, y: centerY };\n \n // Rotate all contained shapes around the frame's center\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n \n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n \n switch (shape.shapeName) {\n case 'rectangle':\n case 'frame':\n case 'image':\n case 'icon':\n // Get shape's current center\n const shapeCenterX = shape.x + shape.width / 2;\n const shapeCenterY = shape.y + shape.height / 2;\n \n // Calculate relative position from rotation center\n const relativeX = shapeCenterX - rotationCenter.x;\n const relativeY = shapeCenterY - rotationCenter.y;\n \n // Apply rotation to get new center position\n const newCenterX = rotationCenter.x + (relativeX * cosAngle - relativeY * sinAngle);\n const newCenterY = rotationCenter.y + (relativeX * sinAngle + relativeY * cosAngle);\n \n // Update shape position\n shape.x = newCenterX - shape.width / 2;\n shape.y = newCenterY - shape.height / 2;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'circle':\n // Get circle's center\n const circleCenterX = shape.x;\n const circleCenterY = shape.y;\n \n // Calculate relative position from rotation center\n const relativeCircleX = circleCenterX - rotationCenter.x;\n const relativeCircleY = circleCenterY - rotationCenter.y;\n \n // Apply rotation\n const newCircleCenterX = rotationCenter.x + (relativeCircleX * cosAngle - relativeCircleY * sinAngle);\n const newCircleCenterY = rotationCenter.y + (relativeCircleX * sinAngle + relativeCircleY * cosAngle);\n \n shape.x = newCircleCenterX;\n shape.y = newCircleCenterY;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'line':\n case 'arrow':\n // Calculate relative positions for start and end points\n const relativeStartX = shape.startPoint.x - rotationCenter.x;\n const relativeStartY = shape.startPoint.y - rotationCenter.y;\n const relativeEndX = shape.endPoint.x - rotationCenter.x;\n const relativeEndY = shape.endPoint.y - rotationCenter.y;\n \n // Apply rotation to both points\n const newStartX = rotationCenter.x + (relativeStartX * cosAngle - relativeStartY * sinAngle);\n const newStartY = rotationCenter.y + (relativeStartX * sinAngle + relativeStartY * cosAngle);\n const newEndX = rotationCenter.x + (relativeEndX * cosAngle - relativeEndY * sinAngle);\n const newEndY = rotationCenter.y + (relativeEndX * sinAngle + relativeEndY * cosAngle);\n \n shape.startPoint.x = newStartX;\n shape.startPoint.y = newStartY;\n shape.endPoint.x = newEndX;\n shape.endPoint.y = newEndY;\n \n if (shape.shapeName === 'arrow' && shape.arrowCurved && typeof shape.initializeCurveControlPoints === 'function') {\n shape.initializeCurveControlPoints();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'text':\n case 'code':\n // Get text/code bounds for center calculation\n const textOrCodeEl = shape.group ? (shape.group.querySelector('text') || shape.group.querySelector('foreignObject')) : null;\n if (textOrCodeEl) {\n const bbox = textOrCodeEl.getBBox();\n const transform = shape.group.transform.baseVal.consolidate();\n const matrix = transform ? transform.matrix : { e: 0, f: 0 };\n\n const textCenterX = bbox.x + matrix.e + bbox.width / 2;\n const textCenterY = bbox.y + matrix.f + bbox.height / 2;\n\n // Calculate relative position\n const relativeTextX = textCenterX - rotationCenter.x;\n const relativeTextY = textCenterY - rotationCenter.y;\n\n // Apply rotation\n const newTextCenterX = rotationCenter.x + (relativeTextX * cosAngle - relativeTextY * sinAngle);\n const newTextCenterY = rotationCenter.y + (relativeTextX * sinAngle + relativeTextY * cosAngle);\n\n // Update position\n const newTransformX = newTextCenterX - bbox.width / 2;\n const newTransformY = newTextCenterY - bbox.height / 2;\n const newShapeRotation = (shape.rotation || 0) + angleDiff;\n\n const textCenterRelativeX = bbox.width / 2;\n const textCenterRelativeY = bbox.height / 2;\n\n shape.group.setAttribute('transform',\n `translate(${newTransformX}, ${newTransformY}) rotate(${newShapeRotation}, ${textCenterRelativeX}, ${textCenterRelativeY})`\n );\n\n shape.x = newTransformX;\n shape.y = newTransformY;\n shape.rotation = newShapeRotation;\n }\n break;\n \n case 'freehandStroke':\n if (shape.points && Array.isArray(shape.points)) {\n // Rotate each point in the stroke\n shape.points = shape.points.map(point => {\n if (!Array.isArray(point) || point.length < 2) return point;\n \n const relativePointX = point[0] - rotationCenter.x;\n const relativePointY = point[1] - rotationCenter.y;\n \n const newPointX = rotationCenter.x + (relativePointX * cosAngle - relativePointY * sinAngle);\n const newPointY = rotationCenter.y + (relativePointX * sinAngle + relativePointY * cosAngle);\n \n return [newPointX, newPointY, point[2] || 0.5];\n });\n \n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n }\n break;\n }\n \n // Update arrows attached to the contained shape\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n \n // Remove the flag after rotation\n delete shape.isBeingMovedByFrame;\n });\n \n // Update the frame's rotation\n this.rotation = newRotation;\n \n // Update arrows attached to this frame\n this.updateAttachedArrows();\n }\n\n handleResize(anchorIndex, currentPos, startPos, initialFrame) {\n const rawDx = currentPos.x - startPos.x;\n const rawDy = currentPos.y - startPos.y;\n\n // Rotate delta to local (unrotated) space when frame is rotated\n const rad = (this.rotation || 0) * Math.PI / 180;\n const cosR = Math.cos(rad);\n const sinR = Math.sin(rad);\n const dx = rawDx * cosR + rawDy * sinR;\n const dy = -rawDx * sinR + rawDy * cosR;\n\n // Store old frame for scale calculation\n const oldX = this.x, oldY = this.y, oldW = this.width, oldH = this.height;\n\n // Compute new dimensions using local-space deltas\n let newW, newH;\n // Fixed corner relative to initial frame origin: (fixRelX, fixRelY)\n let fixRelX, fixRelY;\n\n switch (anchorIndex) {\n case 0: // Top-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = initialFrame.width; fixRelY = initialFrame.height;\n break;\n case 1: // Top-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 2: // Top-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 3: // Right-middle\n newW = Math.max(10, initialFrame.width + dx);\n newH = initialFrame.height;\n fixRelX = 0; fixRelY = 0;\n break;\n case 4: // Bottom-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 5: // Bottom-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 6: // Bottom-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n case 7: // Left-middle\n newW = Math.max(10, initialFrame.width - dx);\n newH = initialFrame.height;\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n }\n\n // Compute new position using fixed-corner constraint\n if (this.rotation && this.rotation !== 0) {\n // Compute rotated world position of the fixed corner in the initial frame\n const iCX = initialFrame.x + initialFrame.width / 2;\n const iCY = initialFrame.y + initialFrame.height / 2;\n const odx = (initialFrame.x + fixRelX) - iCX;\n const ody = (initialFrame.y + fixRelY) - iCY;\n const fixedWorldX = iCX + odx * cosR - ody * sinR;\n const fixedWorldY = iCY + odx * sinR + ody * cosR;\n\n // Where the fixed corner sits in new rect (relative to new origin)\n const fixNewRelX = (fixRelX === 0) ? 0 : newW;\n const fixNewRelY = (fixRelY === 0) ? 0 : newH;\n\n // Solve for new origin\n const ncx = newW / 2;\n const ncy = newH / 2;\n const ndx = fixNewRelX - ncx;\n const ndy = fixNewRelY - ncy;\n const rotX = ncx + ndx * cosR - ndy * sinR;\n const rotY = ncy + ndx * sinR + ndy * cosR;\n\n this.x = fixedWorldX - rotX;\n this.y = fixedWorldY - rotY;\n } else {\n // No rotation - use simple axis-aligned position calculation\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + (initialFrame.width - newW); this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 1: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 2: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 3: break;\n case 4: break;\n case 5: break;\n case 6: this.x = initialFrame.x + (initialFrame.width - newW); break;\n case 7: this.x = initialFrame.x + (initialFrame.width - newW); break;\n }\n }\n\n this.width = newW;\n this.height = newH;\n\n // Scale contained shapes proportionally so nothing falls out\n if (oldW > 0 && oldH > 0) {\n const scaleX = this.width / oldW;\n const scaleY = this.height / oldH;\n\n if (Math.abs(scaleX - 1) > 0.001 || Math.abs(scaleY - 1) > 0.001) {\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n shape.isBeingMovedByFrame = true;\n\n switch (shape.shapeName) {\n case 'rectangle':\n case 'image':\n case 'icon':\n case 'code': {\n const relX = (shape.x - oldX) / oldW;\n const relY = (shape.y - oldY) / oldH;\n const relW = shape.width / oldW;\n const relH = shape.height / oldH;\n shape.x = this.x + relX * this.width;\n shape.y = this.y + relY * this.height;\n shape.width = relW * this.width;\n shape.height = relH * this.height;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'circle': {\n const relCX = (shape.x - oldX) / oldW;\n const relCY = (shape.y - oldY) / oldH;\n shape.x = this.x + relCX * this.width;\n shape.y = this.y + relCY * this.height;\n shape.rx = (shape.rx / oldW) * this.width;\n shape.ry = (shape.ry / oldH) * this.height;\n shape.width = shape.rx * 2;\n shape.height = shape.ry * 2;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'arrow':\n case 'line': {\n const relSX = (shape.startPoint.x - oldX) / oldW;\n const relSY = (shape.startPoint.y - oldY) / oldH;\n const relEX = (shape.endPoint.x - oldX) / oldW;\n const relEY = (shape.endPoint.y - oldY) / oldH;\n shape.startPoint.x = this.x + relSX * this.width;\n shape.startPoint.y = this.y + relSY * this.height;\n shape.endPoint.x = this.x + relEX * this.width;\n shape.endPoint.y = this.y + relEY * this.height;\n if (shape.controlPoint1) {\n const relC1X = (shape.controlPoint1.x - oldX) / oldW;\n const relC1Y = (shape.controlPoint1.y - oldY) / oldH;\n shape.controlPoint1.x = this.x + relC1X * this.width;\n shape.controlPoint1.y = this.y + relC1Y * this.height;\n }\n if (shape.controlPoint2) {\n const relC2X = (shape.controlPoint2.x - oldX) / oldW;\n const relC2Y = (shape.controlPoint2.y - oldY) / oldH;\n shape.controlPoint2.x = this.x + relC2X * this.width;\n shape.controlPoint2.y = this.y + relC2Y * this.height;\n }\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'text': {\n const tx = shape.x || 0;\n const ty = shape.y || 0;\n const relTX = (tx - oldX) / oldW;\n const relTY = (ty - oldY) / oldH;\n shape.x = this.x + relTX * this.width;\n shape.y = this.y + relTY * this.height;\n break;\n }\n }\n\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n delete shape.isBeingMovedByFrame;\n });\n }\n }\n\n // Update contained shapes visibility\n this.updateContainedShapes();\n }\n \n temporarilyRemoveFromFrame(shape) {\n if (shape && shape.parentFrame === this) {\n // Move shape back to main SVG temporarily (without removing from containedShapes array)\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n shape.isDraggedOutTemporarily = true;\n }\n}\n\n// Add a method to restore clipping for a shape after drag\nrestoreToFrame(shape) {\n if (shape && shape.parentFrame === this && shape.isDraggedOutTemporarily) {\n // Move shape back to clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === svg) {\n svg.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n\n contains(viewBoxX, viewBoxY) {\n // Simple point-in-rectangle test (without rotation for now)\n return viewBoxX >= this.x && viewBoxX <= this.x + this.width &&\n viewBoxY >= this.y && viewBoxY <= this.y + this.height;\n }\n\n // Arrow attachment support (similar to other shapes)\n getAttachmentPoint(point, tolerance = 20) {\n const rect = {\n left: this.x,\n right: this.x + this.width,\n top: this.y,\n bottom: this.y + this.height\n };\n\n const distances = {\n top: Math.abs(point.y - rect.top),\n bottom: Math.abs(point.y - rect.bottom),\n left: Math.abs(point.x - rect.left),\n right: Math.abs(point.x - rect.right)\n };\n\n let closestSide = null;\n let minDistance = tolerance;\n\n for (let side in distances) {\n if (distances[side] < minDistance &&\n ((side === 'top' || side === 'bottom') && point.x >= rect.left && point.x <= rect.right) ||\n ((side === 'left' || side === 'right') && point.y >= rect.top && point.y <= rect.bottom)) {\n minDistance = distances[side];\n closestSide = side;\n }\n }\n\n if (closestSide) {\n let attachPoint;\n const offset = { x: 0, y: 0 };\n\n switch (closestSide) {\n case 'top':\n attachPoint = { x: point.x, y: rect.top };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'bottom':\n attachPoint = { x: point.x, y: rect.bottom };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'left':\n attachPoint = { x: rect.left, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n case 'right':\n attachPoint = { x: rect.right, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n }\n\n return { point: attachPoint, side: closestSide, offset, shape: this };\n }\n\n return null;\n }\n\n updateStyle(newOptions) {\n Object.keys(newOptions).forEach(key => newOptions[key] === undefined && delete newOptions[key]);\n this.options = { ...this.options, ...newOptions };\n this.draw();\n }\n\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n /**\n * Set a background image for this frame from a URL.\n * The image will fit/cover the frame dimensions.\n * @param {string} url - Image URL\n * @param {string} fit - 'cover' (default) | 'contain' | 'fill'\n */\n setImageFromURL(url, fit = 'cover') {\n if (!url) {\n // Remove existing frame image\n if (this._frameImage && this._frameImage.parentNode) {\n this._frameImage.parentNode.removeChild(this._frameImage);\n this._frameImage = null;\n }\n this._frameImageURL = null;\n return;\n }\n\n this._frameImageURL = url;\n this._frameImageFit = fit;\n\n if (!this._frameImage) {\n this._frameImage = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n this._frameImage.setAttribute('pointer-events', 'none');\n }\n // Always update preserveAspectRatio when fit changes\n this._frameImage.setAttribute('preserveAspectRatio',\n fit === 'cover' ? 'xMidYMid slice' :\n fit === 'contain' ? 'xMidYMid meet' :\n fit === 'center' ? 'xMidYMid meet' : 'none'\n );\n\n this._frameImage.setAttribute('href', url);\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n // Insert image right after the frame rect (below contained shapes)\n if (this._frameImage.parentNode === this.group) {\n this.group.removeChild(this._frameImage);\n }\n if (this.element && this.element.nextSibling) {\n this.group.insertBefore(this._frameImage, this.element.nextSibling);\n } else {\n this.group.appendChild(this._frameImage);\n }\n }\n\n /**\n * Update frame image position/size (called during move/resize)\n */\n _updateFrameImage() {\n if (!this._frameImage) return;\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this._frameImage.removeAttribute('transform');\n }\n }\n}\n\nexport { Frame };\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/* eslint-disable */\n// Frame shape class - extracted from frameHolder.js\n// Depends on globals: svg, shapes, currentShape, currentZoom\n\nimport { cleanupAttachments } from '../tools/arrowTool.js';\n\nfunction getSVGCoordsFromMouse(e) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n const svgX = viewBox.x + (mouseX / rect.width) * viewBox.width;\n const svgY = viewBox.y + (mouseY / rect.height) * viewBox.height;\n return { x: svgX, y: svgY };\n}\n\nlet dragOldPosFrame = null;\n\nclass Frame {\n constructor(x, y, width, height, options = {}) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n this.rotation = options.rotation || 0;\n this.frameName = options.frameName || \"Frame\";\n this.fillStyle = options.fillStyle || \"transparent\"; // 'transparent' | 'solid' | 'grid'\n this.fillColor = options.fillColor || \"#1e1e28\";\n this.gridSize = options.gridSize || 20;\n // Issue #38 follow-up: read the grid stroke from a CSS custom\n // property so the frame grid stays visible in both themes. The\n // var is defined in globals.css for both `body.canvas-mode`\n // (dark-on-light) and `body.canvas-mode.theme-dark` (light-on-dark).\n // The literal here is the dark-theme fallback for environments\n // (tests, embeds) without the canvas-mode CSS in scope.\n this.gridColor = options.gridColor || \"var(--lixsketch-grid-fine, rgba(255,255,255,0.06))\";\n this.options = {\n stroke: options.stroke || \"#555\",\n strokeWidth: options.strokeWidth || 1,\n fill: options.fill || \"transparent\",\n opacity: options.opacity || 1,\n ...options\n };\n\n this.element = null;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.isSelected = false;\n this.anchors = [];\n this.shapeName = \"frame\";\n this.shapeID = `frame-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n this.group.setAttribute('id', this.shapeID);\n\n // Create clipping group for contained shapes\n this.clipGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.clipPath = document.createElementNS('http://www.w3.org/2000/svg', 'clipPath');\n this.clipRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n \n // Set up clipping\n this.clipId = `clip-${this.shapeID}`;\n this.clipPath.setAttribute('id', this.clipId);\n this.clipPath.appendChild(this.clipRect);\n this.clipGroup.setAttribute('clip-path', `url(#${this.clipId})`);\n \n // Add clip path to defs\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n defs.appendChild(this.clipPath);\n\n // Array to hold shapes inside this frame\n this.containedShapes = [];\n\n svg.appendChild(this.group);\n svg.appendChild(this.clipGroup);\n this.draw();\n this.updateClipPath();\n }\n\n draw() {\n // Clear previous elements\n while (this.group.firstChild) {\n this.group.removeChild(this.group.firstChild);\n }\n this.anchors = [];\n\n // Ensure defs exists for grid pattern\n let defs = svg.querySelector('defs');\n if (!defs) {\n defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');\n svg.appendChild(defs);\n }\n\n // Determine fill based on fillStyle\n let fillValue = \"transparent\";\n if (this.fillStyle === 'solid') {\n fillValue = this.fillColor;\n } else if (this.fillStyle === 'grid') {\n // Create or update a grid pattern unique to this frame\n const patternId = `frame-grid-${this.shapeID}`;\n let pattern = defs.querySelector(`#${patternId}`);\n if (!pattern) {\n pattern = document.createElementNS('http://www.w3.org/2000/svg', 'pattern');\n pattern.setAttribute('id', patternId);\n pattern.setAttribute('patternUnits', 'userSpaceOnUse');\n defs.appendChild(pattern);\n }\n // Update pattern attributes\n pattern.setAttribute('x', this.x);\n pattern.setAttribute('y', this.y);\n pattern.setAttribute('width', this.gridSize);\n pattern.setAttribute('height', this.gridSize);\n // Clear and rebuild pattern content\n while (pattern.firstChild) pattern.removeChild(pattern.firstChild);\n // Background fill\n const bgRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n bgRect.setAttribute('width', this.gridSize);\n bgRect.setAttribute('height', this.gridSize);\n bgRect.setAttribute('fill', this.fillColor);\n pattern.appendChild(bgRect);\n // Grid lines\n const gridPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n gridPath.setAttribute('d', `M ${this.gridSize} 0 L 0 0 0 ${this.gridSize}`);\n gridPath.setAttribute('fill', 'none');\n gridPath.setAttribute('stroke', this.gridColor);\n gridPath.setAttribute('stroke-width', '0.5');\n pattern.appendChild(gridPath);\n fillValue = `url(#${patternId})`;\n }\n\n // Create the frame rectangle\n const frameRect = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n frameRect.setAttribute(\"x\", this.x);\n frameRect.setAttribute(\"y\", this.y);\n frameRect.setAttribute(\"width\", this.width);\n frameRect.setAttribute(\"height\", this.height);\n frameRect.setAttribute(\"stroke\", this.options.stroke);\n frameRect.setAttribute(\"stroke-width\", this.options.strokeWidth);\n frameRect.setAttribute(\"fill\", fillValue);\n frameRect.setAttribute(\"opacity\", this.options.opacity);\n frameRect.setAttribute(\"stroke-dasharray\", \"5,5\");\n frameRect.classList.add(\"frame-rect\");\n\n // Apply rotation\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n frameRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.element = frameRect;\n this.group.appendChild(this.element);\n\n // Add label\n this.addFrameLabel();\n\n // Re-attach frame image if present\n if (this._frameImageURL) {\n this.setImageFromURL(this._frameImageURL, this._frameImageFit || 'cover');\n }\n\n // Add selection anchors if selected\n if (this.isSelected) {\n this.addAnchors();\n }\n\n // Update clip path\n this.updateClipPath();\n }\n\n updateAttachedArrows() {\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(shape => {\n if (shape.shapeName === 'arrow') {\n let needsUpdate = false;\n \n // Check if arrow is attached to this frame\n if (shape.attachedToStart && shape.attachedToStart.shape === this) {\n needsUpdate = true;\n }\n if (shape.attachedToEnd && shape.attachedToEnd.shape === this) {\n needsUpdate = true;\n }\n \n if (needsUpdate) {\n shape.updateAttachments();\n }\n }\n });\n }\n }\n\n updateClipPath() {\n // Update the clipping rectangle to match frame dimensions\n this.clipRect.setAttribute(\"x\", this.x);\n this.clipRect.setAttribute(\"y\", this.y);\n this.clipRect.setAttribute(\"width\", this.width);\n this.clipRect.setAttribute(\"height\", this.height);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this.clipRect.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this.clipRect.removeAttribute(\"transform\");\n }\n }\n\n addShapeToFrame(shape) {\n if (shape && !this.containedShapes.includes(shape)) {\n const oldFrame = shape.parentFrame;\n\n // Remove from other frames first\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(otherFrame => {\n if (otherFrame.shapeName === 'frame' && otherFrame !== this) {\n otherFrame.removeShapeFromFrame(shape);\n }\n });\n }\n\n this.containedShapes.push(shape);\n shape.parentFrame = this;\n\n // Only move to clipped group if not currently being dragged\n const el = shape.group || shape.element;\n if (el && el.parentNode && !shape.isDraggedOutTemporarily) {\n el.parentNode.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup into our clipGroup\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n this.clipGroup.appendChild(shape.clipGroup);\n }\n }\n}\n\n removeShapeFromFrame(shape) {\n const index = this.containedShapes.indexOf(shape);\n if (index > -1) {\n this.containedShapes.splice(index, 1);\n if (shape.parentFrame === this) {\n shape.parentFrame = null;\n }\n\n // Move shape's group/element back to main SVG if it's in the clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n\n // For sub-frames, also move their clipGroup back to main SVG\n if (shape.shapeName === 'frame' && shape.clipGroup && shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n svg.appendChild(shape.clipGroup);\n }\n\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n // Check if a point is inside the frame bounds\n isPointInFrame(x, y) {\n // Simple bounding box check (can be enhanced for rotation)\n return x >= this.x && x <= this.x + this.width &&\n y >= this.y && y <= this.y + this.height;\n }\n\n // Check if a shape overlaps with this frame\n isShapeInFrame(shape) {\n if (!shape || shape === this) return false;\n \n const shapeX = shape.x || 0;\n const shapeY = shape.y || 0;\n const shapeWidth = shape.width || 0;\n const shapeHeight = shape.height || 0;\n \n // Check if the center of the shape is inside the frame (for better UX)\n const shapeCenterX = shapeX + shapeWidth / 2;\n const shapeCenterY = shapeY + shapeHeight / 2;\n \n return shapeCenterX >= this.x && shapeCenterX <= this.x + this.width &&\n shapeCenterY >= this.y && shapeCenterY <= this.y + this.height;\n}\n\nupdateContainedShapes(applyClipping = true) {\n // Check all shapes to see if they should be in this frame\n if (typeof shapes === 'undefined' || !Array.isArray(shapes)) return;\n shapes.forEach(shape => {\n if (shape !== this) {\n // Skip frames that are larger than or equal to this frame (prevent parent containing child loops)\n if (shape.shapeName === 'frame') {\n const shapeArea = (shape.width || 0) * (shape.height || 0);\n const thisArea = (this.width || 0) * (this.height || 0);\n if (shapeArea >= thisArea) return;\n }\n const isInFrame = this.isShapeInFrame(shape);\n const isAlreadyContained = this.containedShapes.includes(shape);\n\n if (isInFrame && !isAlreadyContained) {\n this.addShapeToFrame(shape);\n // Don't apply clipping if we're not supposed to\n if (!applyClipping) {\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n shape.isDraggedOutTemporarily = true;\n }\n }\n } else if (!isInFrame && isAlreadyContained) {\n this.removeShapeFromFrame(shape);\n }\n }\n });\n \n // Update clip path\n this.updateClipPath();\n}\n\nhighlightFrame() {\n if (this.element) {\n this.element.setAttribute('stroke', '#5B57D1');\n this.element.setAttribute('stroke-width', '3');\n this.element.setAttribute('opacity', '0.7');\n }\n}\n\n// Remove frame highlight\nremoveHighlight() {\n if (this.element) {\n this.element.setAttribute('stroke', this.options.stroke);\n this.element.setAttribute('stroke-width', this.options.strokeWidth);\n this.element.setAttribute('opacity', this.options.opacity);\n }\n}\n \n\nmove(dx, dy) {\n this.x += dx;\n this.y += dy;\n\n // Move all contained shapes with the frame\n this.containedShapes.forEach(shape => {\n if (shape) {\n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n\n // Use shape's own move method for proper handling of all shape types\n if (typeof shape.move === 'function') {\n shape.move(dx, dy);\n } else {\n shape.x += dx;\n shape.y += dy;\n }\n\n // Force redraw for shapes whose move() doesn't auto-redraw\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n\n // Update bounding box for freehand strokes\n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n\n // Remove the flag after movement\n delete shape.isBeingMovedByFrame;\n }\n });\n\n // Update arrows attached to this frame\n this.updateAttachedArrows();\n\n this.draw();\n this.updateClipPath();\n}\n\n handleResizeLegacy(anchorIndex, currentPos, startPos, initialFrame) {\n // Legacy version - superseded by the handleResize below with contained shapes scaling\n const dx = currentPos.x - startPos.x;\n const dy = currentPos.y - startPos.y;\n\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + dx; this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 1: this.y = initialFrame.y + dy; this.height = Math.max(10, initialFrame.height - dy); break;\n case 2: this.y = initialFrame.y + dy; this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height - dy); break;\n case 3: this.width = Math.max(10, initialFrame.width + dx); break;\n case 4: this.width = Math.max(10, initialFrame.width + dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 5: this.height = Math.max(10, initialFrame.height + dy); break;\n case 6: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); this.height = Math.max(10, initialFrame.height + dy); break;\n case 7: this.x = initialFrame.x + dx; this.width = Math.max(10, initialFrame.width - dx); break;\n }\n this.updateAttachedArrows();\n this.updateContainedShapes();\n}\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n addFrameLabel() {\n const labelText = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n labelText.setAttribute(\"x\", this.x + 5);\n labelText.setAttribute(\"y\", this.y - 10);\n labelText.setAttribute(\"font-size\", `${16 / currentZoom}px`);\n labelText.setAttribute(\"fill\", this.options.stroke);\n labelText.setAttribute(\"font-family\", \"lixFont\");\n labelText.textContent = this.frameName || \"Frame\";\n labelText.style.cursor = \"pointer\";\n labelText.style.userSelect = \"none\";\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n labelText.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Add double-click event for renaming\n labelText.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n this.startLabelEdit(labelText);\n });\n \n this.group.appendChild(labelText);\n this.labelElement = labelText;\n}\n\nstartLabelEdit(labelElement) {\n // Create a foreignObject to hold an HTML input\n const foreignObject = document.createElementNS(\"http://www.w3.org/2000/svg\", \"foreignObject\");\n foreignObject.setAttribute(\"x\", this.x + 5);\n foreignObject.setAttribute(\"y\", this.y - 20);\n foreignObject.setAttribute(\"width\", Math.max(100, this.width - 10));\n foreignObject.setAttribute(\"height\", 20);\n \n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n foreignObject.setAttribute(\"transform\", `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n // Create input element\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.value = this.frameName || \"Frame\";\n const oldName = this.frameName; // Store old name for undo\n \n input.style.cssText = `\n position: absolute;\n width: 100%;\n height: 20px;\n border: 1px solid #5B57D1;\n background: transparent;\n color: ${this.options.stroke};\n font-family: \"lixFont\";\n font-size: ${15 / currentZoom}px;\n padding: 2px 10px;\n margin: 0;\n outline: none;\n border-radius: 2px;\n box-sizing: border-box;\n `;\n \n foreignObject.appendChild(input);\n this.group.appendChild(foreignObject);\n \n // Hide the original label\n labelElement.style.display = \"none\";\n \n // Focus and select the text\n setTimeout(() => {\n input.focus();\n input.select();\n }, 10);\n \n const finishEdit = () => {\n const newName = input.value.trim() || \"Frame\";\n \n // Track name change in undo system if it actually changed\n if (newName !== oldName) {\n pushTransformAction(this, \n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: oldName \n },\n { \n x: this.x, \n y: this.y, \n width: this.width, \n height: this.height, \n rotation: this.rotation,\n frameName: newName \n }\n );\n }\n \n this.frameName = newName;\n \n // Remove the input\n this.group.removeChild(foreignObject);\n \n // Show and update the label\n labelElement.style.display = \"block\";\n labelElement.textContent = this.frameName;\n \n this.labelElement = labelElement;\n };\n \n // Handle input events\n input.addEventListener('blur', finishEdit);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n finishEdit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n // Cancel edit - restore original name\n this.group.removeChild(foreignObject);\n labelElement.style.display = \"block\";\n }\n });\n \n // Prevent the input from interfering with other interactions\n input.addEventListener('pointerdown', (e) => e.stopPropagation());\n input.addEventListener('pointermove', (e) => e.stopPropagation());\n input.addEventListener('pointerup', (e) => e.stopPropagation());\n}\n selectFrame() {\n this.isSelected = true;\n this.draw();\n this._showSidebar();\n }\n\n _showSidebar() {\n // React sidebar bridge\n if (window.__showSidebarForShape) {\n window.__showSidebarForShape('frame');\n }\n\n const sidebar = document.getElementById('frameSideBar');\n const renameInput = document.getElementById('frameRenameInput');\n const resizeBtn = document.getElementById('frameResizeToFit');\n if (!sidebar) return;\n\n sidebar.classList.remove('hidden');\n\n if (renameInput) {\n renameInput.value = this.frameName || 'Frame';\n // Replace old listener by cloning\n const newInput = renameInput.cloneNode(true);\n renameInput.parentNode.replaceChild(newInput, renameInput);\n newInput.addEventListener('input', () => {\n const val = newInput.value.trim() || 'Frame';\n this.frameName = val;\n if (this.labelElement) this.labelElement.textContent = val;\n });\n newInput.addEventListener('keydown', (e) => {\n if (e.key === 'Enter') newInput.blur();\n });\n newInput.addEventListener('pointerdown', (e) => e.stopPropagation());\n }\n\n if (resizeBtn) {\n const newBtn = resizeBtn.cloneNode(true);\n resizeBtn.parentNode.replaceChild(newBtn, resizeBtn);\n newBtn.addEventListener('click', () => this.resizeToFit());\n }\n }\n\n resizeToFit() {\n if (this.containedShapes.length === 0) return;\n\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n this.containedShapes.forEach(shape => {\n if (shape.shapeName === 'arrow' || shape.shapeName === 'line') {\n [shape.startPoint, shape.endPoint].filter(Boolean).forEach(p => {\n minX = Math.min(minX, p.x);\n minY = Math.min(minY, p.y);\n maxX = Math.max(maxX, p.x);\n maxY = Math.max(maxY, p.y);\n });\n } else if (typeof shape.x === 'number' && typeof shape.y === 'number') {\n const w = shape.width || 0;\n const h = shape.height || 0;\n minX = Math.min(minX, shape.x);\n minY = Math.min(minY, shape.y);\n maxX = Math.max(maxX, shape.x + w);\n maxY = Math.max(maxY, shape.y + h);\n }\n });\n\n if (!isFinite(minX)) return;\n\n const padding = 20;\n const oldState = { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation };\n\n this.x = minX - padding;\n this.y = minY - padding;\n this.width = (maxX - minX) + padding * 2;\n this.height = (maxY - minY) + padding * 2;\n\n pushTransformAction(this, oldState, { x: this.x, y: this.y, width: this.width, height: this.height, rotation: this.rotation });\n this.draw();\n this.updateClipPath();\n this.updateContainedShapes();\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode) {\n anchor.parentNode.removeChild(anchor);\n }\n });\n this.anchors = [];\n this.isSelected = false;\n this.draw();\n const sidebar = document.getElementById('frameSideBar');\n if (sidebar) sidebar.classList.add('hidden');\n }\n\n addAnchors() {\n const anchorSize = 8 / currentZoom;\n const anchorStrokeWidth = 2 / currentZoom;\n\n // Calculate anchor positions (corners + midpoints + rotation handle)\n const anchorPositions = [\n { x: this.x, y: this.y, cursor: 'nw-resize', type: 'corner' }, // Top-left\n { x: this.x + this.width / 2, y: this.y, cursor: 'n-resize', type: 'edge' }, // Top-middle\n { x: this.x + this.width, y: this.y, cursor: 'ne-resize', type: 'corner' }, // Top-right\n { x: this.x + this.width, y: this.y + this.height / 2, cursor: 'e-resize', type: 'edge' }, // Right-middle\n { x: this.x + this.width, y: this.y + this.height, cursor: 'se-resize', type: 'corner' }, // Bottom-right\n { x: this.x + this.width / 2, y: this.y + this.height, cursor: 's-resize', type: 'edge' }, // Bottom-middle\n { x: this.x, y: this.y + this.height, cursor: 'sw-resize', type: 'corner' }, // Bottom-left\n { x: this.x, y: this.y + this.height / 2, cursor: 'w-resize', type: 'edge' }, // Left-middle\n ];\n\n // Add rotation handle\n const rotationHandleDistance = 30 / currentZoom;\n const rotationHandle = {\n x: this.x + this.width / 2,\n y: this.y - rotationHandleDistance,\n cursor: 'grab',\n type: 'rotation'\n };\n anchorPositions.push(rotationHandle);\n\n // Create selection outline first (behind anchors)\n const outline = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n outline.setAttribute('x', this.x);\n outline.setAttribute('y', this.y);\n outline.setAttribute('width', this.width);\n outline.setAttribute('height', this.height);\n outline.setAttribute('fill', 'none');\n outline.setAttribute('stroke', '#5B57D1');\n outline.setAttribute('stroke-width', 1.5);\n outline.setAttribute('vector-effect', 'non-scaling-stroke');\n outline.setAttribute('stroke-dasharray', '4 2');\n outline.setAttribute('style', 'pointer-events: none;');\n\n // Apply rotation to outline if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n outline.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n this.group.appendChild(outline);\n this.selectionOutline = outline;\n\n anchorPositions.forEach((position, index) => {\n let anchor;\n \n if (position.type === 'rotation') {\n // Create rotation handle (circle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n anchor.setAttribute(\"cx\", position.x);\n anchor.setAttribute(\"cy\", position.y);\n anchor.setAttribute(\"r\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Add rotation line\n const rotationLine = document.createElementNS(\"http://www.w3.org/2000/svg\", \"line\");\n rotationLine.setAttribute(\"x1\", this.x + this.width / 2);\n rotationLine.setAttribute(\"y1\", this.y);\n rotationLine.setAttribute(\"x2\", position.x);\n rotationLine.setAttribute(\"y2\", position.y);\n rotationLine.setAttribute(\"stroke\", \"#5B57D1\"); \n rotationLine.setAttribute(\"stroke-width\", anchorStrokeWidth);\n rotationLine.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n\n // Apply rotation to rotation line if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n rotationLine.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n \n this.group.appendChild(rotationLine);\n } else {\n // Create resize handle (rectangle)\n anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n anchor.setAttribute(\"x\", position.x - anchorSize / 2);\n anchor.setAttribute(\"y\", position.y - anchorSize / 2);\n anchor.setAttribute(\"width\", anchorSize);\n anchor.setAttribute(\"height\", anchorSize);\n anchor.setAttribute(\"fill\", \"#121212\"); \n anchor.setAttribute(\"stroke\", \"#5B57D1\"); \n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n }\n\n // Apply rotation to anchor if needed\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n anchor.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n anchor.style.cursor = position.cursor;\n anchor.addEventListener('pointerdown', (e) => this.startAnchorDrag(e, index));\n \n this.anchors.push(anchor);\n this.group.appendChild(anchor);\n });\n }\n\n startAnchorDrag(e, index) {\n e.stopPropagation();\n e.preventDefault();\n\n // Store initial state for undo\n dragOldPosFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const startMousePos = getSVGCoordsFromMouse(e);\n const initialFrame = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n\n const onPointerMove = (event) => {\n const currentMousePos = getSVGCoordsFromMouse(event);\n \n if (index === 8) { // Rotation handle\n this.handleRotation(currentMousePos, initialFrame);\n } else {\n this.handleResize(index, currentMousePos, startMousePos, initialFrame);\n }\n \n this.draw();\n this.updateContainedShapes();\n };\n\n const onPointerUp = () => {\n if (dragOldPosFrame) {\n const newPos = {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rotation: this.rotation\n };\n pushTransformAction(this, dragOldPosFrame, newPos);\n dragOldPosFrame = null;\n }\n \n svg.removeEventListener('pointermove', onPointerMove);\n svg.removeEventListener('pointerup', onPointerUp);\n svg.style.cursor = 'default';\n };\n\n svg.addEventListener('pointermove', onPointerMove);\n svg.addEventListener('pointerup', onPointerUp);\n }\n\n handleRotation(mousePos, initialFrame) {\n const centerX = initialFrame.x + initialFrame.width / 2;\n const centerY = initialFrame.y + initialFrame.height / 2;\n \n const angle = Math.atan2(mousePos.y - centerY, mousePos.x - centerX);\n const newRotation = (angle * 180 / Math.PI + 90) % 360;\n const angleDiff = newRotation - this.rotation;\n const angleRad = angleDiff * Math.PI / 180;\n const cosAngle = Math.cos(angleRad);\n const sinAngle = Math.sin(angleRad);\n \n // Store the rotation center for contained shapes\n const rotationCenter = { x: centerX, y: centerY };\n \n // Rotate all contained shapes around the frame's center\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n \n // Mark shape as being moved by frame to prevent frame containment updates\n shape.isBeingMovedByFrame = true;\n \n switch (shape.shapeName) {\n case 'rectangle':\n case 'frame':\n case 'image':\n case 'icon':\n // Get shape's current center\n const shapeCenterX = shape.x + shape.width / 2;\n const shapeCenterY = shape.y + shape.height / 2;\n \n // Calculate relative position from rotation center\n const relativeX = shapeCenterX - rotationCenter.x;\n const relativeY = shapeCenterY - rotationCenter.y;\n \n // Apply rotation to get new center position\n const newCenterX = rotationCenter.x + (relativeX * cosAngle - relativeY * sinAngle);\n const newCenterY = rotationCenter.y + (relativeX * sinAngle + relativeY * cosAngle);\n \n // Update shape position\n shape.x = newCenterX - shape.width / 2;\n shape.y = newCenterY - shape.height / 2;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'circle':\n // Get circle's center\n const circleCenterX = shape.x;\n const circleCenterY = shape.y;\n \n // Calculate relative position from rotation center\n const relativeCircleX = circleCenterX - rotationCenter.x;\n const relativeCircleY = circleCenterY - rotationCenter.y;\n \n // Apply rotation\n const newCircleCenterX = rotationCenter.x + (relativeCircleX * cosAngle - relativeCircleY * sinAngle);\n const newCircleCenterY = rotationCenter.y + (relativeCircleX * sinAngle + relativeCircleY * cosAngle);\n \n shape.x = newCircleCenterX;\n shape.y = newCircleCenterY;\n shape.rotation = (shape.rotation || 0) + angleDiff;\n \n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'line':\n case 'arrow':\n // Calculate relative positions for start and end points\n const relativeStartX = shape.startPoint.x - rotationCenter.x;\n const relativeStartY = shape.startPoint.y - rotationCenter.y;\n const relativeEndX = shape.endPoint.x - rotationCenter.x;\n const relativeEndY = shape.endPoint.y - rotationCenter.y;\n \n // Apply rotation to both points\n const newStartX = rotationCenter.x + (relativeStartX * cosAngle - relativeStartY * sinAngle);\n const newStartY = rotationCenter.y + (relativeStartX * sinAngle + relativeStartY * cosAngle);\n const newEndX = rotationCenter.x + (relativeEndX * cosAngle - relativeEndY * sinAngle);\n const newEndY = rotationCenter.y + (relativeEndX * sinAngle + relativeEndY * cosAngle);\n \n shape.startPoint.x = newStartX;\n shape.startPoint.y = newStartY;\n shape.endPoint.x = newEndX;\n shape.endPoint.y = newEndY;\n \n if (shape.shapeName === 'arrow' && shape.arrowCurved && typeof shape.initializeCurveControlPoints === 'function') {\n shape.initializeCurveControlPoints();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n break;\n \n case 'text':\n case 'code':\n // Get text/code bounds for center calculation\n const textOrCodeEl = shape.group ? (shape.group.querySelector('text') || shape.group.querySelector('foreignObject')) : null;\n if (textOrCodeEl) {\n const bbox = textOrCodeEl.getBBox();\n const transform = shape.group.transform.baseVal.consolidate();\n const matrix = transform ? transform.matrix : { e: 0, f: 0 };\n\n const textCenterX = bbox.x + matrix.e + bbox.width / 2;\n const textCenterY = bbox.y + matrix.f + bbox.height / 2;\n\n // Calculate relative position\n const relativeTextX = textCenterX - rotationCenter.x;\n const relativeTextY = textCenterY - rotationCenter.y;\n\n // Apply rotation\n const newTextCenterX = rotationCenter.x + (relativeTextX * cosAngle - relativeTextY * sinAngle);\n const newTextCenterY = rotationCenter.y + (relativeTextX * sinAngle + relativeTextY * cosAngle);\n\n // Update position\n const newTransformX = newTextCenterX - bbox.width / 2;\n const newTransformY = newTextCenterY - bbox.height / 2;\n const newShapeRotation = (shape.rotation || 0) + angleDiff;\n\n const textCenterRelativeX = bbox.width / 2;\n const textCenterRelativeY = bbox.height / 2;\n\n shape.group.setAttribute('transform',\n `translate(${newTransformX}, ${newTransformY}) rotate(${newShapeRotation}, ${textCenterRelativeX}, ${textCenterRelativeY})`\n );\n\n shape.x = newTransformX;\n shape.y = newTransformY;\n shape.rotation = newShapeRotation;\n }\n break;\n \n case 'freehandStroke':\n if (shape.points && Array.isArray(shape.points)) {\n // Rotate each point in the stroke\n shape.points = shape.points.map(point => {\n if (!Array.isArray(point) || point.length < 2) return point;\n \n const relativePointX = point[0] - rotationCenter.x;\n const relativePointY = point[1] - rotationCenter.y;\n \n const newPointX = rotationCenter.x + (relativePointX * cosAngle - relativePointY * sinAngle);\n const newPointY = rotationCenter.y + (relativePointX * sinAngle + relativePointY * cosAngle);\n \n return [newPointX, newPointY, point[2] || 0.5];\n });\n \n if (typeof shape.updateBoundingBox === 'function') {\n shape.updateBoundingBox();\n }\n if (typeof shape.draw === 'function') {\n shape.draw();\n }\n }\n break;\n }\n \n // Update arrows attached to the contained shape\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n \n // Remove the flag after rotation\n delete shape.isBeingMovedByFrame;\n });\n \n // Update the frame's rotation\n this.rotation = newRotation;\n \n // Update arrows attached to this frame\n this.updateAttachedArrows();\n }\n\n handleResize(anchorIndex, currentPos, startPos, initialFrame) {\n const rawDx = currentPos.x - startPos.x;\n const rawDy = currentPos.y - startPos.y;\n\n // Rotate delta to local (unrotated) space when frame is rotated\n const rad = (this.rotation || 0) * Math.PI / 180;\n const cosR = Math.cos(rad);\n const sinR = Math.sin(rad);\n const dx = rawDx * cosR + rawDy * sinR;\n const dy = -rawDx * sinR + rawDy * cosR;\n\n // Store old frame for scale calculation\n const oldX = this.x, oldY = this.y, oldW = this.width, oldH = this.height;\n\n // Compute new dimensions using local-space deltas\n let newW, newH;\n // Fixed corner relative to initial frame origin: (fixRelX, fixRelY)\n let fixRelX, fixRelY;\n\n switch (anchorIndex) {\n case 0: // Top-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = initialFrame.width; fixRelY = initialFrame.height;\n break;\n case 1: // Top-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 2: // Top-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height - dy);\n fixRelX = 0; fixRelY = initialFrame.height;\n break;\n case 3: // Right-middle\n newW = Math.max(10, initialFrame.width + dx);\n newH = initialFrame.height;\n fixRelX = 0; fixRelY = 0;\n break;\n case 4: // Bottom-right\n newW = Math.max(10, initialFrame.width + dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 5: // Bottom-middle\n newW = initialFrame.width;\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = 0; fixRelY = 0;\n break;\n case 6: // Bottom-left\n newW = Math.max(10, initialFrame.width - dx);\n newH = Math.max(10, initialFrame.height + dy);\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n case 7: // Left-middle\n newW = Math.max(10, initialFrame.width - dx);\n newH = initialFrame.height;\n fixRelX = initialFrame.width; fixRelY = 0;\n break;\n }\n\n // Compute new position using fixed-corner constraint\n if (this.rotation && this.rotation !== 0) {\n // Compute rotated world position of the fixed corner in the initial frame\n const iCX = initialFrame.x + initialFrame.width / 2;\n const iCY = initialFrame.y + initialFrame.height / 2;\n const odx = (initialFrame.x + fixRelX) - iCX;\n const ody = (initialFrame.y + fixRelY) - iCY;\n const fixedWorldX = iCX + odx * cosR - ody * sinR;\n const fixedWorldY = iCY + odx * sinR + ody * cosR;\n\n // Where the fixed corner sits in new rect (relative to new origin)\n const fixNewRelX = (fixRelX === 0) ? 0 : newW;\n const fixNewRelY = (fixRelY === 0) ? 0 : newH;\n\n // Solve for new origin\n const ncx = newW / 2;\n const ncy = newH / 2;\n const ndx = fixNewRelX - ncx;\n const ndy = fixNewRelY - ncy;\n const rotX = ncx + ndx * cosR - ndy * sinR;\n const rotY = ncy + ndx * sinR + ndy * cosR;\n\n this.x = fixedWorldX - rotX;\n this.y = fixedWorldY - rotY;\n } else {\n // No rotation - use simple axis-aligned position calculation\n switch (anchorIndex) {\n case 0: this.x = initialFrame.x + (initialFrame.width - newW); this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 1: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 2: this.y = initialFrame.y + (initialFrame.height - newH); break;\n case 3: break;\n case 4: break;\n case 5: break;\n case 6: this.x = initialFrame.x + (initialFrame.width - newW); break;\n case 7: this.x = initialFrame.x + (initialFrame.width - newW); break;\n }\n }\n\n this.width = newW;\n this.height = newH;\n\n // Scale contained shapes proportionally so nothing falls out\n if (oldW > 0 && oldH > 0) {\n const scaleX = this.width / oldW;\n const scaleY = this.height / oldH;\n\n if (Math.abs(scaleX - 1) > 0.001 || Math.abs(scaleY - 1) > 0.001) {\n this.containedShapes.forEach(shape => {\n if (!shape) return;\n shape.isBeingMovedByFrame = true;\n\n switch (shape.shapeName) {\n case 'rectangle':\n case 'image':\n case 'icon':\n case 'code': {\n const relX = (shape.x - oldX) / oldW;\n const relY = (shape.y - oldY) / oldH;\n const relW = shape.width / oldW;\n const relH = shape.height / oldH;\n shape.x = this.x + relX * this.width;\n shape.y = this.y + relY * this.height;\n shape.width = relW * this.width;\n shape.height = relH * this.height;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'circle': {\n const relCX = (shape.x - oldX) / oldW;\n const relCY = (shape.y - oldY) / oldH;\n shape.x = this.x + relCX * this.width;\n shape.y = this.y + relCY * this.height;\n shape.rx = (shape.rx / oldW) * this.width;\n shape.ry = (shape.ry / oldH) * this.height;\n shape.width = shape.rx * 2;\n shape.height = shape.ry * 2;\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'arrow':\n case 'line': {\n const relSX = (shape.startPoint.x - oldX) / oldW;\n const relSY = (shape.startPoint.y - oldY) / oldH;\n const relEX = (shape.endPoint.x - oldX) / oldW;\n const relEY = (shape.endPoint.y - oldY) / oldH;\n shape.startPoint.x = this.x + relSX * this.width;\n shape.startPoint.y = this.y + relSY * this.height;\n shape.endPoint.x = this.x + relEX * this.width;\n shape.endPoint.y = this.y + relEY * this.height;\n if (shape.controlPoint1) {\n const relC1X = (shape.controlPoint1.x - oldX) / oldW;\n const relC1Y = (shape.controlPoint1.y - oldY) / oldH;\n shape.controlPoint1.x = this.x + relC1X * this.width;\n shape.controlPoint1.y = this.y + relC1Y * this.height;\n }\n if (shape.controlPoint2) {\n const relC2X = (shape.controlPoint2.x - oldX) / oldW;\n const relC2Y = (shape.controlPoint2.y - oldY) / oldH;\n shape.controlPoint2.x = this.x + relC2X * this.width;\n shape.controlPoint2.y = this.y + relC2Y * this.height;\n }\n if (typeof shape.draw === 'function') shape.draw();\n break;\n }\n case 'text': {\n const tx = shape.x || 0;\n const ty = shape.y || 0;\n const relTX = (tx - oldX) / oldW;\n const relTY = (ty - oldY) / oldH;\n shape.x = this.x + relTX * this.width;\n shape.y = this.y + relTY * this.height;\n break;\n }\n case 'freehandStroke': {\n // Pie sectors are editable closed freehand polygons.\n // Scale their source points with the frame so their\n // geometry stays attached instead of being clipped\n // at its previous canvas coordinates.\n if (Array.isArray(shape.points)) {\n shape.points = shape.points.map(point => {\n if (!Array.isArray(point) || point.length < 2) return point;\n const relPX = (point[0] - oldX) / oldW;\n const relPY = (point[1] - oldY) / oldH;\n return [\n this.x + relPX * this.width,\n this.y + relPY * this.height,\n point[2] || 0.5\n ];\n });\n shape._moveOffsetX = 0;\n shape._moveOffsetY = 0;\n if (typeof shape.draw === 'function') shape.draw();\n }\n break;\n }\n }\n\n if (typeof shape.updateAttachedArrows === 'function') {\n shape.updateAttachedArrows();\n }\n delete shape.isBeingMovedByFrame;\n });\n }\n }\n\n // Update contained shapes visibility\n this.updateContainedShapes();\n }\n \n temporarilyRemoveFromFrame(shape) {\n if (shape && shape.parentFrame === this) {\n // Move shape back to main SVG temporarily (without removing from containedShapes array)\n const el = shape.group || shape.element;\n if (el && el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n svg.appendChild(el);\n }\n shape.isDraggedOutTemporarily = true;\n }\n}\n\n// Add a method to restore clipping for a shape after drag\nrestoreToFrame(shape) {\n if (shape && shape.parentFrame === this && shape.isDraggedOutTemporarily) {\n // Move shape back to clipped group\n const el = shape.group || shape.element;\n if (el && el.parentNode === svg) {\n svg.removeChild(el);\n this.clipGroup.appendChild(el);\n }\n delete shape.isDraggedOutTemporarily;\n }\n}\n\n\n contains(viewBoxX, viewBoxY) {\n // Simple point-in-rectangle test (without rotation for now)\n return viewBoxX >= this.x && viewBoxX <= this.x + this.width &&\n viewBoxY >= this.y && viewBoxY <= this.y + this.height;\n }\n\n // Arrow attachment support (similar to other shapes)\n getAttachmentPoint(point, tolerance = 20) {\n const rect = {\n left: this.x,\n right: this.x + this.width,\n top: this.y,\n bottom: this.y + this.height\n };\n\n const distances = {\n top: Math.abs(point.y - rect.top),\n bottom: Math.abs(point.y - rect.bottom),\n left: Math.abs(point.x - rect.left),\n right: Math.abs(point.x - rect.right)\n };\n\n let closestSide = null;\n let minDistance = tolerance;\n\n for (let side in distances) {\n if (distances[side] < minDistance &&\n ((side === 'top' || side === 'bottom') && point.x >= rect.left && point.x <= rect.right) ||\n ((side === 'left' || side === 'right') && point.y >= rect.top && point.y <= rect.bottom)) {\n minDistance = distances[side];\n closestSide = side;\n }\n }\n\n if (closestSide) {\n let attachPoint;\n const offset = { x: 0, y: 0 };\n\n switch (closestSide) {\n case 'top':\n attachPoint = { x: point.x, y: rect.top };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'bottom':\n attachPoint = { x: point.x, y: rect.bottom };\n offset.x = point.x - (rect.left + this.width / 2);\n break;\n case 'left':\n attachPoint = { x: rect.left, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n case 'right':\n attachPoint = { x: rect.right, y: point.y };\n offset.y = point.y - (rect.top + this.height / 2);\n break;\n }\n\n return { point: attachPoint, side: closestSide, offset, shape: this };\n }\n\n return null;\n }\n\n updateStyle(newOptions) {\n Object.keys(newOptions).forEach(key => newOptions[key] === undefined && delete newOptions[key]);\n this.options = { ...this.options, ...newOptions };\n this.draw();\n }\n\n destroy() {\n const isDiagramFrame = !!this._diagramType;\n\n [...this.containedShapes].forEach(shape => {\n if (isDiagramFrame) {\n // Diagram/graph frame: destroy contained shapes with the frame\n if (typeof window.cleanupAttachments === 'function') {\n window.cleanupAttachments(shape);\n }\n const el = shape.group || shape.element;\n if (el && el.parentNode) {\n el.parentNode.removeChild(el);\n }\n if (shape.shapeName === 'frame') {\n if (shape.clipGroup && shape.clipGroup.parentNode) {\n shape.clipGroup.parentNode.removeChild(shape.clipGroup);\n }\n if (shape.clipPath && shape.clipPath.parentNode) {\n shape.clipPath.parentNode.removeChild(shape.clipPath);\n }\n }\n const idx = shapes.indexOf(shape);\n if (idx > -1) {\n shapes.splice(idx, 1);\n }\n } else {\n // Regular frame: release contained shapes back to canvas\n const el = shape.group || shape.element;\n if (el) {\n if (el.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(el);\n }\n svg.appendChild(el);\n }\n if (shape.shapeName === 'frame' && shape.clipGroup) {\n if (shape.clipGroup.parentNode === this.clipGroup) {\n this.clipGroup.removeChild(shape.clipGroup);\n }\n svg.appendChild(shape.clipGroup);\n }\n }\n shape.parentFrame = null;\n delete shape.isBeingMovedByFrame;\n });\n this.containedShapes = [];\n\n // Remove clip path\n if (this.clipPath && this.clipPath.parentNode) {\n this.clipPath.parentNode.removeChild(this.clipPath);\n }\n\n // Remove groups (clipGroup should be empty now)\n if (this.clipGroup && this.clipGroup.parentNode) {\n this.clipGroup.parentNode.removeChild(this.clipGroup);\n }\n\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n\n /**\n * Set a background image for this frame from a URL.\n * The image will fit/cover the frame dimensions.\n * @param {string} url - Image URL\n * @param {string} fit - 'cover' (default) | 'contain' | 'fill'\n */\n setImageFromURL(url, fit = 'cover') {\n if (!url) {\n // Remove existing frame image\n if (this._frameImage && this._frameImage.parentNode) {\n this._frameImage.parentNode.removeChild(this._frameImage);\n this._frameImage = null;\n }\n this._frameImageURL = null;\n return;\n }\n\n this._frameImageURL = url;\n this._frameImageFit = fit;\n\n if (!this._frameImage) {\n this._frameImage = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n this._frameImage.setAttribute('pointer-events', 'none');\n }\n // Always update preserveAspectRatio when fit changes\n this._frameImage.setAttribute('preserveAspectRatio',\n fit === 'cover' ? 'xMidYMid slice' :\n fit === 'contain' ? 'xMidYMid meet' :\n fit === 'center' ? 'xMidYMid meet' : 'none'\n );\n\n this._frameImage.setAttribute('href', url);\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n }\n\n // Insert image right after the frame rect (below contained shapes)\n if (this._frameImage.parentNode === this.group) {\n this.group.removeChild(this._frameImage);\n }\n if (this.element && this.element.nextSibling) {\n this.group.insertBefore(this._frameImage, this.element.nextSibling);\n } else {\n this.group.appendChild(this._frameImage);\n }\n }\n\n /**\n * Update frame image position/size (called during move/resize)\n */\n _updateFrameImage() {\n if (!this._frameImage) return;\n this._frameImage.setAttribute('x', this.x);\n this._frameImage.setAttribute('y', this.y);\n this._frameImage.setAttribute('width', this.width);\n this._frameImage.setAttribute('height', this.height);\n\n if (this.rotation !== 0) {\n const centerX = this.x + this.width / 2;\n const centerY = this.y + this.height / 2;\n this._frameImage.setAttribute('transform', `rotate(${this.rotation}, ${centerX}, ${centerY})`);\n } else {\n this._frameImage.removeAttribute('transform');\n }\n }\n}\n\nexport { Frame };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/react/index.js
CHANGED
|
@@ -431,7 +431,7 @@ function useSketchEngine(svgRef, ready = true) {
|
|
|
431
431
|
setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
|
|
432
432
|
getState: () => useSketchStore_default.getState()
|
|
433
433
|
};
|
|
434
|
-
const { SketchEngine } = await import("./SketchEngine-
|
|
434
|
+
const { SketchEngine } = await import("./SketchEngine-UYMJJEVW.js");
|
|
435
435
|
if (cancelled) return;
|
|
436
436
|
const engine = new SketchEngine(svgRef.current);
|
|
437
437
|
await engine.init();
|
|
@@ -4741,7 +4741,7 @@ var _saveScene = null;
|
|
|
4741
4741
|
var _loadScene = null;
|
|
4742
4742
|
async function ensureSceneSerializer() {
|
|
4743
4743
|
if (_saveScene && _loadScene) return;
|
|
4744
|
-
const m = await import("./SceneSerializer-
|
|
4744
|
+
const m = await import("./SceneSerializer-7UACFCRF.js");
|
|
4745
4745
|
_saveScene = m.saveScene;
|
|
4746
4746
|
_loadScene = m.loadScene;
|
|
4747
4747
|
}
|
package/package.json
CHANGED
package/src/shapes/Frame.js
CHANGED
|
@@ -1211,6 +1211,28 @@ startLabelEdit(labelElement) {
|
|
|
1211
1211
|
shape.y = this.y + relTY * this.height;
|
|
1212
1212
|
break;
|
|
1213
1213
|
}
|
|
1214
|
+
case 'freehandStroke': {
|
|
1215
|
+
// Pie sectors are editable closed freehand polygons.
|
|
1216
|
+
// Scale their source points with the frame so their
|
|
1217
|
+
// geometry stays attached instead of being clipped
|
|
1218
|
+
// at its previous canvas coordinates.
|
|
1219
|
+
if (Array.isArray(shape.points)) {
|
|
1220
|
+
shape.points = shape.points.map(point => {
|
|
1221
|
+
if (!Array.isArray(point) || point.length < 2) return point;
|
|
1222
|
+
const relPX = (point[0] - oldX) / oldW;
|
|
1223
|
+
const relPY = (point[1] - oldY) / oldH;
|
|
1224
|
+
return [
|
|
1225
|
+
this.x + relPX * this.width,
|
|
1226
|
+
this.y + relPY * this.height,
|
|
1227
|
+
point[2] || 0.5
|
|
1228
|
+
];
|
|
1229
|
+
});
|
|
1230
|
+
shape._moveOffsetX = 0;
|
|
1231
|
+
shape._moveOffsetY = 0;
|
|
1232
|
+
if (typeof shape.draw === 'function') shape.draw();
|
|
1233
|
+
}
|
|
1234
|
+
break;
|
|
1235
|
+
}
|
|
1214
1236
|
}
|
|
1215
1237
|
|
|
1216
1238
|
if (typeof shape.updateAttachedArrows === 'function') {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|