@elixpo/lixsketch 5.6.9 → 5.6.10
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-PPDS3AD6.js → CopyPaste-N4U2NTQT.js} +5 -5
- package/dist/react/{EventDispatcher-UV7LFSAS.js → EventDispatcher-J657SDW4.js} +12 -12
- package/dist/react/{EventDispatcher-UV7LFSAS.js.map → EventDispatcher-J657SDW4.js.map} +1 -1
- package/dist/react/{Frame-DELCMYV6.js → Frame-NHPESH4Y.js} +2 -2
- package/dist/react/IconShape-RN5HJDUF.js +10 -0
- package/dist/react/ImageShape-L7U64AVP.js +10 -0
- package/dist/react/Line-LPRTGPUQ.js +10 -0
- package/dist/react/{SceneSerializer-H6KMQCO2.js → SceneSerializer-Y6QABGZY.js} +5 -5
- package/dist/react/{Selection-CFWRGVKH.js → Selection-GCZWCNAR.js} +3 -3
- package/dist/react/{SketchEngine-UFLZJQXS.js → SketchEngine-PCMCE63L.js} +19 -19
- package/dist/react/{arrowTool-DO327FKU.js → arrowTool-UN3TNJFP.js} +2 -2
- package/dist/react/{chunk-O7KXLFZN.js → chunk-3FCIBY54.js} +2 -2
- package/dist/react/{chunk-6LWUR7XB.js → chunk-3PFVMNDJ.js} +3 -3
- package/dist/react/{chunk-6LWUR7XB.js.map → chunk-3PFVMNDJ.js.map} +1 -1
- package/dist/react/{chunk-2ALS5JGS.js → chunk-5XGQ3CMT.js} +2 -2
- package/dist/react/{chunk-KZBKYHZO.js → chunk-7NHZYKYB.js} +3 -3
- package/dist/react/{chunk-KZBKYHZO.js.map → chunk-7NHZYKYB.js.map} +1 -1
- package/dist/react/{chunk-I7TVGJFF.js → chunk-7WXEWDRL.js} +3 -3
- package/dist/react/{chunk-I7TVGJFF.js.map → chunk-7WXEWDRL.js.map} +1 -1
- package/dist/react/{chunk-CGMUXYPJ.js → chunk-JVHZVV5U.js} +3 -3
- package/dist/react/{chunk-CGMUXYPJ.js.map → chunk-JVHZVV5U.js.map} +1 -1
- package/dist/react/{chunk-37PF7FG2.js → chunk-KACRJ6AJ.js} +2 -2
- package/dist/react/{chunk-X5ENBMGL.js → chunk-KXLNEFN5.js} +2 -2
- package/dist/react/{chunk-X5ENBMGL.js.map → chunk-KXLNEFN5.js.map} +1 -1
- package/dist/react/{chunk-DODPOWNX.js → chunk-P5476S5I.js} +3 -3
- package/dist/react/{chunk-DODPOWNX.js.map → chunk-P5476S5I.js.map} +1 -1
- package/dist/react/{chunk-BOZEDUAF.js → chunk-TAJ5E6KI.js} +3 -3
- package/dist/react/chunk-TAJ5E6KI.js.map +7 -0
- package/dist/react/{chunk-KC26KJW4.js → chunk-UERV53R7.js} +2 -2
- package/dist/react/{chunk-7DD2JRBC.js → chunk-ULZW5PXM.js} +2 -2
- package/dist/react/{chunk-RK3NVAER.js → chunk-YHQ4ZAJQ.js} +4 -4
- package/dist/react/{chunk-RK3NVAER.js.map → chunk-YHQ4ZAJQ.js.map} +1 -1
- package/dist/react/{circleTool-NK4RVDAR.js → circleTool-YDTQDGYX.js} +3 -3
- package/dist/react/{codeTool-3WF4HEOW.js → codeTool-U6SYKHHD.js} +3 -3
- package/dist/react/{frameTool-VCNV2NG2.js → frameTool-VRI7OODN.js} +2 -2
- package/dist/react/{freehandTool-TBAOD46K.js → freehandTool-2ICCQHVY.js} +3 -3
- package/dist/react/{iconTool-65JCAKYF.js → iconTool-32D5NJ4I.js} +3 -3
- package/dist/react/{imageTool-UQZUBOK2.js → imageTool-Z6Y4OXBG.js} +3 -3
- package/dist/react/index.js +21 -9
- package/dist/react/index.js.map +2 -2
- package/dist/react/{lineTool-762KBYOM.js → lineTool-BUWVQ666.js} +3 -3
- package/dist/react/{rectangleTool-IQK3HZK6.js → rectangleTool-NJYG6Y6L.js} +3 -3
- package/dist/react/styles.css +4 -0
- package/dist/react/{textTool-ITG2SBJK.js → textTool-CIJCF4Z3.js} +4 -4
- package/package.json +1 -1
- package/src/react/components/sidebars/TextSidebar.jsx +10 -4
- package/src/react/store/useUIStore.js +1 -1
- package/src/react/styles.css +13 -0
- package/src/react/utils/canvasBackgrounds.js +11 -2
- package/src/shapes/Line.js +2 -2
- package/src/tools/arrowTool.js +1 -1
- package/src/tools/circleTool.js +1 -1
- package/src/tools/codeTool.js +1 -1
- package/src/tools/freehandTool.js +1 -1
- package/src/tools/lineTool.js +1 -1
- package/src/tools/rectangleTool.js +1 -1
- package/src/tools/shapeRecognitionTool.js +1 -1
- package/src/tools/textTool.js +1 -1
- package/dist/react/IconShape-PZHMZSLR.js +0 -10
- package/dist/react/ImageShape-ZMBZARRI.js +0 -10
- package/dist/react/Line-VPVPL6ET.js +0 -10
- package/dist/react/chunk-BOZEDUAF.js.map +0 -7
- /package/dist/react/{CopyPaste-PPDS3AD6.js.map → CopyPaste-N4U2NTQT.js.map} +0 -0
- /package/dist/react/{Frame-DELCMYV6.js.map → Frame-NHPESH4Y.js.map} +0 -0
- /package/dist/react/{IconShape-PZHMZSLR.js.map → IconShape-RN5HJDUF.js.map} +0 -0
- /package/dist/react/{ImageShape-ZMBZARRI.js.map → ImageShape-L7U64AVP.js.map} +0 -0
- /package/dist/react/{Line-VPVPL6ET.js.map → Line-LPRTGPUQ.js.map} +0 -0
- /package/dist/react/{SceneSerializer-H6KMQCO2.js.map → SceneSerializer-Y6QABGZY.js.map} +0 -0
- /package/dist/react/{Selection-CFWRGVKH.js.map → Selection-GCZWCNAR.js.map} +0 -0
- /package/dist/react/{SketchEngine-UFLZJQXS.js.map → SketchEngine-PCMCE63L.js.map} +0 -0
- /package/dist/react/{arrowTool-DO327FKU.js.map → arrowTool-UN3TNJFP.js.map} +0 -0
- /package/dist/react/{chunk-O7KXLFZN.js.map → chunk-3FCIBY54.js.map} +0 -0
- /package/dist/react/{chunk-2ALS5JGS.js.map → chunk-5XGQ3CMT.js.map} +0 -0
- /package/dist/react/{chunk-37PF7FG2.js.map → chunk-KACRJ6AJ.js.map} +0 -0
- /package/dist/react/{chunk-KC26KJW4.js.map → chunk-UERV53R7.js.map} +0 -0
- /package/dist/react/{chunk-7DD2JRBC.js.map → chunk-ULZW5PXM.js.map} +0 -0
- /package/dist/react/{circleTool-NK4RVDAR.js.map → circleTool-YDTQDGYX.js.map} +0 -0
- /package/dist/react/{codeTool-3WF4HEOW.js.map → codeTool-U6SYKHHD.js.map} +0 -0
- /package/dist/react/{frameTool-VCNV2NG2.js.map → frameTool-VRI7OODN.js.map} +0 -0
- /package/dist/react/{freehandTool-TBAOD46K.js.map → freehandTool-2ICCQHVY.js.map} +0 -0
- /package/dist/react/{iconTool-65JCAKYF.js.map → iconTool-32D5NJ4I.js.map} +0 -0
- /package/dist/react/{imageTool-UQZUBOK2.js.map → imageTool-Z6Y4OXBG.js.map} +0 -0
- /package/dist/react/{lineTool-762KBYOM.js.map → lineTool-BUWVQ666.js.map} +0 -0
- /package/dist/react/{rectangleTool-IQK3HZK6.js.map → rectangleTool-NJYG6Y6L.js.map} +0 -0
- /package/dist/react/{textTool-ITG2SBJK.js.map → textTool-CIJCF4Z3.js.map} +0 -0
|
@@ -168,12 +168,12 @@ var SketchEngine = class {
|
|
|
168
168
|
import("./Rectangle-4U4CD2ER.js"),
|
|
169
169
|
import("./Circle-HMM5PKJ2.js"),
|
|
170
170
|
import("./Arrow-EF7ALH2Y.js"),
|
|
171
|
-
import("./Line-
|
|
171
|
+
import("./Line-LPRTGPUQ.js"),
|
|
172
172
|
import("./TextShape-DY77FFI2.js"),
|
|
173
173
|
import("./CodeShape-TE74XP5V.js"),
|
|
174
|
-
import("./ImageShape-
|
|
175
|
-
import("./IconShape-
|
|
176
|
-
import("./Frame-
|
|
174
|
+
import("./ImageShape-L7U64AVP.js"),
|
|
175
|
+
import("./IconShape-RN5HJDUF.js"),
|
|
176
|
+
import("./Frame-NHPESH4Y.js"),
|
|
177
177
|
import("./FreehandStroke-WXIJKD5I.js")
|
|
178
178
|
]);
|
|
179
179
|
window.Rectangle = Rectangle;
|
|
@@ -210,16 +210,16 @@ var SketchEngine = class {
|
|
|
210
210
|
frameTool,
|
|
211
211
|
freehandTool
|
|
212
212
|
] = await Promise.all([
|
|
213
|
-
import("./rectangleTool-
|
|
214
|
-
import("./circleTool-
|
|
215
|
-
import("./arrowTool-
|
|
216
|
-
import("./lineTool-
|
|
217
|
-
import("./textTool-
|
|
218
|
-
import("./codeTool-
|
|
219
|
-
import("./imageTool-
|
|
220
|
-
import("./iconTool-
|
|
221
|
-
import("./frameTool-
|
|
222
|
-
import("./freehandTool-
|
|
213
|
+
import("./rectangleTool-NJYG6Y6L.js"),
|
|
214
|
+
import("./circleTool-YDTQDGYX.js"),
|
|
215
|
+
import("./arrowTool-UN3TNJFP.js"),
|
|
216
|
+
import("./lineTool-BUWVQ666.js"),
|
|
217
|
+
import("./textTool-CIJCF4Z3.js"),
|
|
218
|
+
import("./codeTool-U6SYKHHD.js"),
|
|
219
|
+
import("./imageTool-Z6Y4OXBG.js"),
|
|
220
|
+
import("./iconTool-32D5NJ4I.js"),
|
|
221
|
+
import("./frameTool-VRI7OODN.js"),
|
|
222
|
+
import("./freehandTool-2ICCQHVY.js")
|
|
223
223
|
]);
|
|
224
224
|
this._modules.tools = {
|
|
225
225
|
rectangleTool,
|
|
@@ -243,11 +243,11 @@ var SketchEngine = class {
|
|
|
243
243
|
resizeShapes,
|
|
244
244
|
resizeCode
|
|
245
245
|
] = await Promise.all([
|
|
246
|
-
import("./EventDispatcher-
|
|
246
|
+
import("./EventDispatcher-J657SDW4.js"),
|
|
247
247
|
import("./UndoRedo-RXO7YHA2.js"),
|
|
248
|
-
import("./Selection-
|
|
248
|
+
import("./Selection-GCZWCNAR.js"),
|
|
249
249
|
import("./ZoomPan-RR7KUYZT.js"),
|
|
250
|
-
import("./CopyPaste-
|
|
250
|
+
import("./CopyPaste-N4U2NTQT.js"),
|
|
251
251
|
import("./EraserTrail-PA6IQLQN.js"),
|
|
252
252
|
import("./ResizeShapes-LKEQTITP.js"),
|
|
253
253
|
import("./ResizeCode-WAMDTKSW.js")
|
|
@@ -266,7 +266,7 @@ var SketchEngine = class {
|
|
|
266
266
|
eventDispatcher.initEventDispatcher(this.svg);
|
|
267
267
|
}
|
|
268
268
|
window.__sketchInteractionReady = true;
|
|
269
|
-
const sceneSerializer = await import("./SceneSerializer-
|
|
269
|
+
const sceneSerializer = await import("./SceneSerializer-Y6QABGZY.js");
|
|
270
270
|
if (sceneSerializer.initSceneSerializer) sceneSerializer.initSceneSerializer();
|
|
271
271
|
await Promise.all([
|
|
272
272
|
import("./eraserTool-2GS2LQCS.js"),
|
|
@@ -441,4 +441,4 @@ export {
|
|
|
441
441
|
SketchEngine,
|
|
442
442
|
SketchEngine_default as default
|
|
443
443
|
};
|
|
444
|
-
//# sourceMappingURL=SketchEngine-
|
|
444
|
+
//# sourceMappingURL=SketchEngine-PCMCE63L.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
handleMouseMove,
|
|
6
6
|
handleMouseUp,
|
|
7
7
|
updateAttachedArrows
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-KXLNEFN5.js";
|
|
9
9
|
import "./chunk-VZX55VQL.js";
|
|
10
10
|
export {
|
|
11
11
|
cleanupAttachments,
|
|
@@ -14,4 +14,4 @@ export {
|
|
|
14
14
|
handleMouseUp as handleMouseUpArrow,
|
|
15
15
|
updateAttachedArrows
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=arrowTool-
|
|
17
|
+
//# sourceMappingURL=arrowTool-UN3TNJFP.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
cleanupAttachments,
|
|
7
7
|
updateAttachedArrows
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-KXLNEFN5.js";
|
|
9
9
|
import {
|
|
10
10
|
pushCreateAction,
|
|
11
11
|
pushDeleteAction,
|
|
@@ -961,4 +961,4 @@ export {
|
|
|
961
961
|
startDrag,
|
|
962
962
|
stopDrag
|
|
963
963
|
};
|
|
964
|
-
//# sourceMappingURL=chunk-
|
|
964
|
+
//# sourceMappingURL=chunk-3FCIBY54.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
calculateSnap,
|
|
4
4
|
clearSnapGuides,
|
|
5
5
|
updateAttachedArrows
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KXLNEFN5.js";
|
|
7
7
|
import {
|
|
8
8
|
pushCreateAction,
|
|
9
9
|
pushDeleteAction,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
// src/tools/freehandTool.js
|
|
16
16
|
function getThemeStroke() {
|
|
17
17
|
if (typeof document === "undefined") return "#fff";
|
|
18
|
-
return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#
|
|
18
|
+
return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#000000";
|
|
19
19
|
}
|
|
20
20
|
window.__updateArrowsForShape = updateAttachedArrows;
|
|
21
21
|
var strokeColors = document.querySelectorAll(".strokeColors span");
|
|
@@ -561,4 +561,4 @@ export {
|
|
|
561
561
|
handleMouseMove,
|
|
562
562
|
handleMouseUp
|
|
563
563
|
};
|
|
564
|
-
//# sourceMappingURL=chunk-
|
|
564
|
+
//# sourceMappingURL=chunk-3PFVMNDJ.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tools/freehandTool.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable */\n// Freehand tool event handlers - extracted from canvasStroke.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { updateAttachedArrows as updateArrowsForShape, cleanupAttachments } from './arrowTool.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#1a1a2e\"; }\n\n// Expose updateArrowsForShape globally so FreehandStroke.updateAttachedArrows() can call it\n// (FreehandStroke.js is a separate module and cannot import freehandTool's local bindings)\nwindow.__updateArrowsForShape = updateArrowsForShape;\n\nconst strokeColors = document.querySelectorAll(\".strokeColors span\");\nconst strokeThicknesses = document.querySelectorAll(\".strokeThickness span\");\nconst strokeStyles = document.querySelectorAll(\".strokeStyleSpan\");\nconst strokeTapers = document.querySelectorAll(\".strokeTaperSpan\");\nconst strokeRoughnesses = document.querySelectorAll(\".strokeRoughnessSpan\");\nlet strokeColor = null;\nlet strokeThickness = 2;\nlet strokeStyleValue = \"solid\";\nlet strokeThinning = 0;\nlet strokeRoughnessValue = \"smooth\";\nlet points = [];\nlet isDrawingStroke = false;\nlet currentStroke = null;\nlet strokeOpacity = 1;\n\n\nlet isDraggingStroke = false;\nlet isResizingStroke = false;\nlet isRotatingStroke = false;\nlet dragOldPosStroke = null;\nlet resizingAnchorIndex = null;\nlet startRotationMouseAngle = null;\nlet startShapeRotation = null;\nlet startX, startY;\n\n// Frame attachment variables\nlet draggedShapeInitialFrameStroke = null;\nlet hoveredFrameStroke = null;\n\n// Enhanced mouse tracking with better point collection\nlet lastPoint = null;\nlet lastTime = 0;\nconst minDistance = 2; // Minimum distance between points\nconst maxDistance = 15; // Maximum distance for interpolation\nlet isdraggingOpacity = false;\n\n\nfunction getSvgCoordinates(event) {\n const rect = svg.getBoundingClientRect();\n const scaleX = currentViewBox.width / rect.width;\n const scaleY = currentViewBox.height / rect.height;\n\n const svgX = currentViewBox.x + (event.clientX - rect.left) * scaleX;\n const svgY = currentViewBox.y + (event.clientY - rect.top) * scaleY;\n\n return { x: svgX, y: svgY };\n}\n\nfunction getSvgPathFromStroke(stroke) {\n if (!stroke.length) return '';\n \n // Use more sophisticated curve fitting\n const pathData = [];\n pathData.push('M', stroke[0][0], stroke[0][1]);\n \n for (let i = 1; i < stroke.length - 1; i++) {\n const curr = stroke[i];\n const next = stroke[i + 1];\n \n // Calculate control points for smoother curves\n const cpX = curr[0] + (next[0] - curr[0]) * 0.5;\n const cpY = curr[1] + (next[1] - curr[1]) * 0.5;\n \n pathData.push('Q', curr[0], curr[1], cpX, cpY);\n }\n \n // Add final point\n if (stroke.length > 1) {\n const lastPoint = stroke[stroke.length - 1];\n pathData.push('L', lastPoint[0], lastPoint[1]);\n }\n \n return pathData.join(' ');\n}\n\n// Frame containment check for a freehand stroke during drag.\n// Lives here (not in FreehandStroke.js) because it needs isDraggingStroke & hoveredFrameStroke.\nfunction updateFrameContainmentForStroke(shape) {\n if (shape.isBeingMovedByFrame) return;\n\n let targetFrame = null;\n shapes.forEach(s => {\n if (s.shapeName === 'frame' && s.isShapeInFrame(shape)) {\n targetFrame = s;\n }\n });\n\n if (shape.parentFrame && isDraggingStroke) {\n shape.parentFrame.temporarilyRemoveFromFrame(shape);\n }\n\n if (hoveredFrameStroke && hoveredFrameStroke !== targetFrame) {\n hoveredFrameStroke.removeHighlight();\n }\n if (targetFrame && targetFrame !== hoveredFrameStroke) {\n targetFrame.highlightFrame();\n }\n hoveredFrameStroke = targetFrame;\n}\n\n// Delete functionality\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'freehandStroke') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'freehandStroke') {\n deleteCurrentShape();\n }\n});\n\n// Event handlers\nfunction handleMouseDown(e) {\n const { x, y } = getSvgCoordinates(e);\n \n if (isPaintToolActive) {\n isDrawingStroke = true;\n const pressure = e.pressure || 0.5;\n points = [[x, y, pressure]];\n lastPoint = [x, y, pressure];\n lastTime = Date.now();\n\n currentStroke = new FreehandStroke(points, {\n stroke: strokeColor ?? getThemeStroke(),\n strokeWidth: strokeThickness\n });\n\n shapes.push(currentStroke);\n currentShape = currentStroke;\n } else if (isSelectionToolActive) {\n let clickedOnShape = false;\n \n // Check if clicking on current selected stroke\n if (currentShape && currentShape.shapeName === 'freehandStroke' && currentShape.isSelected) {\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo) {\n if (anchorInfo.type === 'resize') {\n isResizingStroke = true;\n resizingAnchorIndex = anchorInfo.index;\n dragOldPosStroke = cloneStrokeData(currentShape);\n } else if (anchorInfo.type === 'rotate') {\n isRotatingStroke = true;\n const centerX = currentShape.boundingBox.x + currentShape.boundingBox.width / 2;\n const centerY = currentShape.boundingBox.y + currentShape.boundingBox.height / 2;\n startRotationMouseAngle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;\n startShapeRotation = currentShape.rotation;\n dragOldPosStroke = cloneStrokeData(currentShape);\n }\n clickedOnShape = true;\n } else if (currentShape.contains(x, y)) {\n isDraggingStroke = true;\n dragOldPosStroke = cloneStrokeData(currentShape);\n \n // Store initial frame state\n draggedShapeInitialFrameStroke = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n clickedOnShape = true;\n }\n }\n\n // If not clicking on selected shape, check for other shapes\n if (!clickedOnShape) {\n let shapeToSelect = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof FreehandStroke && shape.contains(x, y)) {\n shapeToSelect = shape;\n break;\n }\n }\n\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.deselectStroke();\n currentShape = null;\n }\n\n if (shapeToSelect) {\n currentShape = shapeToSelect;\n currentShape.selectStroke(); // This will show the sidebar\n \n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo) {\n if (anchorInfo.type === 'resize') {\n isResizingStroke = true;\n resizingAnchorIndex = anchorInfo.index;\n dragOldPosStroke = cloneStrokeData(currentShape);\n } else if (anchorInfo.type === 'rotate') {\n isRotatingStroke = true;\n const centerX = currentShape.boundingBox.x + currentShape.boundingBox.width / 2;\n const centerY = currentShape.boundingBox.y + currentShape.boundingBox.height / 2;\n startRotationMouseAngle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;\n startShapeRotation = currentShape.rotation;\n dragOldPosStroke = cloneStrokeData(currentShape);\n }\n } else {\n isDraggingStroke = true;\n dragOldPosStroke = cloneStrokeData(currentShape);\n \n // Store initial frame state\n draggedShapeInitialFrameStroke = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n }\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape && currentShape) {\n currentShape.deselectStroke();\n currentShape = null;\n disableAllSideBars(); // Hide sidebar when deselecting\n }\n }\n}\n\nfunction handleMouseMove(e) {\n let { x, y } = getSvgCoordinates(e);\n const currentTime = Date.now();\n \n // Keep lastMousePos in screen coordinates for other functions\n const svgRect = svg.getBoundingClientRect();\n lastMousePos = {\n x: e.clientX - svgRect.left, \n y: e.clientY - svgRect.top\n };\n \n if (isDrawingStroke && isPaintToolActive) {\n const pressure = e.pressure || 0.5;\n\n // Shift key constrains to straight line from start point\n if (e.shiftKey && points.length > 0) {\n const startX = points[0][0], startY = points[0][1];\n const dx = x - startX, dy = y - startY;\n const angle = Math.atan2(dy, dx);\n const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);\n const dist = Math.sqrt(dx * dx + dy * dy);\n x = startX + dist * Math.cos(snapAngle);\n y = startY + dist * Math.sin(snapAngle);\n // Reset points to just start + current for straight line\n points = [points[0], [x, y, pressure]];\n lastPoint = [x, y, pressure];\n currentStroke.points = points;\n currentStroke.draw();\n return;\n }\n\n if (lastPoint) {\n const dx = x - lastPoint[0];\n const dy = y - lastPoint[1];\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n // Only add point if it's far enough from the last one\n if (distance >= minDistance) {\n // If distance is too large, interpolate points\n if (distance > maxDistance) {\n const steps = Math.ceil(distance / maxDistance);\n for (let i = 1; i < steps; i++) {\n const t = i / steps;\n const interpX = lastPoint[0] + dx * t;\n const interpY = lastPoint[1] + dy * t;\n const interpPressure = lastPoint[2] + (pressure - lastPoint[2]) * t;\n points.push([interpX, interpY, interpPressure]);\n }\n }\n \n // Calculate velocity-based pressure\n const timeDelta = currentTime - lastTime;\n const velocity = distance / Math.max(timeDelta, 1);\n const velocityPressure = Math.min(1, Math.max(0.1, 1 - velocity * 0.02));\n const finalPressure = (pressure + velocityPressure) * 0.5;\n \n points.push([x, y, finalPressure]);\n currentStroke.points = points;\n currentStroke.draw();\n \n lastPoint = [x, y, finalPressure];\n lastTime = currentTime;\n }\n } else {\n lastPoint = [x, y, pressure];\n lastTime = currentTime;\n }\n \n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentStroke)) {\n frame.highlightFrame();\n hoveredFrameStroke = frame;\n } else if (hoveredFrameStroke === frame) {\n frame.removeHighlight();\n hoveredFrameStroke = null;\n }\n }\n });\n } else if (isDraggingStroke && currentShape && currentShape.isSelected) {\n const dx = x - startX;\n const dy = y - startY;\n currentShape.move(dx, dy);\n startX = x;\n startY = y;\n\n // Frame containment update (must live here where isDraggingStroke is in scope)\n if (!currentShape.isBeingMovedByFrame) {\n updateFrameContainmentForStroke(currentShape);\n }\n\n // Update arrows attached to this shape\n currentShape.updateAttachedArrows();\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n } else if (isResizingStroke && currentShape && currentShape.isSelected) {\n currentShape.updatePosition(resizingAnchorIndex, x, y);\n } else if (isRotatingStroke && currentShape && currentShape.isSelected) {\n const centerX = currentShape.boundingBox.x + currentShape.boundingBox.width / 2;\n const centerY = currentShape.boundingBox.y + currentShape.boundingBox.height / 2;\n const currentMouseAngle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;\n const angleDiff = currentMouseAngle - startRotationMouseAngle;\n currentShape.rotate(startShapeRotation + angleDiff);\n currentShape.draw();\n }\n}\n\nfunction handleMouseUp(e) {\n if (isDrawingStroke) {\n isDrawingStroke = false;\n lastPoint = null;\n \n // Final smoothing pass after drawing is complete\n if (currentStroke && currentStroke.points.length >= 2) {\n currentStroke.draw(); // Redraw with final smoothing\n pushCreateAction(currentStroke);\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameStroke;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentStroke);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentStroke, 'attach', null);\n }\n\n // Auto-select the drawn stroke and switch to selection tool\n const drawnShape = currentStroke;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnShape;\n currentShape.selectStroke();\n } else if (currentStroke) {\n // Remove strokes that are too small\n shapes.pop();\n if (currentStroke.group.parentNode) {\n currentStroke.group.parentNode.removeChild(currentStroke.group);\n }\n }\n\n // Clear frame highlighting\n if (hoveredFrameStroke) {\n hoveredFrameStroke.removeHighlight();\n hoveredFrameStroke = null;\n }\n\n currentStroke = null;\n }\n \n if ((isDraggingStroke || isResizingStroke || isRotatingStroke) && dragOldPosStroke && currentShape) {\n const newPos = cloneStrokeData(currentShape);\n const stateChanged = \n JSON.stringify(dragOldPosStroke.points) !== JSON.stringify(newPos.points) ||\n dragOldPosStroke.rotation !== newPos.rotation;\n \n const oldPos = {\n ...dragOldPosStroke,\n parentFrame: draggedShapeInitialFrameStroke\n };\n // Issue #34 bug #2: for drag, hoveredFrameStroke is the actual\n // destination \u2014 currentShape.parentFrame at this point is still\n // the OLD frame. Resize / rotate don't track hover, fall back to\n // the shape's own parent.\n const newPosForUndo = {\n ...newPos,\n parentFrame: isDraggingStroke\n ? (hoveredFrameStroke || null)\n : currentShape.parentFrame,\n };\n \n const frameChanged = oldPos.parentFrame !== newPosForUndo.parentFrame;\n \n if (stateChanged || frameChanged) {\n pushTransformAction(currentShape, oldPos, newPosForUndo);\n }\n \n // Handle frame containment changes after drag\n if (isDraggingStroke) {\n const finalFrame = hoveredFrameStroke;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameStroke !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameStroke) {\n draggedShapeInitialFrameStroke.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameStroke, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameStroke);\n }\n } else if (draggedShapeInitialFrameStroke) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameStroke.restoreToFrame(currentShape);\n }\n }\n \n dragOldPosStroke = null;\n draggedShapeInitialFrameStroke = null;\n }\n \n // Clear frame highlighting\n if (hoveredFrameStroke) {\n hoveredFrameStroke.removeHighlight();\n hoveredFrameStroke = null;\n }\n \n // Bake accumulated move offset into point coordinates\n if (currentShape && typeof currentShape.finalizeMove === 'function') {\n currentShape.finalizeMove();\n }\n clearSnapGuides();\n isDraggingStroke = false;\n isResizingStroke = false;\n isRotatingStroke = false;\n resizingAnchorIndex = null;\n startRotationMouseAngle = null;\n startShapeRotation = null;\n svg.style.cursor = 'default';\n}\n\n// Color and thickness selection\nstrokeColors.forEach(span => {\n span.addEventListener(\"click\", (event) => {\n strokeColors.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.stroke = span.getAttribute(\"data-id\");\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeColor = span.getAttribute(\"data-id\");\n }\n });\n});\n\nstrokeThicknesses.forEach(span => {\n span.addEventListener(\"click\", (event) => {\n strokeThicknesses.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeWidth = parseInt(span.getAttribute(\"data-id\"));\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeThickness = parseInt(span.getAttribute(\"data-id\"));\n }\n });\n});\n\n\nstrokeStyles.forEach(span => {\n span.addEventListener(\"click\", () => {\n strokeStyles.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const val = span.getAttribute(\"data-id\");\n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeStyle = val;\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeStyleValue = val;\n }\n });\n});\n\nstrokeTapers.forEach(span => {\n span.addEventListener(\"click\", () => {\n strokeTapers.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const val = parseFloat(span.getAttribute(\"data-id\"));\n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.thinning = val;\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeThinning = val;\n }\n });\n});\n\nstrokeRoughnesses.forEach(span => {\n span.addEventListener(\"click\", () => {\n strokeRoughnesses.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const val = span.getAttribute(\"data-id\");\n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.roughness = val;\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeRoughnessValue = val;\n }\n });\n});\n\ndocument.getElementById(\"strokeOpacity\")?.addEventListener(\"mousedown\", (event) => {\n isdraggingOpacity = true;\n});\n\ndocument.getElementById(\"strokeOpacity\")?.addEventListener(\"mousemove\", (event) => {\n if(isdraggingOpacity) \n {\n const slider = document.getElementById(\"strokeOpacity\");\n const rect = slider.getBoundingClientRect();\n const mouseX = event.clientX - rect.left;\n const percent = Math.max(0, Math.min(100, (mouseX / rect.width) * 100));\n document.getElementById(\"opacityContainerValue\").textContent = percent.toFixed(0);\n const opacity = percent / 100; \n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeOpacity = opacity; \n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeOpacity = opacity; \n }\n }\n});\n\ndocument.getElementById(\"strokeOpacity\")?.addEventListener(\"mouseup\", (event) => {\n isdraggingOpacity = false;\n});\n\nfunction cloneOptions(options) {\n return JSON.parse(JSON.stringify(options));\n}\n\nfunction cloneStrokeData(stroke) {\n return {\n points: JSON.parse(JSON.stringify(stroke.points)),\n rotation: stroke.rotation,\n options: cloneOptions(stroke.options)\n };\n}\n\n// Event listeners\n// svg.addEventListener('pointerdown', handleMouseDown);\n// svg.addEventListener('pointermove', handleMouseMove);\n// svg.addEventListener('pointerup', handleMouseUp);\n\n// Bridge freehand tool settings to React sidebar\nwindow.freehandToolSettings = {\n get strokeColor() { return strokeColor; },\n set strokeColor(v) { strokeColor = v; },\n get strokeWidth() { return strokeThickness; },\n set strokeWidth(v) { strokeThickness = v; },\n get strokeStyle() { return strokeStyleValue; },\n set strokeStyle(v) { strokeStyleValue = v; },\n get thinning() { return strokeThinning; },\n set thinning(v) { strokeThinning = v; },\n get roughness() { return strokeRoughnessValue; },\n set roughness(v) { strokeRoughnessValue = v; },\n get opacity() { return strokeOpacity; },\n set opacity(v) { strokeOpacity = v; },\n};\nwindow.updateSelectedFreehandStyle = function(changes) {\n if (currentShape && currentShape.shapeName === 'freehandStroke' && currentShape.isSelected) {\n if (changes.stroke !== undefined) { strokeColor = changes.stroke; currentShape.options.stroke = changes.stroke; }\n if (changes.strokeWidth !== undefined) { strokeThickness = changes.strokeWidth; currentShape.options.strokeWidth = changes.strokeWidth; }\n if (changes.thinning !== undefined) { strokeThinning = changes.thinning; currentShape.options.thinning = changes.thinning; }\n if (changes.roughness !== undefined) { strokeRoughnessValue = changes.roughness; currentShape.options.roughness = changes.roughness; }\n if (changes.opacity !== undefined) { strokeOpacity = changes.opacity; currentShape.options.strokeOpacity = changes.opacity; }\n currentShape.draw();\n } else {\n if (changes.stroke !== undefined) strokeColor = changes.stroke;\n if (changes.strokeWidth !== undefined) strokeThickness = changes.strokeWidth;\n if (changes.thinning !== undefined) strokeThinning = changes.thinning;\n if (changes.roughness !== undefined) strokeRoughnessValue = changes.roughness;\n if (changes.opacity !== undefined) strokeOpacity = changes.opacity;\n }\n};\n\n// Safety net: if mouseup fires outside the SVG canvas (e.g. on toolbar/overlay),\n// ensure we stop drawing so the stroke doesn't continue when pointer re-enters.\nwindow.addEventListener('pointerup', () => {\n if (isDrawingStroke) {\n isDrawingStroke = false;\n lastPoint = null;\n if (currentStroke && currentStroke.points && currentStroke.points.length >= 2) {\n currentStroke.draw();\n }\n currentStroke = null;\n }\n});\n\n// Also listen for visibility change (e.g. alt-tab while drawing)\ndocument.addEventListener('visibilitychange', () => {\n if (document.hidden && isDrawingStroke) {\n isDrawingStroke = false;\n lastPoint = null;\n currentStroke = null;\n }\n});\n\nexport\n{\n handleMouseDown as handleFreehandMouseDown,\n handleMouseMove as handleFreehandMouseMove,\n handleMouseUp as handleFreehandMouseUp,\n}\n"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable */\n// Freehand tool event handlers - extracted from canvasStroke.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { updateAttachedArrows as updateArrowsForShape, cleanupAttachments } from './arrowTool.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#000000\"; }\n\n// Expose updateArrowsForShape globally so FreehandStroke.updateAttachedArrows() can call it\n// (FreehandStroke.js is a separate module and cannot import freehandTool's local bindings)\nwindow.__updateArrowsForShape = updateArrowsForShape;\n\nconst strokeColors = document.querySelectorAll(\".strokeColors span\");\nconst strokeThicknesses = document.querySelectorAll(\".strokeThickness span\");\nconst strokeStyles = document.querySelectorAll(\".strokeStyleSpan\");\nconst strokeTapers = document.querySelectorAll(\".strokeTaperSpan\");\nconst strokeRoughnesses = document.querySelectorAll(\".strokeRoughnessSpan\");\nlet strokeColor = null;\nlet strokeThickness = 2;\nlet strokeStyleValue = \"solid\";\nlet strokeThinning = 0;\nlet strokeRoughnessValue = \"smooth\";\nlet points = [];\nlet isDrawingStroke = false;\nlet currentStroke = null;\nlet strokeOpacity = 1;\n\n\nlet isDraggingStroke = false;\nlet isResizingStroke = false;\nlet isRotatingStroke = false;\nlet dragOldPosStroke = null;\nlet resizingAnchorIndex = null;\nlet startRotationMouseAngle = null;\nlet startShapeRotation = null;\nlet startX, startY;\n\n// Frame attachment variables\nlet draggedShapeInitialFrameStroke = null;\nlet hoveredFrameStroke = null;\n\n// Enhanced mouse tracking with better point collection\nlet lastPoint = null;\nlet lastTime = 0;\nconst minDistance = 2; // Minimum distance between points\nconst maxDistance = 15; // Maximum distance for interpolation\nlet isdraggingOpacity = false;\n\n\nfunction getSvgCoordinates(event) {\n const rect = svg.getBoundingClientRect();\n const scaleX = currentViewBox.width / rect.width;\n const scaleY = currentViewBox.height / rect.height;\n\n const svgX = currentViewBox.x + (event.clientX - rect.left) * scaleX;\n const svgY = currentViewBox.y + (event.clientY - rect.top) * scaleY;\n\n return { x: svgX, y: svgY };\n}\n\nfunction getSvgPathFromStroke(stroke) {\n if (!stroke.length) return '';\n \n // Use more sophisticated curve fitting\n const pathData = [];\n pathData.push('M', stroke[0][0], stroke[0][1]);\n \n for (let i = 1; i < stroke.length - 1; i++) {\n const curr = stroke[i];\n const next = stroke[i + 1];\n \n // Calculate control points for smoother curves\n const cpX = curr[0] + (next[0] - curr[0]) * 0.5;\n const cpY = curr[1] + (next[1] - curr[1]) * 0.5;\n \n pathData.push('Q', curr[0], curr[1], cpX, cpY);\n }\n \n // Add final point\n if (stroke.length > 1) {\n const lastPoint = stroke[stroke.length - 1];\n pathData.push('L', lastPoint[0], lastPoint[1]);\n }\n \n return pathData.join(' ');\n}\n\n// Frame containment check for a freehand stroke during drag.\n// Lives here (not in FreehandStroke.js) because it needs isDraggingStroke & hoveredFrameStroke.\nfunction updateFrameContainmentForStroke(shape) {\n if (shape.isBeingMovedByFrame) return;\n\n let targetFrame = null;\n shapes.forEach(s => {\n if (s.shapeName === 'frame' && s.isShapeInFrame(shape)) {\n targetFrame = s;\n }\n });\n\n if (shape.parentFrame && isDraggingStroke) {\n shape.parentFrame.temporarilyRemoveFromFrame(shape);\n }\n\n if (hoveredFrameStroke && hoveredFrameStroke !== targetFrame) {\n hoveredFrameStroke.removeHighlight();\n }\n if (targetFrame && targetFrame !== hoveredFrameStroke) {\n targetFrame.highlightFrame();\n }\n hoveredFrameStroke = targetFrame;\n}\n\n// Delete functionality\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'freehandStroke') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'freehandStroke') {\n deleteCurrentShape();\n }\n});\n\n// Event handlers\nfunction handleMouseDown(e) {\n const { x, y } = getSvgCoordinates(e);\n \n if (isPaintToolActive) {\n isDrawingStroke = true;\n const pressure = e.pressure || 0.5;\n points = [[x, y, pressure]];\n lastPoint = [x, y, pressure];\n lastTime = Date.now();\n\n currentStroke = new FreehandStroke(points, {\n stroke: strokeColor ?? getThemeStroke(),\n strokeWidth: strokeThickness\n });\n\n shapes.push(currentStroke);\n currentShape = currentStroke;\n } else if (isSelectionToolActive) {\n let clickedOnShape = false;\n \n // Check if clicking on current selected stroke\n if (currentShape && currentShape.shapeName === 'freehandStroke' && currentShape.isSelected) {\n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo) {\n if (anchorInfo.type === 'resize') {\n isResizingStroke = true;\n resizingAnchorIndex = anchorInfo.index;\n dragOldPosStroke = cloneStrokeData(currentShape);\n } else if (anchorInfo.type === 'rotate') {\n isRotatingStroke = true;\n const centerX = currentShape.boundingBox.x + currentShape.boundingBox.width / 2;\n const centerY = currentShape.boundingBox.y + currentShape.boundingBox.height / 2;\n startRotationMouseAngle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;\n startShapeRotation = currentShape.rotation;\n dragOldPosStroke = cloneStrokeData(currentShape);\n }\n clickedOnShape = true;\n } else if (currentShape.contains(x, y)) {\n isDraggingStroke = true;\n dragOldPosStroke = cloneStrokeData(currentShape);\n \n // Store initial frame state\n draggedShapeInitialFrameStroke = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n clickedOnShape = true;\n }\n }\n\n // If not clicking on selected shape, check for other shapes\n if (!clickedOnShape) {\n let shapeToSelect = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof FreehandStroke && shape.contains(x, y)) {\n shapeToSelect = shape;\n break;\n }\n }\n\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.deselectStroke();\n currentShape = null;\n }\n\n if (shapeToSelect) {\n currentShape = shapeToSelect;\n currentShape.selectStroke(); // This will show the sidebar\n \n const anchorInfo = currentShape.isNearAnchor(x, y);\n if (anchorInfo) {\n if (anchorInfo.type === 'resize') {\n isResizingStroke = true;\n resizingAnchorIndex = anchorInfo.index;\n dragOldPosStroke = cloneStrokeData(currentShape);\n } else if (anchorInfo.type === 'rotate') {\n isRotatingStroke = true;\n const centerX = currentShape.boundingBox.x + currentShape.boundingBox.width / 2;\n const centerY = currentShape.boundingBox.y + currentShape.boundingBox.height / 2;\n startRotationMouseAngle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;\n startShapeRotation = currentShape.rotation;\n dragOldPosStroke = cloneStrokeData(currentShape);\n }\n } else {\n isDraggingStroke = true;\n dragOldPosStroke = cloneStrokeData(currentShape);\n \n // Store initial frame state\n draggedShapeInitialFrameStroke = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n }\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape && currentShape) {\n currentShape.deselectStroke();\n currentShape = null;\n disableAllSideBars(); // Hide sidebar when deselecting\n }\n }\n}\n\nfunction handleMouseMove(e) {\n let { x, y } = getSvgCoordinates(e);\n const currentTime = Date.now();\n \n // Keep lastMousePos in screen coordinates for other functions\n const svgRect = svg.getBoundingClientRect();\n lastMousePos = {\n x: e.clientX - svgRect.left, \n y: e.clientY - svgRect.top\n };\n \n if (isDrawingStroke && isPaintToolActive) {\n const pressure = e.pressure || 0.5;\n\n // Shift key constrains to straight line from start point\n if (e.shiftKey && points.length > 0) {\n const startX = points[0][0], startY = points[0][1];\n const dx = x - startX, dy = y - startY;\n const angle = Math.atan2(dy, dx);\n const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);\n const dist = Math.sqrt(dx * dx + dy * dy);\n x = startX + dist * Math.cos(snapAngle);\n y = startY + dist * Math.sin(snapAngle);\n // Reset points to just start + current for straight line\n points = [points[0], [x, y, pressure]];\n lastPoint = [x, y, pressure];\n currentStroke.points = points;\n currentStroke.draw();\n return;\n }\n\n if (lastPoint) {\n const dx = x - lastPoint[0];\n const dy = y - lastPoint[1];\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n // Only add point if it's far enough from the last one\n if (distance >= minDistance) {\n // If distance is too large, interpolate points\n if (distance > maxDistance) {\n const steps = Math.ceil(distance / maxDistance);\n for (let i = 1; i < steps; i++) {\n const t = i / steps;\n const interpX = lastPoint[0] + dx * t;\n const interpY = lastPoint[1] + dy * t;\n const interpPressure = lastPoint[2] + (pressure - lastPoint[2]) * t;\n points.push([interpX, interpY, interpPressure]);\n }\n }\n \n // Calculate velocity-based pressure\n const timeDelta = currentTime - lastTime;\n const velocity = distance / Math.max(timeDelta, 1);\n const velocityPressure = Math.min(1, Math.max(0.1, 1 - velocity * 0.02));\n const finalPressure = (pressure + velocityPressure) * 0.5;\n \n points.push([x, y, finalPressure]);\n currentStroke.points = points;\n currentStroke.draw();\n \n lastPoint = [x, y, finalPressure];\n lastTime = currentTime;\n }\n } else {\n lastPoint = [x, y, pressure];\n lastTime = currentTime;\n }\n \n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentStroke)) {\n frame.highlightFrame();\n hoveredFrameStroke = frame;\n } else if (hoveredFrameStroke === frame) {\n frame.removeHighlight();\n hoveredFrameStroke = null;\n }\n }\n });\n } else if (isDraggingStroke && currentShape && currentShape.isSelected) {\n const dx = x - startX;\n const dy = y - startY;\n currentShape.move(dx, dy);\n startX = x;\n startY = y;\n\n // Frame containment update (must live here where isDraggingStroke is in scope)\n if (!currentShape.isBeingMovedByFrame) {\n updateFrameContainmentForStroke(currentShape);\n }\n\n // Update arrows attached to this shape\n currentShape.updateAttachedArrows();\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n } else if (isResizingStroke && currentShape && currentShape.isSelected) {\n currentShape.updatePosition(resizingAnchorIndex, x, y);\n } else if (isRotatingStroke && currentShape && currentShape.isSelected) {\n const centerX = currentShape.boundingBox.x + currentShape.boundingBox.width / 2;\n const centerY = currentShape.boundingBox.y + currentShape.boundingBox.height / 2;\n const currentMouseAngle = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI;\n const angleDiff = currentMouseAngle - startRotationMouseAngle;\n currentShape.rotate(startShapeRotation + angleDiff);\n currentShape.draw();\n }\n}\n\nfunction handleMouseUp(e) {\n if (isDrawingStroke) {\n isDrawingStroke = false;\n lastPoint = null;\n \n // Final smoothing pass after drawing is complete\n if (currentStroke && currentStroke.points.length >= 2) {\n currentStroke.draw(); // Redraw with final smoothing\n pushCreateAction(currentStroke);\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameStroke;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentStroke);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentStroke, 'attach', null);\n }\n\n // Auto-select the drawn stroke and switch to selection tool\n const drawnShape = currentStroke;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnShape;\n currentShape.selectStroke();\n } else if (currentStroke) {\n // Remove strokes that are too small\n shapes.pop();\n if (currentStroke.group.parentNode) {\n currentStroke.group.parentNode.removeChild(currentStroke.group);\n }\n }\n\n // Clear frame highlighting\n if (hoveredFrameStroke) {\n hoveredFrameStroke.removeHighlight();\n hoveredFrameStroke = null;\n }\n\n currentStroke = null;\n }\n \n if ((isDraggingStroke || isResizingStroke || isRotatingStroke) && dragOldPosStroke && currentShape) {\n const newPos = cloneStrokeData(currentShape);\n const stateChanged = \n JSON.stringify(dragOldPosStroke.points) !== JSON.stringify(newPos.points) ||\n dragOldPosStroke.rotation !== newPos.rotation;\n \n const oldPos = {\n ...dragOldPosStroke,\n parentFrame: draggedShapeInitialFrameStroke\n };\n // Issue #34 bug #2: for drag, hoveredFrameStroke is the actual\n // destination \u2014 currentShape.parentFrame at this point is still\n // the OLD frame. Resize / rotate don't track hover, fall back to\n // the shape's own parent.\n const newPosForUndo = {\n ...newPos,\n parentFrame: isDraggingStroke\n ? (hoveredFrameStroke || null)\n : currentShape.parentFrame,\n };\n \n const frameChanged = oldPos.parentFrame !== newPosForUndo.parentFrame;\n \n if (stateChanged || frameChanged) {\n pushTransformAction(currentShape, oldPos, newPosForUndo);\n }\n \n // Handle frame containment changes after drag\n if (isDraggingStroke) {\n const finalFrame = hoveredFrameStroke;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameStroke !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameStroke) {\n draggedShapeInitialFrameStroke.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameStroke, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameStroke);\n }\n } else if (draggedShapeInitialFrameStroke) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameStroke.restoreToFrame(currentShape);\n }\n }\n \n dragOldPosStroke = null;\n draggedShapeInitialFrameStroke = null;\n }\n \n // Clear frame highlighting\n if (hoveredFrameStroke) {\n hoveredFrameStroke.removeHighlight();\n hoveredFrameStroke = null;\n }\n \n // Bake accumulated move offset into point coordinates\n if (currentShape && typeof currentShape.finalizeMove === 'function') {\n currentShape.finalizeMove();\n }\n clearSnapGuides();\n isDraggingStroke = false;\n isResizingStroke = false;\n isRotatingStroke = false;\n resizingAnchorIndex = null;\n startRotationMouseAngle = null;\n startShapeRotation = null;\n svg.style.cursor = 'default';\n}\n\n// Color and thickness selection\nstrokeColors.forEach(span => {\n span.addEventListener(\"click\", (event) => {\n strokeColors.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.stroke = span.getAttribute(\"data-id\");\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeColor = span.getAttribute(\"data-id\");\n }\n });\n});\n\nstrokeThicknesses.forEach(span => {\n span.addEventListener(\"click\", (event) => {\n strokeThicknesses.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeWidth = parseInt(span.getAttribute(\"data-id\"));\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeThickness = parseInt(span.getAttribute(\"data-id\"));\n }\n });\n});\n\n\nstrokeStyles.forEach(span => {\n span.addEventListener(\"click\", () => {\n strokeStyles.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const val = span.getAttribute(\"data-id\");\n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeStyle = val;\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeStyleValue = val;\n }\n });\n});\n\nstrokeTapers.forEach(span => {\n span.addEventListener(\"click\", () => {\n strokeTapers.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const val = parseFloat(span.getAttribute(\"data-id\"));\n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.thinning = val;\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeThinning = val;\n }\n });\n});\n\nstrokeRoughnesses.forEach(span => {\n span.addEventListener(\"click\", () => {\n strokeRoughnesses.forEach(el => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n const val = span.getAttribute(\"data-id\");\n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.roughness = val;\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeRoughnessValue = val;\n }\n });\n});\n\ndocument.getElementById(\"strokeOpacity\")?.addEventListener(\"mousedown\", (event) => {\n isdraggingOpacity = true;\n});\n\ndocument.getElementById(\"strokeOpacity\")?.addEventListener(\"mousemove\", (event) => {\n if(isdraggingOpacity) \n {\n const slider = document.getElementById(\"strokeOpacity\");\n const rect = slider.getBoundingClientRect();\n const mouseX = event.clientX - rect.left;\n const percent = Math.max(0, Math.min(100, (mouseX / rect.width) * 100));\n document.getElementById(\"opacityContainerValue\").textContent = percent.toFixed(0);\n const opacity = percent / 100; \n if (currentShape instanceof FreehandStroke && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeOpacity = opacity; \n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n strokeOpacity = opacity; \n }\n }\n});\n\ndocument.getElementById(\"strokeOpacity\")?.addEventListener(\"mouseup\", (event) => {\n isdraggingOpacity = false;\n});\n\nfunction cloneOptions(options) {\n return JSON.parse(JSON.stringify(options));\n}\n\nfunction cloneStrokeData(stroke) {\n return {\n points: JSON.parse(JSON.stringify(stroke.points)),\n rotation: stroke.rotation,\n options: cloneOptions(stroke.options)\n };\n}\n\n// Event listeners\n// svg.addEventListener('pointerdown', handleMouseDown);\n// svg.addEventListener('pointermove', handleMouseMove);\n// svg.addEventListener('pointerup', handleMouseUp);\n\n// Bridge freehand tool settings to React sidebar\nwindow.freehandToolSettings = {\n get strokeColor() { return strokeColor; },\n set strokeColor(v) { strokeColor = v; },\n get strokeWidth() { return strokeThickness; },\n set strokeWidth(v) { strokeThickness = v; },\n get strokeStyle() { return strokeStyleValue; },\n set strokeStyle(v) { strokeStyleValue = v; },\n get thinning() { return strokeThinning; },\n set thinning(v) { strokeThinning = v; },\n get roughness() { return strokeRoughnessValue; },\n set roughness(v) { strokeRoughnessValue = v; },\n get opacity() { return strokeOpacity; },\n set opacity(v) { strokeOpacity = v; },\n};\nwindow.updateSelectedFreehandStyle = function(changes) {\n if (currentShape && currentShape.shapeName === 'freehandStroke' && currentShape.isSelected) {\n if (changes.stroke !== undefined) { strokeColor = changes.stroke; currentShape.options.stroke = changes.stroke; }\n if (changes.strokeWidth !== undefined) { strokeThickness = changes.strokeWidth; currentShape.options.strokeWidth = changes.strokeWidth; }\n if (changes.thinning !== undefined) { strokeThinning = changes.thinning; currentShape.options.thinning = changes.thinning; }\n if (changes.roughness !== undefined) { strokeRoughnessValue = changes.roughness; currentShape.options.roughness = changes.roughness; }\n if (changes.opacity !== undefined) { strokeOpacity = changes.opacity; currentShape.options.strokeOpacity = changes.opacity; }\n currentShape.draw();\n } else {\n if (changes.stroke !== undefined) strokeColor = changes.stroke;\n if (changes.strokeWidth !== undefined) strokeThickness = changes.strokeWidth;\n if (changes.thinning !== undefined) strokeThinning = changes.thinning;\n if (changes.roughness !== undefined) strokeRoughnessValue = changes.roughness;\n if (changes.opacity !== undefined) strokeOpacity = changes.opacity;\n }\n};\n\n// Safety net: if mouseup fires outside the SVG canvas (e.g. on toolbar/overlay),\n// ensure we stop drawing so the stroke doesn't continue when pointer re-enters.\nwindow.addEventListener('pointerup', () => {\n if (isDrawingStroke) {\n isDrawingStroke = false;\n lastPoint = null;\n if (currentStroke && currentStroke.points && currentStroke.points.length >= 2) {\n currentStroke.draw();\n }\n currentStroke = null;\n }\n});\n\n// Also listen for visibility change (e.g. alt-tab while drawing)\ndocument.addEventListener('visibilitychange', () => {\n if (document.hidden && isDrawingStroke) {\n isDrawingStroke = false;\n lastPoint = null;\n currentStroke = null;\n }\n});\n\nexport\n{\n handleMouseDown as handleFreehandMouseDown,\n handleMouseMove as handleFreehandMouseMove,\n handleMouseUp as handleFreehandMouseUp,\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["startX", "startY"]
|
|
7
7
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
cleanupAttachments,
|
|
4
4
|
updateAttachedArrows
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KXLNEFN5.js";
|
|
6
6
|
|
|
7
7
|
// src/shapes/IconShape.js
|
|
8
8
|
var isDragging = false;
|
|
@@ -220,4 +220,4 @@ var IconShape = class {
|
|
|
220
220
|
export {
|
|
221
221
|
IconShape
|
|
222
222
|
};
|
|
223
|
-
//# sourceMappingURL=chunk-
|
|
223
|
+
//# sourceMappingURL=chunk-5XGQ3CMT.js.map
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
calculateSnap,
|
|
4
4
|
cleanupAttachments,
|
|
5
5
|
clearSnapGuides
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-KXLNEFN5.js";
|
|
7
7
|
import {
|
|
8
8
|
pushCreateAction,
|
|
9
9
|
pushDeleteAction,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
// src/tools/circleTool.js
|
|
16
16
|
function getThemeStroke() {
|
|
17
17
|
if (typeof document === "undefined") return "#fff";
|
|
18
|
-
return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#
|
|
18
|
+
return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#000000";
|
|
19
19
|
}
|
|
20
20
|
var isDrawingCircle = false;
|
|
21
21
|
var isDraggingShapeCircle = false;
|
|
@@ -550,4 +550,4 @@ export {
|
|
|
550
550
|
handleMouseMove,
|
|
551
551
|
handleMouseUp
|
|
552
552
|
};
|
|
553
|
-
//# sourceMappingURL=chunk-
|
|
553
|
+
//# sourceMappingURL=chunk-7NHZYKYB.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/tools/circleTool.js"],
|
|
4
|
-
"sourcesContent": ["/* eslint-disable */\n// Circle tool event handlers - extracted from drawCircle.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { cleanupAttachments } from './arrowTool.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#1a1a2e\"; }\n\nlet isDrawingCircle = false;\nlet isDraggingShapeCircle = false;\nlet isResizingShapeCircle = false;\nlet isRotatingShapeCircle = false;\nlet resizingAnchorIndexCircle = null;\n\nlet startRotationMouseAngleCircle = null;\nlet startShapeRotationCircle = null;\nconst rc = rough.svg(svg);\nlet startX, startY;\n\n\nlet circleStrokecolor = null;\nlet circleBackgroundColor = \"transparent\";\nlet circleFillStyleValue = \"none\";\nlet circleStrokeThicknes = 2;\nlet circleOutlineStyle = \"solid\";\n\nlet dragOldPosCircle = null;\nlet draggedShapeInitialFrameCircle = null;\nlet hoveredFrameCircle = null;\nlet colorOptionsCircle = document.querySelectorAll(\".circleStrokeSpan\");\nlet backgroundColorOptionsCircle = document.querySelectorAll(\".circleBackgroundSpan\");\nlet fillStyleOptionsCircle = document.querySelectorAll(\".circleFillStyleSpan\");\nlet strokeThicknessValueCircle = document.querySelectorAll(\".circleStrokeThickSpan\");\nlet outlineStyleValueCircle = document.querySelectorAll(\".circleOutlineStyle\");\n\n\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\n\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'circle') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n \n // Clean up any arrow attachments before deleting\n cleanupAttachments(currentShape);\n \n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'circle') {\n deleteCurrentShape();\n }\n});\n\nconst handleMouseDown = (e) => {\n const {x: svgMouseX, y: svgMouseY} = getSVGCoordsFromMouse(e);\n\n if(isCircleToolActive)\n {\n startX = svgMouseX;\n startY = svgMouseY;\n isDrawingCircle = true;\n\n if(currentShape) \n {\n currentShape.removeSelection();\n currentShape = null;\n disableAllSideBars();\n }\n let initialOptions = {\n stroke: circleStrokecolor ?? getThemeStroke(),\n fill: circleBackgroundColor,\n fillStyle: circleFillStyleValue,\n strokeWidth: circleStrokeThicknes,\n };\n if(circleOutlineStyle === \"dashed\") {\n initialOptions.strokeDasharray = \"5,5\";\n }\n else if(circleOutlineStyle === \"dotted\") {\n initialOptions.strokeDasharray = \"2,8\";\n } else {\n initialOptions.strokeDasharray = \"\";\n }\n\n currentShape = new Circle(startX, startY, 0, 0, initialOptions);\n }\n\n else if(isSelectionToolActive) \n {\n let clickedOnShape = false;\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected)\n {\n const anchorInfo = currentShape.isNearAnchor(svgMouseX, svgMouseY);\n if (anchorInfo) {\n dragOldPosCircle = { \n x: currentShape.x, \n y: currentShape.y, \n rx: currentShape.rx, \n ry: currentShape.ry, \n rotation: currentShape.rotation \n };\n if(anchorInfo.type === 'resize') \n {\n isResizingShapeCircle = true;\n resizingAnchorIndexCircle = anchorInfo.index;\n }\n else if(anchorInfo.type === 'rotate') \n {\n isRotatingShapeCircle = true;\n startRotationMouseAngleCircle = Math.atan2(svgMouseY - currentShape.y, svgMouseX - currentShape.x) * (180 / Math.PI);\n startShapeRotationCircle = currentShape.rotation;\n }\n clickedOnShape = true;\n }\n else if (currentShape.contains(svgMouseX, svgMouseY)) \n {\n isDraggingShapeCircle = true;\n dragOldPosCircle = { \n x: currentShape.x, \n y: currentShape.y, \n rx: currentShape.rx, \n ry: currentShape.ry, \n rotation: currentShape.rotation \n };\n \n // Store initial frame state\n draggedShapeInitialFrameCircle = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = svgMouseX;\n startY = svgMouseY;\n clickedOnShape = true;\n }\n }\n if (!clickedOnShape) \n {\n let shapeToSelect = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape.shapeName === 'circle' && shape.contains(svgMouseX, svgMouseY)) {\n shapeToSelect = shape;\n break; \n }\n }\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.removeSelection();\n currentShape = null;\n disableAllSideBars();\n }\n if(shapeToSelect)\n {\n currentShape = shapeToSelect;\n currentShape.isSelected = true;\n currentShape.draw();\n isDraggingShapeCircle = true;\n dragOldPosCircle = { \n x: currentShape.x, \n y: currentShape.y, \n rx: currentShape.rx, \n ry: currentShape.ry, \n rotation: currentShape.rotation \n };\n \n // Store initial frame state\n draggedShapeInitialFrameCircle = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = svgMouseX;\n startY = svgMouseY;\n clickedOnShape = true;\n }\n }\n if(!clickedOnShape && currentShape) {\n currentShape.removeSelection();\n currentShape = null;\n disableAllSideBars();\n }\n }\n};\n\nconst handleMouseMove = (e) => {\n\n const {x: svgMouseX, y: svgMouseY} = getSVGCoordsFromMouse(e);\n \n // Keep lastMousePos in screen coordinates for other functions\n const svgRect = svg.getBoundingClientRect();\n lastMousePos = {\n x: e.clientX - svgRect.left, \n y: e.clientY - svgRect.top\n };\n\n if(isDrawingCircle && isCircleToolActive && currentShape) \n {\n currentShape.x = (startX + svgMouseX) / 2;\n currentShape.y = (startY + svgMouseY) / 2;\n currentShape.rx = Math.abs(svgMouseX - startX) / 2;\n currentShape.ry = Math.abs(svgMouseY - startY) / 2;\n currentShape.draw();\n \n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentShape)) {\n frame.highlightFrame();\n hoveredFrameCircle = frame;\n } else if (hoveredFrameCircle === frame) {\n frame.removeHighlight();\n hoveredFrameCircle = null;\n }\n }\n });\n }\n else if (isDraggingShapeCircle && currentShape && currentShape.isSelected) {\n const dx = svgMouseX - startX;\n const dy = svgMouseY - startY;\n currentShape.move(dx, dy);\n startX = svgMouseX;\n startY = svgMouseY;\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n\n // Issue #24 bug #4: track containing frame during drag (see same\n // block in rectangleTool for the rationale).\n let newHover = null;\n for (const f of shapes) {\n if (f.shapeName !== 'frame') continue;\n if (f === currentShape) continue;\n if (typeof f.isShapeInFrame === 'function' && f.isShapeInFrame(currentShape)) {\n newHover = f;\n break;\n }\n }\n if (hoveredFrameCircle && hoveredFrameCircle !== newHover && typeof hoveredFrameCircle.removeHighlight === 'function') {\n hoveredFrameCircle.removeHighlight();\n }\n if (newHover && newHover !== hoveredFrameCircle && typeof newHover.highlightFrame === 'function') {\n newHover.highlightFrame();\n }\n hoveredFrameCircle = newHover;\n }\n \n else if(isResizingShapeCircle && currentShape && currentShape.isSelected)\n {\n currentShape.updatePosition(resizingAnchorIndexCircle, svgMouseX, svgMouseY);\n currentShape._skipAnchors = true;\n currentShape.draw();\n currentShape._skipAnchors = false;\n }\n else if (isRotatingShapeCircle && currentShape && currentShape.isSelected)\n {\n const currentMouseAngle = Math.atan2(svgMouseY - currentShape.y, svgMouseX - currentShape.x) * (180 / Math.PI);\n const angleDiff = currentMouseAngle - startRotationMouseAngleCircle;\n let newRotation = startShapeRotationCircle + angleDiff;\n const snapAngle = 15;\n if (e.shiftKey) {\n newRotation = Math.round(newRotation / snapAngle) * snapAngle;\n }\n currentShape.rotate(newRotation);\n currentShape._skipAnchors = true;\n currentShape.draw();\n currentShape._skipAnchors = false;\n svg.style.cursor = 'grabbing'; \n }\n else if (isSelectionToolActive && !isDrawingCircle && currentShape && currentShape.isSelected) \n {\n const anchorInfo = currentShape.isNearAnchor(svgMouseX, svgMouseY);\n if(anchorInfo)\n {\n if(anchorInfo.type === 'resize') {\n const baseDirection = anchorInfo.index; \n const rotatedCursor = currentShape.getRotatedCursor(baseDirection, currentShape.rotation);\n svg.style.cursor = rotatedCursor + '-resize';\n }\n else if(anchorInfo.type === 'rotate') {\n svg.style.cursor = 'grab';\n }\n }\n else if(currentShape.contains(svgMouseX, svgMouseY)) {\n svg.style.cursor = 'move';\n }\n else \n {\n svg.style.cursor = 'default';\n }\n }\n else if (isSelectionToolActive && !isDrawingCircle && !isDraggingShapeCircle && !isResizingShapeCircle && !isRotatingShapeCircle) \n {\n let hoveredShape = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape.shapeName === 'circle' && shape.contains(svgMouseX, svgMouseY)) {\n hoveredShape = shape;\n break; \n }\n }\n if (hoveredShape) {\n svg.style.cursor = 'pointer';\n } else {\n svg.style.cursor = 'default';\n }\n }\n}\n\nconst handleMouseUp = (e) => {\n if (isDrawingCircle && currentShape) {\n if(currentShape.rx === 0 && currentShape.ry === 0) {\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n currentShape = null;\n } else {\n shapes.push(currentShape);\n pushCreateAction(currentShape);\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameCircle;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentShape, 'attach', null);\n }\n\n // Auto-select the drawn shape and switch to selection tool\n const drawnShape = currentShape;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnShape;\n currentShape.isSelected = true;\n if (typeof currentShape.addAnchors === 'function') {\n currentShape.addAnchors();\n }\n }\n \n // Clear frame highlighting\n if (hoveredFrameCircle) {\n hoveredFrameCircle.removeHighlight();\n hoveredFrameCircle = null;\n }\n }\n \n if((isDraggingShapeCircle || isResizingShapeCircle || isRotatingShapeCircle) && dragOldPosCircle && currentShape) {\n // Issue #34 bug #2: see rectangleTool \u2014 record the hovered frame\n // as the destination, not the stale `parentFrame` (containment\n // transfer happens later in this handler).\n const newPos = {\n x: currentShape.x,\n y: currentShape.y,\n rx: currentShape.rx,\n ry: currentShape.ry,\n rotation: currentShape.rotation,\n parentFrame: isDraggingShapeCircle ? (hoveredFrameCircle || null) : currentShape.parentFrame,\n };\n const oldPos = {\n ...dragOldPosCircle,\n parentFrame: draggedShapeInitialFrameCircle\n };\n \n const stateChanged = oldPos.x !== newPos.x || oldPos.y !== newPos.y ||\n oldPos.rx !== newPos.rx || oldPos.ry !== newPos.ry || \n oldPos.rotation !== newPos.rotation;\n\n const frameChanged = oldPos.parentFrame !== newPos.parentFrame;\n\n if (stateChanged || frameChanged) {\n const oldPosForUndo = {\n x: oldPos.x,\n y: oldPos.y,\n rx: oldPos.rx,\n ry: oldPos.ry,\n rotation: oldPos.rotation,\n parentFrame: oldPos.parentFrame\n };\n const newPosForUndo = {\n x: newPos.x,\n y: newPos.y,\n rx: newPos.rx,\n ry: newPos.ry,\n rotation: newPos.rotation,\n parentFrame: newPos.parentFrame\n };\n pushTransformAction(currentShape, oldPosForUndo, newPosForUndo);\n }\n \n // Handle frame containment changes after drag\n if (isDraggingShapeCircle) {\n const finalFrame = hoveredFrameCircle;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameCircle !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameCircle) {\n draggedShapeInitialFrameCircle.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameCircle, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameCircle);\n }\n } else if (draggedShapeInitialFrameCircle) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameCircle.restoreToFrame(currentShape);\n }\n }\n \n dragOldPosCircle = null;\n draggedShapeInitialFrameCircle = null;\n }\n \n // Clear frame highlighting\n if (hoveredFrameCircle) {\n hoveredFrameCircle.removeHighlight();\n hoveredFrameCircle = null;\n }\n\n clearSnapGuides();\n isDrawingCircle = false;\n isDraggingShapeCircle = false;\n isResizingShapeCircle = false;\n isRotatingShapeCircle = false;\n resizingAnchorIndexCircle = null;\n startRotationMouseAngleCircle = null;\n startShapeRotationCircle = 0;\n svg.style.cursor = 'default';\n}\n\n\ncolorOptionsCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const color = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n currentShape.options.stroke = color;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleStrokecolor = this.getAttribute('data-id');\n }\n colorOptionsCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\nbackgroundColorOptionsCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const color = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n currentShape.options.fill = color;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleBackgroundColor = this.getAttribute('data-id');\n }\n backgroundColorOptionsCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\nfillStyleOptionsCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const style = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n currentShape.options.fillStyle = style;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleFillStyleValue = this.getAttribute('data-id');\n }\n fillStyleOptionsCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\nstrokeThicknessValueCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const thick = parseInt(this.getAttribute('data-id'), 10);\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeWidth = thick;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleStrokeThicknes = parseInt(this.getAttribute('data-id'), 10);\n }\n strokeThicknessValueCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\noutlineStyleValueCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const style = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n if (style === \"dashed\") {\n currentShape.options.strokeDasharray = \"5,5\";\n } else if (style === \"dotted\") {\n currentShape.options.strokeDasharray = \"2,8\";\n } else {\n currentShape.options.strokeDasharray = \"\";\n }\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleOutlineStyle = this.getAttribute('data-id');\n }\n outlineStyleValueCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\n\nwindow.Circle = Circle;\n\n// Bridge circle tool settings to React sidebar\nwindow.circleToolSettings = {\n get strokeColor() { return circleStrokecolor; },\n set strokeColor(v) { circleStrokecolor = v; },\n get bgColor() { return circleBackgroundColor; },\n set bgColor(v) { circleBackgroundColor = v; },\n get fillStyle() { return circleFillStyleValue; },\n set fillStyle(v) { circleFillStyleValue = v; },\n get strokeWidth() { return circleStrokeThicknes; },\n set strokeWidth(v) { circleStrokeThicknes = v; },\n get outlineStyle() { return circleOutlineStyle; },\n set outlineStyle(v) { circleOutlineStyle = v; },\n};\nwindow.updateSelectedCircleStyle = function(changes) {\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n pushOptionsChangeAction(currentShape, { ...currentShape.options });\n if (changes.stroke !== undefined) { circleStrokecolor = changes.stroke; currentShape.options.stroke = changes.stroke; }\n if (changes.fill !== undefined) { circleBackgroundColor = changes.fill; currentShape.options.fill = changes.fill; }\n if (changes.fillStyle !== undefined) { circleFillStyleValue = changes.fillStyle; currentShape.options.fillStyle = changes.fillStyle; }\n if (changes.strokeWidth !== undefined) { circleStrokeThicknes = changes.strokeWidth; currentShape.options.strokeWidth = changes.strokeWidth; }\n if (changes.outlineStyle !== undefined) {\n circleOutlineStyle = changes.outlineStyle;\n if (changes.outlineStyle === \"dashed\") currentShape.options.strokeDasharray = \"5,5\";\n else if (changes.outlineStyle === \"dotted\") currentShape.options.strokeDasharray = \"2,8\";\n else currentShape.options.strokeDasharray = \"\";\n }\n currentShape.draw();\n } else {\n if (changes.stroke !== undefined) circleStrokecolor = changes.stroke;\n if (changes.fill !== undefined) circleBackgroundColor = changes.fill;\n if (changes.fillStyle !== undefined) circleFillStyleValue = changes.fillStyle;\n if (changes.strokeWidth !== undefined) circleStrokeThicknes = changes.strokeWidth;\n if (changes.outlineStyle !== undefined) circleOutlineStyle = changes.outlineStyle;\n }\n};\n\nexport {\n handleMouseDown as handleMouseDownCircle,\n handleMouseMove as handleMouseMoveCircle,\n handleMouseUp as handleMouseUpCircle,\n}\n"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable */\n// Circle tool event handlers - extracted from drawCircle.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { cleanupAttachments } from './arrowTool.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#000000\"; }\n\nlet isDrawingCircle = false;\nlet isDraggingShapeCircle = false;\nlet isResizingShapeCircle = false;\nlet isRotatingShapeCircle = false;\nlet resizingAnchorIndexCircle = null;\n\nlet startRotationMouseAngleCircle = null;\nlet startShapeRotationCircle = null;\nconst rc = rough.svg(svg);\nlet startX, startY;\n\n\nlet circleStrokecolor = null;\nlet circleBackgroundColor = \"transparent\";\nlet circleFillStyleValue = \"none\";\nlet circleStrokeThicknes = 2;\nlet circleOutlineStyle = \"solid\";\n\nlet dragOldPosCircle = null;\nlet draggedShapeInitialFrameCircle = null;\nlet hoveredFrameCircle = null;\nlet colorOptionsCircle = document.querySelectorAll(\".circleStrokeSpan\");\nlet backgroundColorOptionsCircle = document.querySelectorAll(\".circleBackgroundSpan\");\nlet fillStyleOptionsCircle = document.querySelectorAll(\".circleFillStyleSpan\");\nlet strokeThicknessValueCircle = document.querySelectorAll(\".circleStrokeThickSpan\");\nlet outlineStyleValueCircle = document.querySelectorAll(\".circleOutlineStyle\");\n\n\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\n\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'circle') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n \n // Clean up any arrow attachments before deleting\n cleanupAttachments(currentShape);\n \n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'circle') {\n deleteCurrentShape();\n }\n});\n\nconst handleMouseDown = (e) => {\n const {x: svgMouseX, y: svgMouseY} = getSVGCoordsFromMouse(e);\n\n if(isCircleToolActive)\n {\n startX = svgMouseX;\n startY = svgMouseY;\n isDrawingCircle = true;\n\n if(currentShape) \n {\n currentShape.removeSelection();\n currentShape = null;\n disableAllSideBars();\n }\n let initialOptions = {\n stroke: circleStrokecolor ?? getThemeStroke(),\n fill: circleBackgroundColor,\n fillStyle: circleFillStyleValue,\n strokeWidth: circleStrokeThicknes,\n };\n if(circleOutlineStyle === \"dashed\") {\n initialOptions.strokeDasharray = \"5,5\";\n }\n else if(circleOutlineStyle === \"dotted\") {\n initialOptions.strokeDasharray = \"2,8\";\n } else {\n initialOptions.strokeDasharray = \"\";\n }\n\n currentShape = new Circle(startX, startY, 0, 0, initialOptions);\n }\n\n else if(isSelectionToolActive) \n {\n let clickedOnShape = false;\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected)\n {\n const anchorInfo = currentShape.isNearAnchor(svgMouseX, svgMouseY);\n if (anchorInfo) {\n dragOldPosCircle = { \n x: currentShape.x, \n y: currentShape.y, \n rx: currentShape.rx, \n ry: currentShape.ry, \n rotation: currentShape.rotation \n };\n if(anchorInfo.type === 'resize') \n {\n isResizingShapeCircle = true;\n resizingAnchorIndexCircle = anchorInfo.index;\n }\n else if(anchorInfo.type === 'rotate') \n {\n isRotatingShapeCircle = true;\n startRotationMouseAngleCircle = Math.atan2(svgMouseY - currentShape.y, svgMouseX - currentShape.x) * (180 / Math.PI);\n startShapeRotationCircle = currentShape.rotation;\n }\n clickedOnShape = true;\n }\n else if (currentShape.contains(svgMouseX, svgMouseY)) \n {\n isDraggingShapeCircle = true;\n dragOldPosCircle = { \n x: currentShape.x, \n y: currentShape.y, \n rx: currentShape.rx, \n ry: currentShape.ry, \n rotation: currentShape.rotation \n };\n \n // Store initial frame state\n draggedShapeInitialFrameCircle = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = svgMouseX;\n startY = svgMouseY;\n clickedOnShape = true;\n }\n }\n if (!clickedOnShape) \n {\n let shapeToSelect = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape.shapeName === 'circle' && shape.contains(svgMouseX, svgMouseY)) {\n shapeToSelect = shape;\n break; \n }\n }\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.removeSelection();\n currentShape = null;\n disableAllSideBars();\n }\n if(shapeToSelect)\n {\n currentShape = shapeToSelect;\n currentShape.isSelected = true;\n currentShape.draw();\n isDraggingShapeCircle = true;\n dragOldPosCircle = { \n x: currentShape.x, \n y: currentShape.y, \n rx: currentShape.rx, \n ry: currentShape.ry, \n rotation: currentShape.rotation \n };\n \n // Store initial frame state\n draggedShapeInitialFrameCircle = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = svgMouseX;\n startY = svgMouseY;\n clickedOnShape = true;\n }\n }\n if(!clickedOnShape && currentShape) {\n currentShape.removeSelection();\n currentShape = null;\n disableAllSideBars();\n }\n }\n};\n\nconst handleMouseMove = (e) => {\n\n const {x: svgMouseX, y: svgMouseY} = getSVGCoordsFromMouse(e);\n \n // Keep lastMousePos in screen coordinates for other functions\n const svgRect = svg.getBoundingClientRect();\n lastMousePos = {\n x: e.clientX - svgRect.left, \n y: e.clientY - svgRect.top\n };\n\n if(isDrawingCircle && isCircleToolActive && currentShape) \n {\n currentShape.x = (startX + svgMouseX) / 2;\n currentShape.y = (startY + svgMouseY) / 2;\n currentShape.rx = Math.abs(svgMouseX - startX) / 2;\n currentShape.ry = Math.abs(svgMouseY - startY) / 2;\n currentShape.draw();\n \n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentShape)) {\n frame.highlightFrame();\n hoveredFrameCircle = frame;\n } else if (hoveredFrameCircle === frame) {\n frame.removeHighlight();\n hoveredFrameCircle = null;\n }\n }\n });\n }\n else if (isDraggingShapeCircle && currentShape && currentShape.isSelected) {\n const dx = svgMouseX - startX;\n const dy = svgMouseY - startY;\n currentShape.move(dx, dy);\n startX = svgMouseX;\n startY = svgMouseY;\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n\n // Issue #24 bug #4: track containing frame during drag (see same\n // block in rectangleTool for the rationale).\n let newHover = null;\n for (const f of shapes) {\n if (f.shapeName !== 'frame') continue;\n if (f === currentShape) continue;\n if (typeof f.isShapeInFrame === 'function' && f.isShapeInFrame(currentShape)) {\n newHover = f;\n break;\n }\n }\n if (hoveredFrameCircle && hoveredFrameCircle !== newHover && typeof hoveredFrameCircle.removeHighlight === 'function') {\n hoveredFrameCircle.removeHighlight();\n }\n if (newHover && newHover !== hoveredFrameCircle && typeof newHover.highlightFrame === 'function') {\n newHover.highlightFrame();\n }\n hoveredFrameCircle = newHover;\n }\n \n else if(isResizingShapeCircle && currentShape && currentShape.isSelected)\n {\n currentShape.updatePosition(resizingAnchorIndexCircle, svgMouseX, svgMouseY);\n currentShape._skipAnchors = true;\n currentShape.draw();\n currentShape._skipAnchors = false;\n }\n else if (isRotatingShapeCircle && currentShape && currentShape.isSelected)\n {\n const currentMouseAngle = Math.atan2(svgMouseY - currentShape.y, svgMouseX - currentShape.x) * (180 / Math.PI);\n const angleDiff = currentMouseAngle - startRotationMouseAngleCircle;\n let newRotation = startShapeRotationCircle + angleDiff;\n const snapAngle = 15;\n if (e.shiftKey) {\n newRotation = Math.round(newRotation / snapAngle) * snapAngle;\n }\n currentShape.rotate(newRotation);\n currentShape._skipAnchors = true;\n currentShape.draw();\n currentShape._skipAnchors = false;\n svg.style.cursor = 'grabbing'; \n }\n else if (isSelectionToolActive && !isDrawingCircle && currentShape && currentShape.isSelected) \n {\n const anchorInfo = currentShape.isNearAnchor(svgMouseX, svgMouseY);\n if(anchorInfo)\n {\n if(anchorInfo.type === 'resize') {\n const baseDirection = anchorInfo.index; \n const rotatedCursor = currentShape.getRotatedCursor(baseDirection, currentShape.rotation);\n svg.style.cursor = rotatedCursor + '-resize';\n }\n else if(anchorInfo.type === 'rotate') {\n svg.style.cursor = 'grab';\n }\n }\n else if(currentShape.contains(svgMouseX, svgMouseY)) {\n svg.style.cursor = 'move';\n }\n else \n {\n svg.style.cursor = 'default';\n }\n }\n else if (isSelectionToolActive && !isDrawingCircle && !isDraggingShapeCircle && !isResizingShapeCircle && !isRotatingShapeCircle) \n {\n let hoveredShape = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape.shapeName === 'circle' && shape.contains(svgMouseX, svgMouseY)) {\n hoveredShape = shape;\n break; \n }\n }\n if (hoveredShape) {\n svg.style.cursor = 'pointer';\n } else {\n svg.style.cursor = 'default';\n }\n }\n}\n\nconst handleMouseUp = (e) => {\n if (isDrawingCircle && currentShape) {\n if(currentShape.rx === 0 && currentShape.ry === 0) {\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n currentShape = null;\n } else {\n shapes.push(currentShape);\n pushCreateAction(currentShape);\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameCircle;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentShape, 'attach', null);\n }\n\n // Auto-select the drawn shape and switch to selection tool\n const drawnShape = currentShape;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnShape;\n currentShape.isSelected = true;\n if (typeof currentShape.addAnchors === 'function') {\n currentShape.addAnchors();\n }\n }\n \n // Clear frame highlighting\n if (hoveredFrameCircle) {\n hoveredFrameCircle.removeHighlight();\n hoveredFrameCircle = null;\n }\n }\n \n if((isDraggingShapeCircle || isResizingShapeCircle || isRotatingShapeCircle) && dragOldPosCircle && currentShape) {\n // Issue #34 bug #2: see rectangleTool \u2014 record the hovered frame\n // as the destination, not the stale `parentFrame` (containment\n // transfer happens later in this handler).\n const newPos = {\n x: currentShape.x,\n y: currentShape.y,\n rx: currentShape.rx,\n ry: currentShape.ry,\n rotation: currentShape.rotation,\n parentFrame: isDraggingShapeCircle ? (hoveredFrameCircle || null) : currentShape.parentFrame,\n };\n const oldPos = {\n ...dragOldPosCircle,\n parentFrame: draggedShapeInitialFrameCircle\n };\n \n const stateChanged = oldPos.x !== newPos.x || oldPos.y !== newPos.y ||\n oldPos.rx !== newPos.rx || oldPos.ry !== newPos.ry || \n oldPos.rotation !== newPos.rotation;\n\n const frameChanged = oldPos.parentFrame !== newPos.parentFrame;\n\n if (stateChanged || frameChanged) {\n const oldPosForUndo = {\n x: oldPos.x,\n y: oldPos.y,\n rx: oldPos.rx,\n ry: oldPos.ry,\n rotation: oldPos.rotation,\n parentFrame: oldPos.parentFrame\n };\n const newPosForUndo = {\n x: newPos.x,\n y: newPos.y,\n rx: newPos.rx,\n ry: newPos.ry,\n rotation: newPos.rotation,\n parentFrame: newPos.parentFrame\n };\n pushTransformAction(currentShape, oldPosForUndo, newPosForUndo);\n }\n \n // Handle frame containment changes after drag\n if (isDraggingShapeCircle) {\n const finalFrame = hoveredFrameCircle;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameCircle !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameCircle) {\n draggedShapeInitialFrameCircle.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameCircle, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameCircle);\n }\n } else if (draggedShapeInitialFrameCircle) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameCircle.restoreToFrame(currentShape);\n }\n }\n \n dragOldPosCircle = null;\n draggedShapeInitialFrameCircle = null;\n }\n \n // Clear frame highlighting\n if (hoveredFrameCircle) {\n hoveredFrameCircle.removeHighlight();\n hoveredFrameCircle = null;\n }\n\n clearSnapGuides();\n isDrawingCircle = false;\n isDraggingShapeCircle = false;\n isResizingShapeCircle = false;\n isRotatingShapeCircle = false;\n resizingAnchorIndexCircle = null;\n startRotationMouseAngleCircle = null;\n startShapeRotationCircle = 0;\n svg.style.cursor = 'default';\n}\n\n\ncolorOptionsCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const color = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n currentShape.options.stroke = color;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleStrokecolor = this.getAttribute('data-id');\n }\n colorOptionsCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\nbackgroundColorOptionsCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const color = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n currentShape.options.fill = color;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleBackgroundColor = this.getAttribute('data-id');\n }\n backgroundColorOptionsCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\nfillStyleOptionsCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const style = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n currentShape.options.fillStyle = style;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleFillStyleValue = this.getAttribute('data-id');\n }\n fillStyleOptionsCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\nstrokeThicknessValueCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const thick = parseInt(this.getAttribute('data-id'), 10);\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeWidth = thick;\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleStrokeThicknes = parseInt(this.getAttribute('data-id'), 10);\n }\n strokeThicknessValueCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\noutlineStyleValueCircle.forEach(span => {\n span.addEventListener('click', function(event) {\n event.stopPropagation();\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n const style = this.getAttribute('data-id');\n const oldOptions = {...currentShape.options};\n if (style === \"dashed\") {\n currentShape.options.strokeDasharray = \"5,5\";\n } else if (style === \"dotted\") {\n currentShape.options.strokeDasharray = \"2,8\";\n } else {\n currentShape.options.strokeDasharray = \"\";\n }\n currentShape.draw();\n currentShape.updateSidebar();\n pushOptionsChangeAction(currentShape, oldOptions);\n }\n else \n {\n circleOutlineStyle = this.getAttribute('data-id');\n }\n outlineStyleValueCircle.forEach(span => {\n span.classList.remove('selected');\n });\n this.classList.add('selected');\n });\n});\n\nwindow.Circle = Circle;\n\n// Bridge circle tool settings to React sidebar\nwindow.circleToolSettings = {\n get strokeColor() { return circleStrokecolor; },\n set strokeColor(v) { circleStrokecolor = v; },\n get bgColor() { return circleBackgroundColor; },\n set bgColor(v) { circleBackgroundColor = v; },\n get fillStyle() { return circleFillStyleValue; },\n set fillStyle(v) { circleFillStyleValue = v; },\n get strokeWidth() { return circleStrokeThicknes; },\n set strokeWidth(v) { circleStrokeThicknes = v; },\n get outlineStyle() { return circleOutlineStyle; },\n set outlineStyle(v) { circleOutlineStyle = v; },\n};\nwindow.updateSelectedCircleStyle = function(changes) {\n if (currentShape && currentShape.shapeName === 'circle' && currentShape.isSelected) {\n pushOptionsChangeAction(currentShape, { ...currentShape.options });\n if (changes.stroke !== undefined) { circleStrokecolor = changes.stroke; currentShape.options.stroke = changes.stroke; }\n if (changes.fill !== undefined) { circleBackgroundColor = changes.fill; currentShape.options.fill = changes.fill; }\n if (changes.fillStyle !== undefined) { circleFillStyleValue = changes.fillStyle; currentShape.options.fillStyle = changes.fillStyle; }\n if (changes.strokeWidth !== undefined) { circleStrokeThicknes = changes.strokeWidth; currentShape.options.strokeWidth = changes.strokeWidth; }\n if (changes.outlineStyle !== undefined) {\n circleOutlineStyle = changes.outlineStyle;\n if (changes.outlineStyle === \"dashed\") currentShape.options.strokeDasharray = \"5,5\";\n else if (changes.outlineStyle === \"dotted\") currentShape.options.strokeDasharray = \"2,8\";\n else currentShape.options.strokeDasharray = \"\";\n }\n currentShape.draw();\n } else {\n if (changes.stroke !== undefined) circleStrokecolor = changes.stroke;\n if (changes.fill !== undefined) circleBackgroundColor = changes.fill;\n if (changes.fillStyle !== undefined) circleFillStyleValue = changes.fillStyle;\n if (changes.strokeWidth !== undefined) circleStrokeThicknes = changes.strokeWidth;\n if (changes.outlineStyle !== undefined) circleOutlineStyle = changes.outlineStyle;\n }\n};\n\nexport {\n handleMouseDown as handleMouseDownCircle,\n handleMouseMove as handleMouseMoveCircle,\n handleMouseUp as handleMouseUpCircle,\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["span"]
|
|
7
7
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
calculateSnap,
|
|
4
4
|
clearSnapGuides
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KXLNEFN5.js";
|
|
6
6
|
import {
|
|
7
7
|
pushCreateAction,
|
|
8
8
|
pushFrameAttachmentAction,
|
|
@@ -23,7 +23,7 @@ var startX;
|
|
|
23
23
|
var startY;
|
|
24
24
|
function getThemeStroke() {
|
|
25
25
|
if (typeof document === "undefined") return "#fff";
|
|
26
|
-
return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#
|
|
26
|
+
return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#000000";
|
|
27
27
|
}
|
|
28
28
|
var squareStrokecolor = null;
|
|
29
29
|
var squareBackgroundColor = "transparent";
|
|
@@ -500,4 +500,4 @@ export {
|
|
|
500
500
|
handleMouseMoveRect,
|
|
501
501
|
handleMouseUpRect
|
|
502
502
|
};
|
|
503
|
-
//# sourceMappingURL=chunk-
|
|
503
|
+
//# sourceMappingURL=chunk-7WXEWDRL.js.map
|