@elixpo/lixsketch 5.4.7 → 5.5.0

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.
Files changed (218) hide show
  1. package/dist/react/AIRenderer-M4LMJ66J.js +1105 -0
  2. package/dist/react/AIRenderer-M4LMJ66J.js.map +7 -0
  3. package/dist/react/Arrow-BJDAXPMH.js +8 -0
  4. package/dist/react/Arrow-BJDAXPMH.js.map +7 -0
  5. package/dist/react/Circle-KPG7TKIX.js +8 -0
  6. package/dist/react/Circle-KPG7TKIX.js.map +7 -0
  7. package/dist/react/CodeShape-K4DIZAIV.js +8 -0
  8. package/dist/react/CodeShape-K4DIZAIV.js.map +7 -0
  9. package/dist/react/CopyPaste-4CKJRHJ3.js +569 -0
  10. package/dist/react/CopyPaste-4CKJRHJ3.js.map +7 -0
  11. package/dist/react/EraserTrail-PA6IQLQN.js +20 -0
  12. package/dist/react/EraserTrail-PA6IQLQN.js.map +7 -0
  13. package/dist/react/EventDispatcher-SRFH6LQZ.js +463 -0
  14. package/dist/react/EventDispatcher-SRFH6LQZ.js.map +7 -0
  15. package/dist/react/Frame-6UR5XPAX.js +10 -0
  16. package/dist/react/Frame-6UR5XPAX.js.map +7 -0
  17. package/dist/react/FreehandStroke-CK24NUT3.js +8 -0
  18. package/dist/react/FreehandStroke-CK24NUT3.js.map +7 -0
  19. package/dist/react/GraphEngine-QE5B2PMR.js +340 -0
  20. package/dist/react/GraphEngine-QE5B2PMR.js.map +7 -0
  21. package/dist/react/GraphMathParser-2WMTY4IE.js +10 -0
  22. package/dist/react/GraphMathParser-2WMTY4IE.js.map +7 -0
  23. package/dist/react/IconShape-KMIA6T2H.js +10 -0
  24. package/dist/react/IconShape-KMIA6T2H.js.map +7 -0
  25. package/dist/react/ImageShape-CHHGBXUQ.js +10 -0
  26. package/dist/react/ImageShape-CHHGBXUQ.js.map +7 -0
  27. package/dist/react/LayerOrder-XCHF4MSS.js +66 -0
  28. package/dist/react/LayerOrder-XCHF4MSS.js.map +7 -0
  29. package/dist/react/Line-2KOQEEGA.js +10 -0
  30. package/dist/react/Line-2KOQEEGA.js.map +7 -0
  31. package/dist/react/LixScriptParser-JYWJX375.js +1033 -0
  32. package/dist/react/LixScriptParser-JYWJX375.js.map +7 -0
  33. package/dist/react/MermaidFlowchartRenderer-4QBAZ5MB.js +412 -0
  34. package/dist/react/MermaidFlowchartRenderer-4QBAZ5MB.js.map +7 -0
  35. package/dist/react/MermaidSequenceParser-UKG2NSZY.js +8 -0
  36. package/dist/react/MermaidSequenceParser-UKG2NSZY.js.map +7 -0
  37. package/dist/react/MermaidSequenceRenderer-HPLHY5II.js +387 -0
  38. package/dist/react/MermaidSequenceRenderer-HPLHY5II.js.map +7 -0
  39. package/dist/react/Rectangle-6FE7RN6W.js +8 -0
  40. package/dist/react/Rectangle-6FE7RN6W.js.map +7 -0
  41. package/dist/react/ResizeCode-WAMDTKSW.js +2 -0
  42. package/dist/react/ResizeCode-WAMDTKSW.js.map +7 -0
  43. package/dist/react/ResizeShapes-LKEQTITP.js +250 -0
  44. package/dist/react/ResizeShapes-LKEQTITP.js.map +7 -0
  45. package/dist/react/SceneSerializer-4U4B24JM.js +739 -0
  46. package/dist/react/SceneSerializer-4U4B24JM.js.map +7 -0
  47. package/dist/react/Selection-VVUHY5YJ.js +34 -0
  48. package/dist/react/Selection-VVUHY5YJ.js.map +7 -0
  49. package/dist/react/SketchEngine-YA4RG3KX.js +413 -0
  50. package/dist/react/SketchEngine-YA4RG3KX.js.map +7 -0
  51. package/dist/react/TextShape-54ZJ66E3.js +8 -0
  52. package/dist/react/TextShape-54ZJ66E3.js.map +7 -0
  53. package/dist/react/UndoRedo-M2JZUBKN.js +30 -0
  54. package/dist/react/UndoRedo-M2JZUBKN.js.map +7 -0
  55. package/dist/react/ZoomPan-U3TXC5AJ.js +186 -0
  56. package/dist/react/ZoomPan-U3TXC5AJ.js.map +7 -0
  57. package/dist/react/arrowTool-CWEMIRXK.js +17 -0
  58. package/dist/react/arrowTool-CWEMIRXK.js.map +7 -0
  59. package/dist/react/boxicons-5JNJQPUP.woff +0 -0
  60. package/dist/react/boxicons-6NVWQSCQ.eot +0 -0
  61. package/dist/react/boxicons-AQ5N6WP7.woff2 +0 -0
  62. package/dist/react/boxicons-GDR4JU3X.ttf +0 -0
  63. package/dist/react/boxicons-NNFHLMOR.svg +1660 -0
  64. package/dist/react/chunk-2OQXI7QB.js +564 -0
  65. package/dist/react/chunk-2OQXI7QB.js.map +7 -0
  66. package/dist/react/chunk-5OUBTHHO.js +187 -0
  67. package/dist/react/chunk-5OUBTHHO.js.map +7 -0
  68. package/dist/react/chunk-6PFXZKL2.js +628 -0
  69. package/dist/react/chunk-6PFXZKL2.js.map +7 -0
  70. package/dist/react/chunk-6SFNWGGZ.js +453 -0
  71. package/dist/react/chunk-6SFNWGGZ.js.map +7 -0
  72. package/dist/react/chunk-7TZSIR6V.js +210 -0
  73. package/dist/react/chunk-7TZSIR6V.js.map +7 -0
  74. package/dist/react/chunk-AJAZC37E.js +662 -0
  75. package/dist/react/chunk-AJAZC37E.js.map +7 -0
  76. package/dist/react/chunk-BU4D2WYQ.js +1213 -0
  77. package/dist/react/chunk-BU4D2WYQ.js.map +7 -0
  78. package/dist/react/chunk-BZE4CEBG.js +747 -0
  79. package/dist/react/chunk-BZE4CEBG.js.map +7 -0
  80. package/dist/react/chunk-CB2RANCB.js +212 -0
  81. package/dist/react/chunk-CB2RANCB.js.map +7 -0
  82. package/dist/react/chunk-DNAG7ML6.js +128 -0
  83. package/dist/react/chunk-DNAG7ML6.js.map +7 -0
  84. package/dist/react/chunk-HZWLPXFN.js +198 -0
  85. package/dist/react/chunk-HZWLPXFN.js.map +7 -0
  86. package/dist/react/chunk-I6HCCIXB.js +572 -0
  87. package/dist/react/chunk-I6HCCIXB.js.map +7 -0
  88. package/dist/react/chunk-IZ5OGWGW.js +235 -0
  89. package/dist/react/chunk-IZ5OGWGW.js.map +7 -0
  90. package/dist/react/chunk-JJCJNLNN.js +1490 -0
  91. package/dist/react/chunk-JJCJNLNN.js.map +7 -0
  92. package/dist/react/chunk-JQ3IRFDP.js +222 -0
  93. package/dist/react/chunk-JQ3IRFDP.js.map +7 -0
  94. package/dist/react/chunk-L5OARZJ7.js +1134 -0
  95. package/dist/react/chunk-L5OARZJ7.js.map +7 -0
  96. package/dist/react/chunk-LHRTXNVE.js +1600 -0
  97. package/dist/react/chunk-LHRTXNVE.js.map +7 -0
  98. package/dist/react/chunk-Q2GA4MBZ.js +1653 -0
  99. package/dist/react/chunk-Q2GA4MBZ.js.map +7 -0
  100. package/dist/react/chunk-QNSE5BAY.js +519 -0
  101. package/dist/react/chunk-QNSE5BAY.js.map +7 -0
  102. package/dist/react/chunk-QXFBG7OM.js +191 -0
  103. package/dist/react/chunk-QXFBG7OM.js.map +7 -0
  104. package/dist/react/chunk-T6ZVV5ZO.js +714 -0
  105. package/dist/react/chunk-T6ZVV5ZO.js.map +7 -0
  106. package/dist/react/chunk-URB6MY46.js +974 -0
  107. package/dist/react/chunk-URB6MY46.js.map +7 -0
  108. package/dist/react/chunk-VN62KLOC.js +931 -0
  109. package/dist/react/chunk-VN62KLOC.js.map +7 -0
  110. package/dist/react/chunk-VQVEPJSA.js +158 -0
  111. package/dist/react/chunk-VQVEPJSA.js.map +7 -0
  112. package/dist/react/chunk-XISEAGBV.js +1632 -0
  113. package/dist/react/chunk-XISEAGBV.js.map +7 -0
  114. package/dist/react/chunk-YKJUBFHE.js +575 -0
  115. package/dist/react/chunk-YKJUBFHE.js.map +7 -0
  116. package/dist/react/circleTool-NUATSEI2.js +14 -0
  117. package/dist/react/circleTool-NUATSEI2.js.map +7 -0
  118. package/dist/react/codeTool-MHCB2FNB.js +38 -0
  119. package/dist/react/codeTool-MHCB2FNB.js.map +7 -0
  120. package/dist/react/eraserTool-2GS2LQCS.js +103 -0
  121. package/dist/react/eraserTool-2GS2LQCS.js.map +7 -0
  122. package/dist/react/frameTool-PWVKKXSP.js +14 -0
  123. package/dist/react/frameTool-PWVKKXSP.js.map +7 -0
  124. package/dist/react/freehandTool-SLYGASVP.js +14 -0
  125. package/dist/react/freehandTool-SLYGASVP.js.map +7 -0
  126. package/dist/react/iconTool-GPZ7O7NH.js +18 -0
  127. package/dist/react/iconTool-GPZ7O7NH.js.map +7 -0
  128. package/dist/react/imageTool-D5R4XGEU.js +15 -0
  129. package/dist/react/imageTool-D5R4XGEU.js.map +7 -0
  130. package/dist/react/index.js +5342 -0
  131. package/dist/react/index.js.map +7 -0
  132. package/dist/react/laserTool-XVMV63AV.js +239 -0
  133. package/dist/react/laserTool-XVMV63AV.js.map +7 -0
  134. package/dist/react/lineTool-WNI5EMZ5.js +14 -0
  135. package/dist/react/lineTool-WNI5EMZ5.js.map +7 -0
  136. package/dist/react/lixCode-OJMVUXXI.ttf +0 -0
  137. package/dist/react/lixDefault-JEAPAUJL.ttf +0 -0
  138. package/dist/react/lixFancy-BPXYM5CQ.ttf +0 -0
  139. package/dist/react/lixFont-CPKEUDVM.woff2 +0 -0
  140. package/dist/react/rectangleTool-U7DZ6ZTA.js +14 -0
  141. package/dist/react/rectangleTool-U7DZ6ZTA.js.map +7 -0
  142. package/dist/react/styles.css +6627 -0
  143. package/dist/react/textTool-M7S6F3VC.js +21 -0
  144. package/dist/react/textTool-M7S6F3VC.js.map +7 -0
  145. package/package.json +39 -5
  146. package/src/EngineShortcuts.js +83 -27
  147. package/src/core/AIRenderer.js +30 -18
  148. package/src/core/GraphEngine.js +64 -41
  149. package/src/core/MermaidFlowchartRenderer.js +153 -88
  150. package/src/core/MermaidSequenceRenderer.js +168 -93
  151. package/src/core/SceneSerializer.js +86 -2
  152. package/src/core/Selection.js +119 -19
  153. package/src/core/UndoRedo.js +82 -15
  154. package/src/core/ZoomPan.js +15 -5
  155. package/src/index.js +14 -1
  156. package/src/react/LixSketchCanvas.jsx +347 -0
  157. package/src/react/components/AppMenu.jsx +475 -0
  158. package/src/react/components/Footer.jsx +85 -0
  159. package/src/react/components/Toolbar.jsx +140 -0
  160. package/src/react/components/canvas/CanvasLoadingOverlay.jsx +76 -0
  161. package/src/react/components/canvas/ContextMenu.jsx +466 -0
  162. package/src/react/components/canvas/FindBar.jsx +177 -0
  163. package/src/react/components/canvas/ImageSourcePicker.jsx +133 -0
  164. package/src/react/components/canvas/MultiSelectActions.jsx +120 -0
  165. package/src/react/components/canvas/SVGCanvas.jsx +145 -0
  166. package/src/react/components/canvas/SaveStatusIndicator.jsx +29 -0
  167. package/src/react/components/modals/CanvasPropertiesModal.jsx +358 -0
  168. package/src/react/components/modals/CommandPalette.jsx +307 -0
  169. package/src/react/components/modals/ExportImageModal.jsx +287 -0
  170. package/src/react/components/modals/GraphModal.jsx +174 -0
  171. package/src/react/components/modals/HelpModal.jsx +208 -0
  172. package/src/react/components/modals/LixScriptModal.jsx +130 -0
  173. package/src/react/components/modals/ShortcutsModal.jsx +125 -0
  174. package/src/react/components/sidebars/ArrowSidebar.jsx +173 -0
  175. package/src/react/components/sidebars/CircleSidebar.jsx +134 -0
  176. package/src/react/components/sidebars/FrameSidebar.jsx +263 -0
  177. package/src/react/components/sidebars/IconSidebar.jsx +279 -0
  178. package/src/react/components/sidebars/ImageSidebar.jsx +69 -0
  179. package/src/react/components/sidebars/LineSidebar.jsx +109 -0
  180. package/src/react/components/sidebars/PaintbrushSidebar.jsx +119 -0
  181. package/src/react/components/sidebars/RectangleSidebar.jsx +165 -0
  182. package/src/react/components/sidebars/ShapeSidebar.jsx +130 -0
  183. package/src/react/components/sidebars/TextSidebar.jsx +174 -0
  184. package/src/react/hooks/inertStores.js +58 -0
  185. package/src/react/hooks/useSketchEngine.js +76 -0
  186. package/src/react/hooks/useTranslation.js +92 -0
  187. package/src/react/index.js +41 -0
  188. package/src/react/store/useSketchStore.js +234 -0
  189. package/src/react/store/useUIStore.js +196 -0
  190. package/src/react/styles/arrowSidebar.css +263 -0
  191. package/src/react/styles/canvasStroke.css +47 -0
  192. package/src/react/styles/canvasTools.css +769 -0
  193. package/src/react/styles/circleSidebar.css +206 -0
  194. package/src/react/styles/fonts/fonts.css +29 -0
  195. package/src/react/styles/fonts/lixCode.ttf +0 -0
  196. package/src/react/styles/fonts/lixDefault.ttf +0 -0
  197. package/src/react/styles/fonts/lixDocs.ttf +0 -0
  198. package/src/react/styles/fonts/lixFancy.ttf +0 -0
  199. package/src/react/styles/fonts/lixFont.woff2 +0 -0
  200. package/src/react/styles/lineSidebar.css +207 -0
  201. package/src/react/styles/paintbrushSidebar.css +247 -0
  202. package/src/react/styles/squareSidebar.css +206 -0
  203. package/src/react/styles/writeText.css +149 -0
  204. package/src/react/styles.css +175 -0
  205. package/src/react/toolsEnum.js +20 -0
  206. package/src/react/utils/toast.js +18 -0
  207. package/src/shapes/Frame.js +7 -1
  208. package/src/shapes/Line.js +11 -5
  209. package/src/tools/arrowTool.js +30 -4
  210. package/src/tools/circleTool.js +33 -9
  211. package/src/tools/codeTool.js +5 -3
  212. package/src/tools/frameTool.js +47 -7
  213. package/src/tools/freehandTool.js +12 -4
  214. package/src/tools/iconTool.js +7 -1
  215. package/src/tools/imageTool.js +7 -1
  216. package/src/tools/lineTool.js +27 -3
  217. package/src/tools/rectangleTool.js +45 -8
  218. package/src/tools/textTool.js +23 -6
@@ -0,0 +1,931 @@
1
+ "use client";
2
+ import {
3
+ cleanupAttachments,
4
+ updateAttachedArrows
5
+ } from "./chunk-BZE4CEBG.js";
6
+ import {
7
+ pushCreateAction,
8
+ pushDeleteAction,
9
+ pushFrameAttachmentAction,
10
+ pushTransformAction
11
+ } from "./chunk-L5OARZJ7.js";
12
+
13
+ // src/tools/iconTool.js
14
+ var isDraggingIcon = false;
15
+ var iconToPlace = null;
16
+ var iconX = 0;
17
+ var iconY = 0;
18
+ var currentIconElement = null;
19
+ var selectedIcon = null;
20
+ var originalX;
21
+ var originalY;
22
+ var originalWidth;
23
+ var originalHeight;
24
+ var currentAnchor = null;
25
+ var isDragging = false;
26
+ var isRotatingIcon = false;
27
+ var dragOffsetX;
28
+ var dragOffsetY;
29
+ var startRotationMouseAngle = null;
30
+ var startIconRotation = null;
31
+ var iconRotation = 0;
32
+ var aspect_ratio_lock = true;
33
+ var minIconSize = 25;
34
+ var miniatureSize = 40;
35
+ var placedIconSize = 40;
36
+ var draggedShapeInitialFrameIcon = null;
37
+ var hoveredFrameIcon = null;
38
+ var _pendingDragChecker = null;
39
+ var iconSearchInput = document.getElementById("iconSearchInput") || document.createElement("input");
40
+ function getSVGElement() {
41
+ return document.getElementById("freehand-canvas");
42
+ }
43
+ function removeSelection() {
44
+ const svg = getSVGElement();
45
+ if (!svg) return;
46
+ svg.querySelectorAll(".selection-outline").forEach((el) => el.remove());
47
+ removeResizeAnchors();
48
+ removeRotationAnchor();
49
+ if (selectedIcon) {
50
+ selectedIcon.removeEventListener("pointerdown", startDrag);
51
+ selectedIcon.removeEventListener("pointerup", stopDrag);
52
+ selectedIcon.removeEventListener("pointerleave", stopDrag);
53
+ }
54
+ }
55
+ function wrapIconElement(element) {
56
+ const iconShape = new IconShape(element);
57
+ return iconShape;
58
+ }
59
+ document.getElementById("importIcon")?.addEventListener("click", () => {
60
+ const iconContainer = document.getElementById("iconsToolBar");
61
+ if (iconContainer) {
62
+ if (iconContainer.classList.contains("hidden")) {
63
+ iconContainer.classList.remove("hidden");
64
+ iconSearchInput.focus();
65
+ } else {
66
+ iconContainer.classList.add("hidden");
67
+ }
68
+ }
69
+ });
70
+ function getSVGCoordsFromMouse(e) {
71
+ const svg = getSVGElement();
72
+ const viewBox = svg.viewBox.baseVal;
73
+ const rect = svg.getBoundingClientRect();
74
+ const mouseX = e.clientX - rect.left;
75
+ const mouseY = e.clientY - rect.top;
76
+ const svgX = viewBox.x + mouseX / rect.width * viewBox.width;
77
+ const svgY = viewBox.y + mouseY / rect.height * viewBox.height;
78
+ return { x: svgX, y: svgY };
79
+ }
80
+ var handleMouseMoveIcon = (e) => {
81
+ if (!isDraggingIcon || !iconToPlace || !isIconToolActive) return;
82
+ const { x, y } = getSVGCoordsFromMouse(e);
83
+ iconX = x;
84
+ iconY = y;
85
+ drawMiniatureIcon();
86
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
87
+ shapes.forEach((frame) => {
88
+ if (frame.shapeName === "frame") {
89
+ const tempIconBounds = {
90
+ x: iconX - 50,
91
+ y: iconY - 50,
92
+ width: 100,
93
+ height: 100
94
+ };
95
+ if (frame.isShapeInFrame(tempIconBounds)) {
96
+ frame.highlightFrame();
97
+ hoveredFrameIcon = frame;
98
+ if (window.__iconShapeState) window.__iconShapeState.hoveredFrameIcon = frame;
99
+ } else if (hoveredFrameIcon === frame) {
100
+ frame.removeHighlight();
101
+ hoveredFrameIcon = null;
102
+ if (window.__iconShapeState) window.__iconShapeState.hoveredFrameIcon = null;
103
+ }
104
+ }
105
+ });
106
+ }
107
+ };
108
+ var drawMiniatureIcon = () => {
109
+ if (!isDraggingIcon || !iconToPlace || !isIconToolActive) return;
110
+ const svg = getSVGElement();
111
+ if (!svg) {
112
+ console.error("SVG element not found for miniature icon");
113
+ return;
114
+ }
115
+ if (currentIconElement) {
116
+ svg.removeChild(currentIconElement);
117
+ currentIconElement = null;
118
+ }
119
+ const tempDiv = document.createElement("div");
120
+ tempDiv.innerHTML = iconToPlace;
121
+ const svgElement = tempDiv.querySelector("svg");
122
+ if (svgElement) {
123
+ const iconGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
124
+ const viewBox = svgElement.getAttribute("viewBox");
125
+ let vbWidth = 24, vbHeight = 24;
126
+ if (viewBox) {
127
+ const [, , widthStr, heightStr] = viewBox.split(/\s+/);
128
+ vbWidth = parseFloat(widthStr) || 24;
129
+ vbHeight = parseFloat(heightStr) || 24;
130
+ } else {
131
+ const width = svgElement.getAttribute("width");
132
+ const height = svgElement.getAttribute("height");
133
+ if (width && height) {
134
+ vbWidth = parseFloat(width) || 24;
135
+ vbHeight = parseFloat(height) || 24;
136
+ }
137
+ }
138
+ const scale = miniatureSize / Math.max(vbWidth, vbHeight);
139
+ iconGroup.setAttribute("transform", `translate(${iconX - miniatureSize / 2}, ${iconY - miniatureSize / 2}) scale(${scale})`);
140
+ const allChildren = svgElement.children;
141
+ for (let i = 0; i < allChildren.length; i++) {
142
+ const clonedChild = allChildren[i].cloneNode(true);
143
+ const applyGrayStyle = (element) => {
144
+ if (element.nodeType === 1) {
145
+ element.setAttribute("fill", "#666");
146
+ element.setAttribute("stroke", "#666");
147
+ for (let j = 0; j < element.children.length; j++) {
148
+ applyGrayStyle(element.children[j]);
149
+ }
150
+ }
151
+ };
152
+ applyGrayStyle(clonedChild);
153
+ iconGroup.appendChild(clonedChild);
154
+ }
155
+ iconGroup.setAttribute("style", "pointer-events: none; opacity: 0.7;");
156
+ iconGroup.setAttribute("class", "miniature-icon");
157
+ currentIconElement = iconGroup;
158
+ svg.appendChild(currentIconElement);
159
+ }
160
+ };
161
+ var handleMouseDownIcon = async (e) => {
162
+ if (!e.target) return;
163
+ if (isSelectionToolActive) {
164
+ const clickedIcon = e.target.closest('[type="icon"]');
165
+ if (clickedIcon) {
166
+ e.preventDefault();
167
+ e.stopPropagation();
168
+ if (selectedIcon === clickedIcon) {
169
+ let checkDragStartWithThreshold = function(moveEvent) {
170
+ const { x: currentX, y: currentY } = getSVGCoordsFromMouse(moveEvent);
171
+ const deltaX = Math.abs(currentX - initialMouseX);
172
+ const deltaY = Math.abs(currentY - initialMouseY);
173
+ if (deltaX > dragThreshold || deltaY > dragThreshold) {
174
+ document.removeEventListener("pointermove", checkDragStartWithThreshold);
175
+ document.removeEventListener("pointerup", cancelDragPrep);
176
+ window.removeEventListener("pointerup", cancelDragPrep);
177
+ const svg2 = getSVGElement();
178
+ if (svg2) svg2.removeEventListener("pointerup", cancelDragPrep);
179
+ startDrag(moveEvent);
180
+ }
181
+ };
182
+ originalX = parseFloat(selectedIcon.getAttribute("x")) || 0;
183
+ originalY = parseFloat(selectedIcon.getAttribute("y")) || 0;
184
+ originalWidth = parseFloat(selectedIcon.getAttribute("width")) || placedIconSize;
185
+ originalHeight = parseFloat(selectedIcon.getAttribute("height")) || placedIconSize;
186
+ const { x, y } = getSVGCoordsFromMouse(e);
187
+ dragOffsetX = x - originalX;
188
+ dragOffsetY = y - originalY;
189
+ const initialMouseX = x;
190
+ const initialMouseY = y;
191
+ const svgEl = getSVGElement();
192
+ const svgRect2 = svgEl ? svgEl.getBoundingClientRect() : { width: 1536 };
193
+ const svgViewW = svgEl ? svgEl.viewBox.baseVal.width : 1536;
194
+ const dragThreshold = 12 * (svgViewW / svgRect2.width);
195
+ _pendingDragChecker = checkDragStartWithThreshold;
196
+ document.addEventListener("pointermove", checkDragStartWithThreshold);
197
+ document.addEventListener("pointerup", cancelDragPrep);
198
+ window.addEventListener("pointerup", cancelDragPrep);
199
+ const svg = getSVGElement();
200
+ if (svg) svg.addEventListener("pointerup", cancelDragPrep);
201
+ return;
202
+ } else {
203
+ selectIcon(e);
204
+ return;
205
+ }
206
+ }
207
+ if (selectedIcon) {
208
+ removeSelection();
209
+ selectedIcon = null;
210
+ if (currentShape && currentShape.shapeName === "icon") {
211
+ currentShape = null;
212
+ }
213
+ }
214
+ return;
215
+ }
216
+ if (!isDraggingIcon || !iconToPlace || !isIconToolActive) {
217
+ return;
218
+ }
219
+ let placedIconShape = null;
220
+ try {
221
+ const svg = getSVGElement();
222
+ if (!svg) {
223
+ throw new Error("SVG element not found");
224
+ }
225
+ if (currentIconElement) {
226
+ svg.removeChild(currentIconElement);
227
+ currentIconElement = null;
228
+ }
229
+ const { x: placedX, y: placedY } = getSVGCoordsFromMouse(e);
230
+ const tempDiv = document.createElement("div");
231
+ tempDiv.innerHTML = iconToPlace;
232
+ const originalSvgElement = tempDiv.querySelector("svg");
233
+ if (!originalSvgElement) {
234
+ throw new Error("Invalid SVG content");
235
+ }
236
+ const finalIconGroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
237
+ const finalX = placedX - placedIconSize / 2;
238
+ const finalY = placedY - placedIconSize / 2;
239
+ const viewBox = originalSvgElement.getAttribute("viewBox");
240
+ let vbWidth = 24, vbHeight = 24;
241
+ if (viewBox) {
242
+ const [, , widthStr, heightStr] = viewBox.split(/\s+/);
243
+ vbWidth = parseFloat(widthStr) || 24;
244
+ vbHeight = parseFloat(heightStr) || 24;
245
+ } else {
246
+ const width = originalSvgElement.getAttribute("width");
247
+ const height = originalSvgElement.getAttribute("height");
248
+ if (width && height) {
249
+ vbWidth = parseFloat(width) || 24;
250
+ vbHeight = parseFloat(height) || 24;
251
+ }
252
+ }
253
+ const scale = placedIconSize / Math.max(vbWidth, vbHeight);
254
+ const localCenterX = placedIconSize / 2 / scale;
255
+ const localCenterY = placedIconSize / 2 / scale;
256
+ finalIconGroup.setAttribute("transform", `translate(${finalX}, ${finalY}) scale(${scale}) rotate(0, ${localCenterX}, ${localCenterY})`);
257
+ finalIconGroup.setAttribute("data-viewbox-width", vbWidth);
258
+ finalIconGroup.setAttribute("data-viewbox-height", vbHeight);
259
+ const backgroundRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
260
+ backgroundRect.setAttribute("x", 0);
261
+ backgroundRect.setAttribute("y", 0);
262
+ backgroundRect.setAttribute("width", vbWidth);
263
+ backgroundRect.setAttribute("height", vbHeight);
264
+ backgroundRect.setAttribute("fill", "transparent");
265
+ backgroundRect.setAttribute("stroke", "none");
266
+ backgroundRect.setAttribute("style", "pointer-events: all; cursor: pointer;");
267
+ finalIconGroup.appendChild(backgroundRect);
268
+ const allChildren = originalSvgElement.children;
269
+ for (let i = 0; i < allChildren.length; i++) {
270
+ const clonedChild = allChildren[i].cloneNode(true);
271
+ const applyWhiteStyle = (element) => {
272
+ if (element.nodeType === 1) {
273
+ const fill = element.getAttribute("fill");
274
+ const stroke = element.getAttribute("stroke");
275
+ if (!fill || fill === "#000" || fill === "#000000" || fill === "black" || fill === "currentColor") {
276
+ element.setAttribute("fill", "#ffffff");
277
+ }
278
+ if (stroke === "#000" || stroke === "#000000" || stroke === "black" || stroke === "currentColor") {
279
+ element.setAttribute("stroke", "#ffffff");
280
+ }
281
+ for (let j = 0; j < element.children.length; j++) {
282
+ applyWhiteStyle(element.children[j]);
283
+ }
284
+ }
285
+ };
286
+ applyWhiteStyle(clonedChild);
287
+ finalIconGroup.appendChild(clonedChild);
288
+ }
289
+ finalIconGroup.setAttribute("x", finalX);
290
+ finalIconGroup.setAttribute("y", finalY);
291
+ finalIconGroup.setAttribute("width", placedIconSize);
292
+ finalIconGroup.setAttribute("height", placedIconSize);
293
+ finalIconGroup.setAttribute("type", "icon");
294
+ finalIconGroup.setAttribute("data-shape-x", finalX);
295
+ finalIconGroup.setAttribute("data-shape-y", finalY);
296
+ finalIconGroup.setAttribute("data-shape-width", placedIconSize);
297
+ finalIconGroup.setAttribute("data-shape-height", placedIconSize);
298
+ finalIconGroup.setAttribute("data-shape-rotation", 0);
299
+ finalIconGroup.shapeID = `icon-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 1e4)}`;
300
+ finalIconGroup.setAttribute("id", finalIconGroup.shapeID);
301
+ finalIconGroup.setAttribute("style", "cursor: pointer; pointer-events: all;");
302
+ svg.appendChild(finalIconGroup);
303
+ const iconShape = wrapIconElement(finalIconGroup);
304
+ placedIconShape = iconShape;
305
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
306
+ const alreadyExists = shapes.some((s) => s.shapeName === "icon" && s.element === finalIconGroup);
307
+ if (!alreadyExists) {
308
+ shapes.push(iconShape);
309
+ }
310
+ }
311
+ const finalFrame = hoveredFrameIcon;
312
+ if (finalFrame) {
313
+ finalFrame.addShapeToFrame(iconShape);
314
+ pushFrameAttachmentAction(finalFrame, iconShape, "attach", null);
315
+ }
316
+ pushCreateAction(iconShape);
317
+ if (hoveredFrameIcon) {
318
+ hoveredFrameIcon.removeHighlight();
319
+ hoveredFrameIcon = null;
320
+ if (window.__iconShapeState) window.__iconShapeState.hoveredFrameIcon = null;
321
+ }
322
+ console.log("Icon placed successfully:", finalIconGroup);
323
+ } catch (error) {
324
+ console.error("Error placing icon:", error);
325
+ isDraggingIcon = false;
326
+ iconToPlace = null;
327
+ } finally {
328
+ isDraggingIcon = false;
329
+ iconToPlace = null;
330
+ document.body.style.cursor = "default";
331
+ }
332
+ if (placedIconShape) {
333
+ currentShape = placedIconShape;
334
+ currentShape.isSelected = true;
335
+ requestAnimationFrame(() => {
336
+ placedIconShape.selectShape();
337
+ });
338
+ }
339
+ };
340
+ var handleMouseUpIcon = (e) => {
341
+ if (!e.target) return;
342
+ if (hoveredFrameIcon) {
343
+ hoveredFrameIcon.removeHighlight();
344
+ hoveredFrameIcon = null;
345
+ }
346
+ };
347
+ function addSelectionOutline() {
348
+ if (!selectedIcon) return;
349
+ const svg = getSVGElement();
350
+ if (!svg) return;
351
+ const x = parseFloat(selectedIcon.getAttribute("data-shape-x")) || 0;
352
+ const y = parseFloat(selectedIcon.getAttribute("data-shape-y")) || 0;
353
+ const width = parseFloat(selectedIcon.getAttribute("data-shape-width")) || 40;
354
+ const height = parseFloat(selectedIcon.getAttribute("data-shape-height")) || 40;
355
+ const rotation = parseFloat(selectedIcon.getAttribute("data-shape-rotation")) || 0;
356
+ const centerX = x + width / 2;
357
+ const centerY = y + height / 2;
358
+ const selectionPadding = Math.max(4, width * 0.08);
359
+ const expandedX = x - selectionPadding;
360
+ const expandedY = y - selectionPadding;
361
+ const expandedWidth = width + 2 * selectionPadding;
362
+ const expandedHeight = height + 2 * selectionPadding;
363
+ removeSelection();
364
+ const outline = document.createElementNS("http://www.w3.org/2000/svg", "rect");
365
+ outline.setAttribute("x", expandedX);
366
+ outline.setAttribute("y", expandedY);
367
+ outline.setAttribute("width", expandedWidth);
368
+ outline.setAttribute("height", expandedHeight);
369
+ outline.setAttribute("fill", "none");
370
+ outline.setAttribute("stroke", "#5B57D1");
371
+ outline.setAttribute("stroke-width", 1.5);
372
+ outline.setAttribute("stroke-dasharray", "4 3");
373
+ outline.setAttribute("style", "pointer-events: none;");
374
+ outline.setAttribute("class", "selection-outline");
375
+ if (rotation !== 0) {
376
+ outline.setAttribute("transform", `rotate(${rotation}, ${centerX}, ${centerY})`);
377
+ }
378
+ svg.appendChild(outline);
379
+ addResizeAnchors(expandedX, expandedY, expandedWidth, expandedHeight, centerX, centerY, width, rotation);
380
+ addRotationAnchor(expandedX, expandedY, expandedWidth, expandedHeight, centerX, centerY, width, rotation);
381
+ }
382
+ function cancelDragPrep(event) {
383
+ if (_pendingDragChecker) {
384
+ document.removeEventListener("pointermove", _pendingDragChecker);
385
+ _pendingDragChecker = null;
386
+ }
387
+ document.removeEventListener("pointerup", cancelDragPrep);
388
+ window.removeEventListener("pointerup", cancelDragPrep);
389
+ const svg = getSVGElement();
390
+ if (svg) {
391
+ svg.removeEventListener("pointerup", cancelDragPrep);
392
+ }
393
+ }
394
+ function startDrag(event) {
395
+ console.log("start dragging icon");
396
+ if (!isSelectionToolActive || !selectedIcon) return;
397
+ isDragging = true;
398
+ if (window.__iconShapeState) window.__iconShapeState.isDragging = true;
399
+ let iconShape = null;
400
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
401
+ iconShape = shapes.find((shape) => shape.shapeName === "icon" && shape.element === selectedIcon);
402
+ }
403
+ if (iconShape) {
404
+ draggedShapeInitialFrameIcon = iconShape.parentFrame || null;
405
+ if (iconShape.parentFrame) {
406
+ iconShape.parentFrame.temporarilyRemoveFromFrame(iconShape);
407
+ }
408
+ }
409
+ document.addEventListener("pointermove", dragIcon);
410
+ document.addEventListener("pointerup", stopDrag);
411
+ window.addEventListener("pointerup", stopDrag);
412
+ const svg = getSVGElement();
413
+ if (svg) {
414
+ svg.addEventListener("pointerup", stopDrag);
415
+ }
416
+ document.addEventListener("dragstart", preventDefaultDrag);
417
+ document.addEventListener("selectstart", preventDefaultDrag);
418
+ }
419
+ function preventDefaultDrag(e) {
420
+ e.preventDefault();
421
+ return false;
422
+ }
423
+ function selectIcon(event) {
424
+ if (!isSelectionToolActive) return;
425
+ event.stopPropagation();
426
+ let targetIcon = event.target.closest ? event.target.closest('[type="icon"]') : null;
427
+ if (!targetIcon) {
428
+ let current = event.target;
429
+ while (current && current !== document) {
430
+ if (current.getAttribute && current.getAttribute("type") === "icon") {
431
+ targetIcon = current;
432
+ break;
433
+ }
434
+ current = current.parentElement;
435
+ }
436
+ }
437
+ if (selectedIcon) {
438
+ removeSelection();
439
+ }
440
+ selectedIcon = targetIcon;
441
+ if (!selectedIcon) {
442
+ console.warn("Could not find icon to select");
443
+ return;
444
+ }
445
+ const transform = selectedIcon.getAttribute("transform");
446
+ if (transform) {
447
+ const rotateMatch = transform.match(/rotate\(([^,\s]+)/);
448
+ if (rotateMatch) {
449
+ iconRotation = parseFloat(rotateMatch[1]);
450
+ }
451
+ } else {
452
+ iconRotation = 0;
453
+ }
454
+ addSelectionOutline();
455
+ originalX = parseFloat(selectedIcon.getAttribute("x")) || 0;
456
+ originalY = parseFloat(selectedIcon.getAttribute("y")) || 0;
457
+ originalWidth = parseFloat(selectedIcon.getAttribute("width")) || placedIconSize;
458
+ originalHeight = parseFloat(selectedIcon.getAttribute("height")) || placedIconSize;
459
+ const iconShape = typeof shapes !== "undefined" && Array.isArray(shapes) ? shapes.find((s) => s.shapeName === "icon" && s.element === selectedIcon) : null;
460
+ if (iconShape) {
461
+ currentShape = iconShape;
462
+ currentShape.isSelected = true;
463
+ if (window.__showSidebarForShape) window.__showSidebarForShape("icon");
464
+ }
465
+ }
466
+ function addResizeAnchors(x, y, width, height, centerX, centerY, iconWidth, rotation) {
467
+ const svg = getSVGElement();
468
+ if (!svg) return;
469
+ const zoom = window.currentZoom || 1;
470
+ const anchorSize = Math.max(8, Math.min(16, iconWidth * 0.15)) / zoom;
471
+ const anchorStrokeWidth = Math.max(1.5, anchorSize * 0.15);
472
+ const positions = [
473
+ { x, y, cursor: "nw-resize" },
474
+ { x: x + width, y, cursor: "ne-resize" },
475
+ { x, y: y + height, cursor: "sw-resize" },
476
+ { x: x + width, y: y + height, cursor: "se-resize" }
477
+ ];
478
+ positions.forEach((pos) => {
479
+ const anchor = document.createElementNS("http://www.w3.org/2000/svg", "rect");
480
+ anchor.setAttribute("x", pos.x - anchorSize / 2);
481
+ anchor.setAttribute("y", pos.y - anchorSize / 2);
482
+ anchor.setAttribute("width", anchorSize);
483
+ anchor.setAttribute("height", anchorSize);
484
+ anchor.setAttribute("fill", "#121212");
485
+ anchor.setAttribute("stroke", "#5B57D1");
486
+ anchor.setAttribute("stroke-width", anchorStrokeWidth);
487
+ anchor.setAttribute("class", "resize-anchor");
488
+ anchor.setAttribute("transform", `rotate(${rotation}, ${centerX}, ${centerY})`);
489
+ anchor.style.cursor = pos.cursor;
490
+ svg.appendChild(anchor);
491
+ anchor.addEventListener("pointerdown", startResize);
492
+ anchor.addEventListener("pointerup", stopResize);
493
+ });
494
+ }
495
+ function addRotationAnchor(x, y, width, height, centerX, centerY, iconWidth, rotation) {
496
+ const svg = getSVGElement();
497
+ if (!svg) return;
498
+ const anchorRadius = Math.max(6, Math.min(12, iconWidth * 0.12));
499
+ const anchorStrokeWidth = Math.max(1.5, anchorRadius * 0.2);
500
+ const rotationDistance = Math.max(25, iconWidth * 0.4);
501
+ const rotationAnchorX = x + width / 2;
502
+ const rotationAnchorY = y - rotationDistance;
503
+ const rotationAnchor = document.createElementNS("http://www.w3.org/2000/svg", "circle");
504
+ rotationAnchor.setAttribute("cx", rotationAnchorX);
505
+ rotationAnchor.setAttribute("cy", rotationAnchorY);
506
+ rotationAnchor.setAttribute("r", anchorRadius);
507
+ rotationAnchor.setAttribute("class", "rotation-anchor");
508
+ rotationAnchor.setAttribute("fill", "#121212");
509
+ rotationAnchor.setAttribute("stroke", "#5B57D1");
510
+ rotationAnchor.setAttribute("stroke-width", anchorStrokeWidth);
511
+ rotationAnchor.setAttribute("style", "pointer-events: all; cursor: grab;");
512
+ rotationAnchor.setAttribute("transform", `rotate(${rotation}, ${centerX}, ${centerY})`);
513
+ svg.appendChild(rotationAnchor);
514
+ rotationAnchor.addEventListener("pointerdown", startRotation);
515
+ rotationAnchor.addEventListener("pointerup", stopRotation);
516
+ rotationAnchor.addEventListener("mouseover", function() {
517
+ if (!isRotatingIcon && !isDragging) {
518
+ rotationAnchor.style.cursor = "grab";
519
+ }
520
+ });
521
+ rotationAnchor.addEventListener("mouseout", function() {
522
+ if (!isRotatingIcon && !isDragging) {
523
+ rotationAnchor.style.cursor = "default";
524
+ }
525
+ });
526
+ }
527
+ function removeRotationAnchor() {
528
+ const svg = getSVGElement();
529
+ if (!svg) return;
530
+ svg.querySelectorAll(".rotation-anchor").forEach((el) => el.remove());
531
+ }
532
+ function removeResizeAnchors() {
533
+ const svg = getSVGElement();
534
+ if (!svg) return;
535
+ const anchors = svg.querySelectorAll(".resize-anchor");
536
+ anchors.forEach((anchor) => svg.removeChild(anchor));
537
+ }
538
+ function startResize(event) {
539
+ event.preventDefault();
540
+ event.stopPropagation();
541
+ currentAnchor = event.target;
542
+ originalX = parseFloat(selectedIcon.getAttribute("x")) || 0;
543
+ originalY = parseFloat(selectedIcon.getAttribute("y")) || 0;
544
+ originalWidth = parseFloat(selectedIcon.getAttribute("width")) || 100;
545
+ originalHeight = parseFloat(selectedIcon.getAttribute("height")) || 100;
546
+ const { x: mouseX, y: mouseY } = getSVGCoordsFromMouse(event);
547
+ currentAnchor.startMouseX = mouseX;
548
+ currentAnchor.startMouseY = mouseY;
549
+ currentAnchor.iconRotation = iconRotation;
550
+ const svg = getSVGElement();
551
+ if (svg) {
552
+ svg.addEventListener("pointermove", resizeIcon);
553
+ }
554
+ document.addEventListener("pointerup", stopResize);
555
+ }
556
+ function stopResize(event) {
557
+ stopInteracting();
558
+ document.removeEventListener("pointerup", stopResize);
559
+ }
560
+ function resizeIcon(event) {
561
+ if (!selectedIcon || !currentAnchor) return;
562
+ const { x: currentMouseX, y: currentMouseY } = getSVGCoordsFromMouse(event);
563
+ const rotation = currentAnchor.iconRotation || 0;
564
+ const rotationRad = rotation * Math.PI / 180;
565
+ const rawDeltaX = currentMouseX - currentAnchor.startMouseX;
566
+ const rawDeltaY = currentMouseY - currentAnchor.startMouseY;
567
+ const deltaX = rawDeltaX * Math.cos(-rotationRad) - rawDeltaY * Math.sin(-rotationRad);
568
+ const deltaY = rawDeltaX * Math.sin(-rotationRad) + rawDeltaY * Math.cos(-rotationRad);
569
+ let newWidth = originalWidth;
570
+ let newHeight = originalHeight;
571
+ let newX = originalX;
572
+ let newY = originalY;
573
+ let fixedRelX, fixedRelY;
574
+ switch (currentAnchor.style.cursor) {
575
+ case "nw-resize":
576
+ newWidth = Math.max(minIconSize, originalWidth - deltaX);
577
+ newHeight = Math.max(minIconSize, originalHeight - deltaY);
578
+ if (aspect_ratio_lock) {
579
+ const scale = Math.min(newWidth / originalWidth, newHeight / originalHeight);
580
+ newWidth = originalWidth * scale;
581
+ newHeight = originalHeight * scale;
582
+ }
583
+ newX = originalX + (originalWidth - newWidth);
584
+ newY = originalY + (originalHeight - newHeight);
585
+ fixedRelX = originalWidth;
586
+ fixedRelY = originalHeight;
587
+ break;
588
+ case "ne-resize":
589
+ newWidth = Math.max(minIconSize, originalWidth + deltaX);
590
+ newHeight = Math.max(minIconSize, originalHeight - deltaY);
591
+ if (aspect_ratio_lock) {
592
+ const scale = Math.max(newWidth / originalWidth, newHeight / originalHeight);
593
+ newWidth = originalWidth * scale;
594
+ newHeight = originalHeight * scale;
595
+ }
596
+ newX = originalX;
597
+ newY = originalY + (originalHeight - newHeight);
598
+ fixedRelX = 0;
599
+ fixedRelY = originalHeight;
600
+ break;
601
+ case "sw-resize":
602
+ newWidth = Math.max(minIconSize, originalWidth - deltaX);
603
+ newHeight = Math.max(minIconSize, originalHeight + deltaY);
604
+ if (aspect_ratio_lock) {
605
+ const scale = Math.max(newWidth / originalWidth, newHeight / originalHeight);
606
+ newWidth = originalWidth * scale;
607
+ newHeight = originalHeight * scale;
608
+ }
609
+ newX = originalX + (originalWidth - newWidth);
610
+ newY = originalY;
611
+ fixedRelX = originalWidth;
612
+ fixedRelY = 0;
613
+ break;
614
+ case "se-resize":
615
+ newWidth = Math.max(minIconSize, originalWidth + deltaX);
616
+ newHeight = Math.max(minIconSize, originalHeight + deltaY);
617
+ if (aspect_ratio_lock) {
618
+ const scale = Math.max(newWidth / originalWidth, newHeight / originalHeight);
619
+ newWidth = originalWidth * scale;
620
+ newHeight = originalHeight * scale;
621
+ }
622
+ newX = originalX;
623
+ newY = originalY;
624
+ fixedRelX = 0;
625
+ fixedRelY = 0;
626
+ break;
627
+ }
628
+ if (rotation !== 0) {
629
+ const cosR = Math.cos(rotationRad);
630
+ const sinR = Math.sin(rotationRad);
631
+ const oldCX = originalX + originalWidth / 2;
632
+ const oldCY = originalY + originalHeight / 2;
633
+ const odx = originalX + fixedRelX - oldCX;
634
+ const ody = originalY + fixedRelY - oldCY;
635
+ const fixedWorldX = oldCX + odx * cosR - ody * sinR;
636
+ const fixedWorldY = oldCY + odx * sinR + ody * cosR;
637
+ const fixedNewRelX = fixedRelX === 0 ? 0 : newWidth;
638
+ const fixedNewRelY = fixedRelY === 0 ? 0 : newHeight;
639
+ const ncx = newWidth / 2;
640
+ const ncy = newHeight / 2;
641
+ const ndx = fixedNewRelX - ncx;
642
+ const ndy = fixedNewRelY - ncy;
643
+ const rotX = ncx + ndx * cosR - ndy * sinR;
644
+ const rotY = ncy + ndx * sinR + ndy * cosR;
645
+ newX = fixedWorldX - rotX;
646
+ newY = fixedWorldY - rotY;
647
+ }
648
+ selectedIcon.setAttribute("width", newWidth);
649
+ selectedIcon.setAttribute("height", newHeight);
650
+ selectedIcon.setAttribute("x", newX);
651
+ selectedIcon.setAttribute("y", newY);
652
+ selectedIcon.setAttribute("data-shape-x", newX);
653
+ selectedIcon.setAttribute("data-shape-y", newY);
654
+ selectedIcon.setAttribute("data-shape-width", newWidth);
655
+ selectedIcon.setAttribute("data-shape-height", newHeight);
656
+ const vbWidth = parseFloat(selectedIcon.getAttribute("data-viewbox-width")) || 24;
657
+ const vbHeight = parseFloat(selectedIcon.getAttribute("data-viewbox-height")) || 24;
658
+ const iconScale = newWidth / Math.max(vbWidth, vbHeight);
659
+ const localCenterX = newWidth / 2 / iconScale;
660
+ const localCenterY = newHeight / 2 / iconScale;
661
+ selectedIcon.setAttribute("transform", `translate(${newX}, ${newY}) scale(${iconScale}) rotate(${iconRotation}, ${localCenterX}, ${localCenterY})`);
662
+ updateAttachedArrows(selectedIcon);
663
+ addSelectionOutline();
664
+ }
665
+ function dragIcon(event) {
666
+ if (!isDragging || !selectedIcon) return;
667
+ const { x, y } = getSVGCoordsFromMouse(event);
668
+ let newX = x - dragOffsetX;
669
+ let newY = y - dragOffsetY;
670
+ selectedIcon.setAttribute("x", newX);
671
+ selectedIcon.setAttribute("y", newY);
672
+ selectedIcon.setAttribute("data-shape-x", newX);
673
+ selectedIcon.setAttribute("data-shape-y", newY);
674
+ const width = parseFloat(selectedIcon.getAttribute("width")) || 100;
675
+ const height = parseFloat(selectedIcon.getAttribute("height")) || 100;
676
+ const vbWidth = parseFloat(selectedIcon.getAttribute("data-viewbox-width")) || 24;
677
+ const vbHeight = parseFloat(selectedIcon.getAttribute("data-viewbox-height")) || 24;
678
+ const scale = width / Math.max(vbWidth, vbHeight);
679
+ const localCenterX = width / 2 / scale;
680
+ const localCenterY = height / 2 / scale;
681
+ selectedIcon.setAttribute("transform", `translate(${newX}, ${newY}) scale(${scale}) rotate(${iconRotation}, ${localCenterX}, ${localCenterY})`);
682
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
683
+ const iconShape = shapes.find((shape) => shape.shapeName === "icon" && shape.element === selectedIcon);
684
+ if (iconShape) {
685
+ iconShape.x = newX;
686
+ iconShape.y = newY;
687
+ iconShape.updateFrameContainment();
688
+ }
689
+ }
690
+ updateAttachedArrows(selectedIcon);
691
+ removeSelection();
692
+ addSelectionOutline();
693
+ }
694
+ function stopDrag(event) {
695
+ if (!isDragging) return;
696
+ console.log("stop dragging icon");
697
+ isDragging = false;
698
+ if (window.__iconShapeState) window.__iconShapeState.isDragging = false;
699
+ document.removeEventListener("pointermove", dragIcon);
700
+ document.removeEventListener("pointerup", stopDrag);
701
+ window.removeEventListener("pointerup", stopDrag);
702
+ const svg = getSVGElement();
703
+ if (svg) {
704
+ svg.removeEventListener("pointerup", stopDrag);
705
+ }
706
+ document.removeEventListener("dragstart", preventDefaultDrag);
707
+ document.removeEventListener("selectstart", preventDefaultDrag);
708
+ stopInteracting();
709
+ }
710
+ function startRotation(event) {
711
+ event.preventDefault();
712
+ event.stopPropagation();
713
+ if (!selectedIcon) return;
714
+ isRotatingIcon = true;
715
+ console.log(selectedIcon);
716
+ const iconX2 = parseFloat(selectedIcon.getAttribute("x"));
717
+ const iconY2 = parseFloat(selectedIcon.getAttribute("y"));
718
+ const iconWidth = parseFloat(selectedIcon.getAttribute("width"));
719
+ const iconHeight = parseFloat(selectedIcon.getAttribute("height"));
720
+ const centerX = iconX2 + iconWidth / 2;
721
+ const centerY = iconY2 + iconHeight / 2;
722
+ const { x: mouseX, y: mouseY } = getSVGCoordsFromMouse(event);
723
+ startRotationMouseAngle = Math.atan2(mouseY - centerY, mouseX - centerX) * 180 / Math.PI;
724
+ console.log("Start rotation mouse angle:", startRotationMouseAngle);
725
+ startIconRotation = iconRotation;
726
+ const svg = getSVGElement();
727
+ if (svg) {
728
+ svg.addEventListener("pointermove", rotateIcon);
729
+ svg.style.cursor = "grabbing";
730
+ }
731
+ document.addEventListener("pointerup", stopRotation);
732
+ }
733
+ function rotateIcon(event) {
734
+ if (!isRotatingIcon || !selectedIcon) return;
735
+ const iconX2 = parseFloat(selectedIcon.getAttribute("x")) || 0;
736
+ const iconY2 = parseFloat(selectedIcon.getAttribute("y")) || 0;
737
+ const iconWidth = parseFloat(selectedIcon.getAttribute("width")) || 100;
738
+ const iconHeight = parseFloat(selectedIcon.getAttribute("height")) || 100;
739
+ const centerX = iconX2 + iconWidth / 2;
740
+ const centerY = iconY2 + iconHeight / 2;
741
+ const { x: mouseX, y: mouseY } = getSVGCoordsFromMouse(event);
742
+ const currentMouseAngle = Math.atan2(mouseY - centerY, mouseX - centerX) * 180 / Math.PI;
743
+ const angleDiff = currentMouseAngle - startRotationMouseAngle;
744
+ iconRotation = startIconRotation + angleDiff;
745
+ iconRotation = iconRotation % 360;
746
+ if (iconRotation < 0) iconRotation += 360;
747
+ const vbWidth = parseFloat(selectedIcon.getAttribute("data-viewbox-width")) || 24;
748
+ const vbHeight = parseFloat(selectedIcon.getAttribute("data-viewbox-height")) || 24;
749
+ const scale = iconWidth / Math.max(vbWidth, vbHeight);
750
+ const localCenterX = iconWidth / 2 / scale;
751
+ const localCenterY = iconHeight / 2 / scale;
752
+ selectedIcon.setAttribute("transform", `translate(${iconX2}, ${iconY2}) scale(${scale}) rotate(${iconRotation}, ${localCenterX}, ${localCenterY})`);
753
+ selectedIcon.setAttribute("data-shape-rotation", iconRotation);
754
+ updateAttachedArrows(selectedIcon);
755
+ removeSelection();
756
+ addSelectionOutline();
757
+ }
758
+ function stopRotation(event) {
759
+ if (!isRotatingIcon) return;
760
+ stopInteracting();
761
+ isRotatingIcon = false;
762
+ startRotationMouseAngle = null;
763
+ startIconRotation = null;
764
+ const svg = getSVGElement();
765
+ if (svg) {
766
+ svg.removeEventListener("pointermove", rotateIcon);
767
+ svg.style.cursor = "default";
768
+ }
769
+ document.removeEventListener("pointerup", stopRotation);
770
+ }
771
+ function stopInteracting() {
772
+ if (selectedIcon && (isDragging || isRotatingIcon || currentAnchor)) {
773
+ const newPos = {
774
+ x: parseFloat(selectedIcon.getAttribute("x")) || 0,
775
+ y: parseFloat(selectedIcon.getAttribute("y")) || 0,
776
+ width: parseFloat(selectedIcon.getAttribute("width")) || 100,
777
+ height: parseFloat(selectedIcon.getAttribute("height")) || 100,
778
+ rotation: iconRotation
779
+ };
780
+ let originalRotation = iconRotation;
781
+ if (isRotatingIcon && startIconRotation !== null) {
782
+ originalRotation = startIconRotation;
783
+ }
784
+ const oldPos = {
785
+ x: originalX,
786
+ y: originalY,
787
+ width: originalWidth,
788
+ height: originalHeight,
789
+ rotation: originalRotation
790
+ };
791
+ let iconShape = null;
792
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
793
+ iconShape = shapes.find((shape) => shape.shapeName === "icon" && shape.element === selectedIcon);
794
+ if (iconShape) {
795
+ iconShape.x = newPos.x;
796
+ iconShape.y = newPos.y;
797
+ iconShape.width = newPos.width;
798
+ iconShape.height = newPos.height;
799
+ iconShape.rotation = newPos.rotation;
800
+ }
801
+ }
802
+ const oldPosWithFrame = {
803
+ ...oldPos,
804
+ parentFrame: draggedShapeInitialFrameIcon
805
+ };
806
+ const newPosWithFrame = {
807
+ ...newPos,
808
+ parentFrame: isDragging ? hoveredFrameIcon || null : iconShape ? iconShape.parentFrame : null
809
+ };
810
+ const stateChanged = newPos.x !== oldPos.x || newPos.y !== oldPos.y || newPos.width !== oldPos.width || newPos.height !== oldPos.height || newPos.rotation !== oldPos.rotation;
811
+ const frameChanged = oldPosWithFrame.parentFrame !== newPosWithFrame.parentFrame;
812
+ if ((stateChanged || frameChanged) && iconShape) {
813
+ pushTransformAction(iconShape, oldPosWithFrame, newPosWithFrame);
814
+ }
815
+ if (isDragging && iconShape) {
816
+ const finalFrame = hoveredFrameIcon;
817
+ if (draggedShapeInitialFrameIcon !== finalFrame) {
818
+ if (draggedShapeInitialFrameIcon) {
819
+ draggedShapeInitialFrameIcon.removeShapeFromFrame(iconShape);
820
+ }
821
+ if (finalFrame) {
822
+ finalFrame.addShapeToFrame(iconShape);
823
+ }
824
+ if (frameChanged) {
825
+ pushFrameAttachmentAction(
826
+ finalFrame || draggedShapeInitialFrameIcon,
827
+ iconShape,
828
+ finalFrame ? "attach" : "detach",
829
+ draggedShapeInitialFrameIcon
830
+ );
831
+ }
832
+ } else if (draggedShapeInitialFrameIcon) {
833
+ draggedShapeInitialFrameIcon.restoreToFrame(iconShape);
834
+ }
835
+ }
836
+ draggedShapeInitialFrameIcon = null;
837
+ }
838
+ if (hoveredFrameIcon) {
839
+ hoveredFrameIcon.removeHighlight();
840
+ hoveredFrameIcon = null;
841
+ if (window.__iconShapeState) window.__iconShapeState.hoveredFrameIcon = null;
842
+ }
843
+ isDragging = false;
844
+ if (window.__iconShapeState) window.__iconShapeState.isDragging = false;
845
+ isRotatingIcon = false;
846
+ const svg = getSVGElement();
847
+ if (svg) {
848
+ svg.removeEventListener("pointermove", dragIcon);
849
+ svg.removeEventListener("pointermove", resizeIcon);
850
+ svg.removeEventListener("pointermove", rotateIcon);
851
+ }
852
+ document.removeEventListener("pointermove", dragIcon);
853
+ document.removeEventListener("pointermove", resizeIcon);
854
+ document.removeEventListener("pointermove", rotateIcon);
855
+ currentAnchor = null;
856
+ startRotationMouseAngle = null;
857
+ startIconRotation = null;
858
+ if (selectedIcon) {
859
+ originalX = parseFloat(selectedIcon.getAttribute("x")) || 0;
860
+ originalY = parseFloat(selectedIcon.getAttribute("y")) || 0;
861
+ originalWidth = parseFloat(selectedIcon.getAttribute("width")) || 100;
862
+ originalHeight = parseFloat(selectedIcon.getAttribute("height")) || 100;
863
+ selectedIcon.setAttribute("data-shape-x", originalX);
864
+ selectedIcon.setAttribute("data-shape-y", originalY);
865
+ selectedIcon.setAttribute("data-shape-width", originalWidth);
866
+ selectedIcon.setAttribute("data-shape-height", originalHeight);
867
+ selectedIcon.setAttribute("data-shape-rotation", iconRotation);
868
+ updateAttachedArrows(selectedIcon);
869
+ }
870
+ }
871
+ function deleteCurrentIcon() {
872
+ if (selectedIcon) {
873
+ let iconShape = null;
874
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
875
+ iconShape = shapes.find((shape) => shape.shapeName === "icon" && shape.element === selectedIcon);
876
+ if (iconShape) {
877
+ const idx = shapes.indexOf(iconShape);
878
+ if (idx !== -1) shapes.splice(idx, 1);
879
+ if (iconShape.group && iconShape.group.parentNode) {
880
+ iconShape.group.parentNode.removeChild(iconShape.group);
881
+ }
882
+ }
883
+ }
884
+ if (!iconShape && selectedIcon.parentNode) {
885
+ selectedIcon.parentNode.removeChild(selectedIcon);
886
+ }
887
+ if (typeof cleanupAttachments === "function") {
888
+ cleanupAttachments(selectedIcon);
889
+ }
890
+ if (iconShape) {
891
+ pushDeleteAction(iconShape);
892
+ }
893
+ removeSelection();
894
+ selectedIcon = null;
895
+ }
896
+ }
897
+ document.addEventListener("keydown", (e) => {
898
+ if (e.key === "Delete" && selectedIcon) {
899
+ deleteCurrentIcon();
900
+ }
901
+ });
902
+ function cleanupIconTool() {
903
+ if (currentIconElement) {
904
+ const svg = getSVGElement();
905
+ if (svg && currentIconElement.parentNode === svg) {
906
+ svg.removeChild(currentIconElement);
907
+ }
908
+ currentIconElement = null;
909
+ }
910
+ isDraggingIcon = false;
911
+ iconToPlace = null;
912
+ document.body.style.cursor = "default";
913
+ }
914
+ window.__cleanupIconTool = cleanupIconTool;
915
+ window.prepareIconPlacement = function(svgContent) {
916
+ iconToPlace = svgContent;
917
+ isDraggingIcon = true;
918
+ window.isIconToolActive = true;
919
+ document.body.style.cursor = "crosshair";
920
+ };
921
+ window.__iconToolSelectIcon = selectIcon;
922
+ window.__iconToolRemoveSelection = removeSelection;
923
+
924
+ export {
925
+ handleMouseMoveIcon,
926
+ handleMouseDownIcon,
927
+ handleMouseUpIcon,
928
+ startDrag,
929
+ stopDrag
930
+ };
931
+ //# sourceMappingURL=chunk-VN62KLOC.js.map