@elixpo/lixsketch 5.6.5 → 5.6.6
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/mcp/index.js +5 -1
- package/dist/mcp/index.js.map +2 -2
- package/dist/mcp/stdio.js +5 -1
- package/dist/mcp/stdio.js.map +2 -2
- package/dist/react/{AIRenderer-SRF7LU5K.js → AIRenderer-R5M2CIDO.js} +13 -6
- package/dist/react/AIRenderer-R5M2CIDO.js.map +7 -0
- package/dist/react/Circle-HMM5PKJ2.js +10 -0
- package/dist/react/{CopyPaste-YUDZ6DHY.js → CopyPaste-P6G35CXO.js} +11 -10
- package/dist/react/{CopyPaste-YUDZ6DHY.js.map → CopyPaste-P6G35CXO.js.map} +1 -1
- package/dist/react/{EventDispatcher-7LAK7GQ7.js → EventDispatcher-M5B4EWHJ.js} +216 -63
- package/dist/react/EventDispatcher-M5B4EWHJ.js.map +7 -0
- package/dist/react/Frame-QEUEYITT.js +11 -0
- package/dist/react/{FreehandStroke-U6GYZOM4.js → FreehandStroke-WXIJKD5I.js} +2 -2
- package/dist/react/{GraphEngine-MM6ALA2N.js → GraphEngine-XH3RPYO4.js} +9 -2
- package/dist/react/GraphEngine-XH3RPYO4.js.map +7 -0
- package/dist/react/IconShape-NHJE4YBY.js +10 -0
- package/dist/react/ImageShape-33VCMSDP.js +10 -0
- package/dist/react/Line-A6FE232Q.js +10 -0
- package/dist/react/{LixScriptParser-JYWJX375.js → LixScriptParser-YS3ZOTGS.js} +6 -2
- package/dist/react/LixScriptParser-YS3ZOTGS.js.map +7 -0
- package/dist/react/{MermaidFlowchartRenderer-PQEC4TMI.js → MermaidFlowchartRenderer-EL3Q2MNW.js} +6 -2
- package/dist/react/MermaidFlowchartRenderer-EL3Q2MNW.js.map +7 -0
- package/dist/react/MermaidSequenceParser-DBYXW23P.js +8 -0
- package/dist/react/{MermaidSequenceRenderer-KCUHO7UI.js → MermaidSequenceRenderer-K4KHHEVC.js} +10 -3
- package/dist/react/MermaidSequenceRenderer-K4KHHEVC.js.map +7 -0
- package/dist/react/{MermaidStructuredRenderer-W7UKN7BM.js → MermaidStructuredRenderer-6LN3WISP.js} +7 -2
- package/dist/react/MermaidStructuredRenderer-6LN3WISP.js.map +7 -0
- package/dist/react/Rectangle-4U4CD2ER.js +10 -0
- package/dist/react/{SceneSerializer-SG6SJN5X.js → SceneSerializer-JEYTYXZQ.js} +120 -46
- package/dist/react/SceneSerializer-JEYTYXZQ.js.map +7 -0
- package/dist/react/{Selection-2TSH3J6P.js → Selection-23MOLHEI.js} +4 -4
- package/dist/react/{SketchEngine-UD2XV2KT.js → SketchEngine-OPJON7TD.js} +26 -26
- package/dist/react/{UndoRedo-IN4SXDG6.js → UndoRedo-QVNRI5OB.js} +8 -2
- package/dist/react/{arrowTool-OYDWJGQK.js → arrowTool-VH3PJPDM.js} +3 -3
- package/dist/react/{chunk-LSHZYN77.js → chunk-2DZHO67H.js} +2 -2
- package/dist/react/{chunk-XOWNCYE4.js → chunk-5NHJJJBZ.js} +3 -3
- package/dist/react/chunk-6AIFXYV6.js +31 -0
- package/dist/react/chunk-6AIFXYV6.js.map +7 -0
- package/dist/react/{chunk-K5RY4EV7.js → chunk-6GPWSPJF.js} +9 -5
- package/dist/react/{chunk-K5RY4EV7.js.map → chunk-6GPWSPJF.js.map} +2 -2
- package/dist/react/{chunk-ASBC5G35.js → chunk-B6CYUZC4.js} +2 -2
- package/dist/react/{chunk-OP56XPWF.js → chunk-DNFPTVIP.js} +2 -2
- package/dist/react/{chunk-XYUFEIZR.js → chunk-DWEFPKDO.js} +2 -2
- package/dist/react/{chunk-GQUZPON4.js → chunk-F56XUE5S.js} +4 -4
- package/dist/react/{chunk-7CM5XQDN.js → chunk-G3DJQY65.js} +20 -36
- package/dist/react/chunk-G3DJQY65.js.map +7 -0
- package/dist/react/{chunk-LJR7EVW2.js → chunk-JEGLUNBC.js} +3 -3
- package/dist/react/{chunk-6GPEWDRB.js → chunk-M7GAB24F.js} +52 -6
- package/dist/react/chunk-M7GAB24F.js.map +7 -0
- package/dist/react/{chunk-VQVEPJSA.js → chunk-MHV5P6TS.js} +2 -1
- package/dist/react/chunk-MHV5P6TS.js.map +7 -0
- package/dist/react/{chunk-PXFPPO3R.js → chunk-NH3NVSWT.js} +18 -2
- package/dist/react/chunk-NH3NVSWT.js.map +7 -0
- package/dist/react/{chunk-XFL4R5ZF.js → chunk-OK4ROGMM.js} +16 -35
- package/dist/react/chunk-OK4ROGMM.js.map +7 -0
- package/dist/react/{chunk-APTOPAOY.js → chunk-SSFEN5CY.js} +3 -3
- package/dist/react/{chunk-RGMDWLRJ.js → chunk-UEL2G6D2.js} +3 -3
- package/dist/react/{chunk-M6TMN76K.js → chunk-ULPIHUVC.js} +3 -3
- package/dist/react/{chunk-FETTJLCV.js → chunk-VZPH7OAM.js} +14 -22
- package/dist/react/chunk-VZPH7OAM.js.map +7 -0
- package/dist/react/{chunk-TKXKJNTX.js → chunk-W7XUY4GR.js} +16 -19
- package/dist/react/chunk-W7XUY4GR.js.map +7 -0
- package/dist/react/{chunk-EOURRJ55.js → chunk-XSE4HQ2D.js} +2 -2
- package/dist/react/{chunk-K5BG5MHY.js → chunk-ZNZAICWY.js} +36 -60
- package/dist/react/chunk-ZNZAICWY.js.map +7 -0
- package/dist/react/{circleTool-LDKGZALF.js → circleTool-2UODOBCV.js} +4 -4
- package/dist/react/{codeTool-4YZO5W7J.js → codeTool-F4RV7SAI.js} +4 -4
- package/dist/react/{frameTool-MXNJEXQQ.js → frameTool-NTGA5BI6.js} +4 -4
- package/dist/react/{freehandTool-26D3FOOX.js → freehandTool-L55EUB5C.js} +4 -4
- package/dist/react/{iconTool-46O5VEUX.js → iconTool-KQQBLGR3.js} +4 -4
- package/dist/react/{imageTool-P2RWZRHO.js → imageTool-LDJ45AD7.js} +4 -4
- package/dist/react/index.js +148 -37
- package/dist/react/index.js.map +4 -4
- package/dist/react/{lineTool-ZMR27U5L.js → lineTool-CSAFD7PW.js} +4 -4
- package/dist/react/{rectangleTool-EJKK6UTX.js → rectangleTool-YPD2SIIZ.js} +4 -4
- package/dist/react/{textTool-S4XXZHZH.js → textTool-VQHMWEFJ.js} +5 -5
- package/package.json +5 -2
- package/src/core/AIRenderer.js +8 -2
- package/src/core/CanvasSpace.js +28 -0
- package/src/core/GraphRenderer.js +8 -3
- package/src/core/LixScriptParser.js +7 -1
- package/src/core/MermaidFlowchartRenderer.js +5 -1
- package/src/core/MermaidSequenceParser.js +1 -0
- package/src/core/MermaidSequenceRenderer.js +8 -3
- package/src/core/MermaidStructuredRenderer.js +6 -1
- package/src/core/SceneSerializer.js +121 -38
- package/src/core/Selection.js +12 -2
- package/src/core/UndoRedo.js +59 -5
- package/src/react/components/AppMenu.jsx +20 -19
- package/src/react/components/canvas/CanvasRulers.jsx +8 -13
- package/src/react/components/canvas/SVGCanvas.jsx +2 -1
- package/src/react/components/canvas/rulerUnits.js +28 -0
- package/src/react/components/sidebars/PaintBucketSidebar.jsx +1 -1
- package/src/react/store/useSketchStore.js +24 -3
- package/src/react/store/useUIStore.js +24 -1
- package/src/react/utils/canvasBackgrounds.js +29 -0
- package/src/shapes/Circle.js +12 -19
- package/src/shapes/Frame.js +38 -69
- package/src/shapes/FreehandStroke.js +24 -1
- package/src/shapes/Rectangle.js +10 -22
- package/src/tools/circleTool.js +3 -27
- package/src/tools/paintBucketTool.js +72 -15
- package/src/tools/rectangleTool.js +7 -23
- package/src/tools/shapeRecognition.js +270 -0
- package/src/tools/shapeRecognitionTool.js +36 -183
- package/dist/react/AIRenderer-SRF7LU5K.js.map +0 -7
- package/dist/react/Circle-6POZCUZD.js +0 -9
- package/dist/react/EventDispatcher-7LAK7GQ7.js.map +0 -7
- package/dist/react/Frame-7D2MXCFF.js +0 -11
- package/dist/react/GraphEngine-MM6ALA2N.js.map +0 -7
- package/dist/react/IconShape-ZADX7Y33.js +0 -10
- package/dist/react/ImageShape-UJQN2HI7.js +0 -10
- package/dist/react/Line-APEULMHE.js +0 -10
- package/dist/react/LixScriptParser-JYWJX375.js.map +0 -7
- package/dist/react/MermaidFlowchartRenderer-PQEC4TMI.js.map +0 -7
- package/dist/react/MermaidSequenceParser-UKG2NSZY.js +0 -8
- package/dist/react/MermaidSequenceRenderer-KCUHO7UI.js.map +0 -7
- package/dist/react/MermaidStructuredRenderer-W7UKN7BM.js.map +0 -7
- package/dist/react/Rectangle-S7XUKWYD.js +0 -9
- package/dist/react/SceneSerializer-SG6SJN5X.js.map +0 -7
- package/dist/react/chunk-6GPEWDRB.js.map +0 -7
- package/dist/react/chunk-7CM5XQDN.js.map +0 -7
- package/dist/react/chunk-FETTJLCV.js.map +0 -7
- package/dist/react/chunk-K5BG5MHY.js.map +0 -7
- package/dist/react/chunk-PXFPPO3R.js.map +0 -7
- package/dist/react/chunk-TKXKJNTX.js.map +0 -7
- package/dist/react/chunk-VQVEPJSA.js.map +0 -7
- package/dist/react/chunk-XFL4R5ZF.js.map +0 -7
- /package/dist/react/{Circle-6POZCUZD.js.map → Circle-HMM5PKJ2.js.map} +0 -0
- /package/dist/react/{Frame-7D2MXCFF.js.map → Frame-QEUEYITT.js.map} +0 -0
- /package/dist/react/{FreehandStroke-U6GYZOM4.js.map → FreehandStroke-WXIJKD5I.js.map} +0 -0
- /package/dist/react/{IconShape-ZADX7Y33.js.map → IconShape-NHJE4YBY.js.map} +0 -0
- /package/dist/react/{ImageShape-UJQN2HI7.js.map → ImageShape-33VCMSDP.js.map} +0 -0
- /package/dist/react/{Line-APEULMHE.js.map → Line-A6FE232Q.js.map} +0 -0
- /package/dist/react/{MermaidSequenceParser-UKG2NSZY.js.map → MermaidSequenceParser-DBYXW23P.js.map} +0 -0
- /package/dist/react/{Rectangle-S7XUKWYD.js.map → Rectangle-4U4CD2ER.js.map} +0 -0
- /package/dist/react/{Selection-2TSH3J6P.js.map → Selection-23MOLHEI.js.map} +0 -0
- /package/dist/react/{SketchEngine-UD2XV2KT.js.map → SketchEngine-OPJON7TD.js.map} +0 -0
- /package/dist/react/{UndoRedo-IN4SXDG6.js.map → UndoRedo-QVNRI5OB.js.map} +0 -0
- /package/dist/react/{arrowTool-OYDWJGQK.js.map → arrowTool-VH3PJPDM.js.map} +0 -0
- /package/dist/react/{chunk-LSHZYN77.js.map → chunk-2DZHO67H.js.map} +0 -0
- /package/dist/react/{chunk-XOWNCYE4.js.map → chunk-5NHJJJBZ.js.map} +0 -0
- /package/dist/react/{chunk-ASBC5G35.js.map → chunk-B6CYUZC4.js.map} +0 -0
- /package/dist/react/{chunk-OP56XPWF.js.map → chunk-DNFPTVIP.js.map} +0 -0
- /package/dist/react/{chunk-XYUFEIZR.js.map → chunk-DWEFPKDO.js.map} +0 -0
- /package/dist/react/{chunk-GQUZPON4.js.map → chunk-F56XUE5S.js.map} +0 -0
- /package/dist/react/{chunk-LJR7EVW2.js.map → chunk-JEGLUNBC.js.map} +0 -0
- /package/dist/react/{chunk-APTOPAOY.js.map → chunk-SSFEN5CY.js.map} +0 -0
- /package/dist/react/{chunk-RGMDWLRJ.js.map → chunk-UEL2G6D2.js.map} +0 -0
- /package/dist/react/{chunk-M6TMN76K.js.map → chunk-ULPIHUVC.js.map} +0 -0
- /package/dist/react/{chunk-EOURRJ55.js.map → chunk-XSE4HQ2D.js.map} +0 -0
- /package/dist/react/{circleTool-LDKGZALF.js.map → circleTool-2UODOBCV.js.map} +0 -0
- /package/dist/react/{codeTool-4YZO5W7J.js.map → codeTool-F4RV7SAI.js.map} +0 -0
- /package/dist/react/{frameTool-MXNJEXQQ.js.map → frameTool-NTGA5BI6.js.map} +0 -0
- /package/dist/react/{freehandTool-26D3FOOX.js.map → freehandTool-L55EUB5C.js.map} +0 -0
- /package/dist/react/{iconTool-46O5VEUX.js.map → iconTool-KQQBLGR3.js.map} +0 -0
- /package/dist/react/{imageTool-P2RWZRHO.js.map → imageTool-LDJ45AD7.js.map} +0 -0
- /package/dist/react/{lineTool-ZMR27U5L.js.map → lineTool-CSAFD7PW.js.map} +0 -0
- /package/dist/react/{rectangleTool-EJKK6UTX.js.map → rectangleTool-YPD2SIIZ.js.map} +0 -0
- /package/dist/react/{textTool-S4XXZHZH.js.map → textTool-VQHMWEFJ.js.map} +0 -0
package/dist/react/index.js
CHANGED
|
@@ -16,8 +16,41 @@ import { useCallback as useCallback17, useEffect as useEffect20, useRef as useRe
|
|
|
16
16
|
|
|
17
17
|
// src/react/store/useSketchStore.js
|
|
18
18
|
import { create } from "zustand";
|
|
19
|
+
|
|
20
|
+
// src/react/utils/canvasBackgrounds.js
|
|
21
|
+
var CANVAS_BACKGROUNDS = {
|
|
22
|
+
light: [
|
|
23
|
+
{ color: "#FBE4DB", label: "menu.canvasBg.white" },
|
|
24
|
+
{ color: "#F6DBC0", label: "menu.canvasBg.cream" },
|
|
25
|
+
{ color: "#F5EED2", label: "menu.canvasBg.paper" },
|
|
26
|
+
{ color: "#F5F2ED", label: "menu.canvasBg.skyTint" },
|
|
27
|
+
{ color: "#F5DABF", label: "menu.canvasBg.sageTint" }
|
|
28
|
+
],
|
|
29
|
+
dark: [
|
|
30
|
+
{ color: "#000000", label: "menu.canvasBg.black" },
|
|
31
|
+
{ color: "#161718", label: "menu.canvasBg.darkGray" },
|
|
32
|
+
{ color: "#15111f", label: "menu.canvasBg.blueBlack" },
|
|
33
|
+
{ color: "#181605", label: "menu.canvasBg.darkYellow" },
|
|
34
|
+
{ color: "#1B1615", label: "menu.canvasBg.darkBrown" }
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
var DEFAULT_CANVAS_BACKGROUNDS = { dark: "#15111f", light: "#F5F2ED" };
|
|
38
|
+
var canvasBackgroundStorageKey = (theme) => `lixsketch-canvas-background-${theme}`;
|
|
39
|
+
function readCanvasBackground(theme, storage) {
|
|
40
|
+
const resolved = theme === "light" ? "light" : "dark";
|
|
41
|
+
try {
|
|
42
|
+
const stored = storage?.getItem(canvasBackgroundStorageKey(resolved));
|
|
43
|
+
const match = CANVAS_BACKGROUNDS[resolved].find(({ color }) => color.toLowerCase() === stored?.toLowerCase());
|
|
44
|
+
if (match) return match.color;
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
return DEFAULT_CANVAS_BACKGROUNDS[resolved];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/react/store/useSketchStore.js
|
|
19
51
|
var GRID_STORAGE_KEY = "lixsketch-grid-enabled";
|
|
20
52
|
var RULER_STORAGE_KEY = "lixsketch-rulers-enabled";
|
|
53
|
+
var RULER_UNIT_STORAGE_KEY = "lixsketch-ruler-unit";
|
|
21
54
|
var TOOLS = {
|
|
22
55
|
SELECT: "select",
|
|
23
56
|
PAN: "pan",
|
|
@@ -174,13 +207,25 @@ var useSketchStore = create((set, get) => ({
|
|
|
174
207
|
setIsPanning: (v) => set({ isPanning: v }),
|
|
175
208
|
setPanStart: (p) => set({ panStart: p }),
|
|
176
209
|
// --- Canvas background ---
|
|
177
|
-
canvasBackground:
|
|
178
|
-
|
|
179
|
-
|
|
210
|
+
canvasBackground: DEFAULT_CANVAS_BACKGROUNDS.dark,
|
|
211
|
+
canvasBackgrounds: { ...DEFAULT_CANVAS_BACKGROUNDS },
|
|
212
|
+
setCanvasBackground: (color, theme = "dark") => {
|
|
213
|
+
const resolved = theme === "light" ? "light" : "dark";
|
|
214
|
+
set((state) => ({ canvasBackground: color, canvasBackgrounds: { ...state.canvasBackgrounds, [resolved]: color } }));
|
|
180
215
|
if (typeof window !== "undefined") {
|
|
216
|
+
try {
|
|
217
|
+
localStorage.setItem(canvasBackgroundStorageKey(resolved), color);
|
|
218
|
+
} catch {
|
|
219
|
+
}
|
|
181
220
|
requestAnimationFrame(() => window.__adaptCanvasContrast?.(color));
|
|
182
221
|
}
|
|
183
222
|
},
|
|
223
|
+
restoreCanvasBackground: (theme) => {
|
|
224
|
+
const resolved = theme === "light" ? "light" : "dark";
|
|
225
|
+
const color = readCanvasBackground(resolved, typeof window === "undefined" ? null : localStorage);
|
|
226
|
+
set((state) => ({ canvasBackground: color, canvasBackgrounds: { ...state.canvasBackgrounds, [resolved]: color } }));
|
|
227
|
+
if (typeof window !== "undefined") requestAnimationFrame(() => window.__adaptCanvasContrast?.(color));
|
|
228
|
+
},
|
|
184
229
|
// --- Grid ---
|
|
185
230
|
gridEnabled: false,
|
|
186
231
|
toggleGrid: () => set((s) => {
|
|
@@ -205,6 +250,7 @@ var useSketchStore = create((set, get) => ({
|
|
|
205
250
|
},
|
|
206
251
|
// --- Rulers ---
|
|
207
252
|
rulersEnabled: false,
|
|
253
|
+
rulerUnit: "px",
|
|
208
254
|
toggleRulers: () => set((s) => {
|
|
209
255
|
const rulersEnabled = !s.rulersEnabled;
|
|
210
256
|
if (typeof window !== "undefined") {
|
|
@@ -215,6 +261,16 @@ var useSketchStore = create((set, get) => ({
|
|
|
215
261
|
}
|
|
216
262
|
return { rulersEnabled };
|
|
217
263
|
}),
|
|
264
|
+
setRulerUnit: (unit) => {
|
|
265
|
+
const rulerUnit = ["px", "cm", "in"].includes(unit) ? unit : "px";
|
|
266
|
+
if (typeof window !== "undefined") {
|
|
267
|
+
try {
|
|
268
|
+
localStorage.setItem(RULER_UNIT_STORAGE_KEY, rulerUnit);
|
|
269
|
+
} catch {
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
set({ rulerUnit });
|
|
273
|
+
},
|
|
218
274
|
hydrateRulers: () => {
|
|
219
275
|
if (typeof window === "undefined") return;
|
|
220
276
|
try {
|
|
@@ -222,6 +278,8 @@ var useSketchStore = create((set, get) => ({
|
|
|
222
278
|
if (saved === "true" || saved === "false") {
|
|
223
279
|
set({ rulersEnabled: saved === "true" });
|
|
224
280
|
}
|
|
281
|
+
const savedUnit = localStorage.getItem(RULER_UNIT_STORAGE_KEY);
|
|
282
|
+
if (["px", "cm", "in"].includes(savedUnit)) set({ rulerUnit: savedUnit });
|
|
225
283
|
} catch {
|
|
226
284
|
}
|
|
227
285
|
},
|
|
@@ -371,6 +429,20 @@ function invertShapeColors(prevResolved, nextResolved) {
|
|
|
371
429
|
}
|
|
372
430
|
}
|
|
373
431
|
}
|
|
432
|
+
function readStoredTheme() {
|
|
433
|
+
if (typeof window === "undefined") return "dark";
|
|
434
|
+
try {
|
|
435
|
+
const theme = localStorage.getItem("theme");
|
|
436
|
+
if (theme && ["dark", "light", "system"].includes(theme)) return theme;
|
|
437
|
+
} catch {
|
|
438
|
+
}
|
|
439
|
+
try {
|
|
440
|
+
const prefs = JSON.parse(localStorage.getItem("lix_ui_prefs") || "{}");
|
|
441
|
+
return ["dark", "light", "system"].includes(prefs.theme) ? prefs.theme : "dark";
|
|
442
|
+
} catch {
|
|
443
|
+
return "dark";
|
|
444
|
+
}
|
|
445
|
+
}
|
|
374
446
|
function applyTheme(theme) {
|
|
375
447
|
const body = document.body;
|
|
376
448
|
if (!body) return;
|
|
@@ -452,13 +524,22 @@ var useUIStore = create2((set, get) => ({
|
|
|
452
524
|
canvasLoadingMessage: "Loading canvas...",
|
|
453
525
|
setCanvasLoading: (loading, message) => set({ canvasLoading: loading, canvasLoadingMessage: message || "Loading canvas..." }),
|
|
454
526
|
// --- Theme ---
|
|
455
|
-
theme:
|
|
527
|
+
theme: readStoredTheme(),
|
|
456
528
|
setTheme: (newTheme) => {
|
|
457
529
|
const prev = get().theme;
|
|
458
530
|
const resolve = (t) => t === "system" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : t;
|
|
459
531
|
invertShapeColors(resolve(prev), resolve(newTheme));
|
|
460
532
|
applyTheme(newTheme);
|
|
461
533
|
set({ theme: newTheme });
|
|
534
|
+
useSketchStore_default.getState().restoreCanvasBackground(resolve(newTheme));
|
|
535
|
+
if (typeof window !== "undefined") {
|
|
536
|
+
try {
|
|
537
|
+
localStorage.setItem("theme", newTheme);
|
|
538
|
+
const prefs = JSON.parse(localStorage.getItem("lix_ui_prefs") || "{}");
|
|
539
|
+
localStorage.setItem("lix_ui_prefs", JSON.stringify({ ...prefs, theme: newTheme }));
|
|
540
|
+
} catch {
|
|
541
|
+
}
|
|
542
|
+
}
|
|
462
543
|
},
|
|
463
544
|
// --- Language / i18n ---
|
|
464
545
|
language: "en",
|
|
@@ -544,7 +625,7 @@ function useSketchEngine(svgRef, ready = true) {
|
|
|
544
625
|
setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
|
|
545
626
|
getState: () => useSketchStore_default.getState()
|
|
546
627
|
};
|
|
547
|
-
const { SketchEngine } = await import("./SketchEngine-
|
|
628
|
+
const { SketchEngine } = await import("./SketchEngine-OPJON7TD.js");
|
|
548
629
|
if (cancelled) return;
|
|
549
630
|
const engine = new SketchEngine(svgRef.current);
|
|
550
631
|
await engine.init();
|
|
@@ -581,6 +662,34 @@ function useSketchEngine(svgRef, ready = true) {
|
|
|
581
662
|
|
|
582
663
|
// src/react/components/canvas/CanvasRulers.jsx
|
|
583
664
|
import { useEffect as useEffect2, useMemo, useState } from "react";
|
|
665
|
+
|
|
666
|
+
// src/react/components/canvas/rulerUnits.js
|
|
667
|
+
var RULER_UNITS = ["px", "cm", "in"];
|
|
668
|
+
var PIXELS_PER_UNIT = { px: 1, cm: 96 / 2.54, in: 96 };
|
|
669
|
+
function normalizeRulerUnit(unit) {
|
|
670
|
+
return RULER_UNITS.includes(unit) ? unit : "px";
|
|
671
|
+
}
|
|
672
|
+
function convertRulerValue(pixelValue, unit = "px") {
|
|
673
|
+
return pixelValue / PIXELS_PER_UNIT[normalizeRulerUnit(unit)];
|
|
674
|
+
}
|
|
675
|
+
function formatRulerValue(pixelValue, unit = "px", suffix = false) {
|
|
676
|
+
const normalized = normalizeRulerUnit(unit);
|
|
677
|
+
const converted = convertRulerValue(pixelValue, normalized);
|
|
678
|
+
let label;
|
|
679
|
+
if (normalized === "px") {
|
|
680
|
+
const rounded = Math.round(converted);
|
|
681
|
+
const absolute = Math.abs(rounded);
|
|
682
|
+
if (absolute >= 1e6) label = `${Number((rounded / 1e6).toFixed(1))}m`;
|
|
683
|
+
else if (absolute >= 1e4) label = `${Number((rounded / 1e3).toFixed(1))}k`;
|
|
684
|
+
else label = String(rounded);
|
|
685
|
+
} else {
|
|
686
|
+
const precision = Math.abs(converted) < 10 ? 2 : Math.abs(converted) < 100 ? 1 : 0;
|
|
687
|
+
label = String(Number(converted.toFixed(precision)));
|
|
688
|
+
}
|
|
689
|
+
return suffix ? `${label} ${normalized}` : label;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// src/react/components/canvas/CanvasRulers.jsx
|
|
584
693
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
585
694
|
var GRID_SIZE = 20;
|
|
586
695
|
var MIN_LABEL_GAP = 52;
|
|
@@ -594,13 +703,6 @@ function getRulerStep(zoom) {
|
|
|
594
703
|
}
|
|
595
704
|
return GRID_SIZE;
|
|
596
705
|
}
|
|
597
|
-
function formatDimension(value) {
|
|
598
|
-
const rounded = Math.round(value);
|
|
599
|
-
const absolute = Math.abs(rounded);
|
|
600
|
-
if (absolute >= 1e6) return `${Number((rounded / 1e6).toFixed(1))}m`;
|
|
601
|
-
if (absolute >= 1e4) return `${Number((rounded / 1e3).toFixed(1))}k`;
|
|
602
|
-
return String(rounded);
|
|
603
|
-
}
|
|
604
706
|
function buildTicks(start, extent, zoom, step) {
|
|
605
707
|
const first = Math.floor(start / step) * step;
|
|
606
708
|
const last = start + extent / zoom;
|
|
@@ -610,7 +712,8 @@ function buildTicks(start, extent, zoom, step) {
|
|
|
610
712
|
}
|
|
611
713
|
return ticks;
|
|
612
714
|
}
|
|
613
|
-
function CanvasRulers({ enabled, svgRef }) {
|
|
715
|
+
function CanvasRulers({ enabled, svgRef, unit = "px" }) {
|
|
716
|
+
const rulerUnit = normalizeRulerUnit(unit);
|
|
614
717
|
const [viewport, setViewport] = useState({ x: 0, y: 0, zoom: 1, width: 0, height: 0, rulerLeft: 64, rulerTop: 48 });
|
|
615
718
|
const [pointer, setPointer] = useState({ x: 0, y: 0, visible: false });
|
|
616
719
|
useEffect2(() => {
|
|
@@ -680,14 +783,15 @@ function CanvasRulers({ enabled, svgRef }) {
|
|
|
680
783
|
const pointerWorldY = viewport.y + pointer.y / viewport.zoom;
|
|
681
784
|
return /* @__PURE__ */ jsxs("div", { className: "pointer-events-none absolute inset-0 z-[900] select-none text-text-muted", "aria-hidden": "true", children: [
|
|
682
785
|
/* @__PURE__ */ jsxs("div", { className: "absolute right-0 overflow-hidden border-b border-border-light bg-surface/95 shadow-sm backdrop-blur-sm", style: { height: RULER_SIZE, left: horizontalStart, top: viewport.rulerTop }, children: [
|
|
683
|
-
horizontalTicks.map(({ value, position }) => /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 h-2 border-l border-text-dim", style: { left: position - horizontalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute bottom-2 left-1 font-mono text-[9px] leading-none tabular-nums", children:
|
|
684
|
-
pointerInDrawingArea && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 border-l border-accent", style: { left: pointer.x - horizontalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute left-1 top-1 rounded bg-accent px-1 font-mono text-[9px] leading-4 text-white shadow-sm", children:
|
|
786
|
+
horizontalTicks.map(({ value, position }) => /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 h-2 border-l border-text-dim", style: { left: position - horizontalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute bottom-2 left-1 font-mono text-[9px] leading-none tabular-nums", children: formatRulerValue(value, rulerUnit) }) }, value)),
|
|
787
|
+
pointerInDrawingArea && /* @__PURE__ */ jsx("div", { className: "absolute inset-y-0 border-l border-accent", style: { left: pointer.x - horizontalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute left-1 top-1 rounded bg-accent px-1 font-mono text-[9px] leading-4 text-white shadow-sm", children: formatRulerValue(pointerWorldX, rulerUnit, true) }) })
|
|
685
788
|
] }),
|
|
686
789
|
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-0 overflow-hidden border-r border-border-light bg-surface/95 shadow-sm backdrop-blur-sm", style: { width: RULER_SIZE, left: viewport.rulerLeft, top: verticalStart }, children: [
|
|
687
|
-
verticalTicks.map(({ value, position }) => /* @__PURE__ */ jsx("div", { className: "absolute right-0 w-2 border-t border-text-dim", style: { top: position - verticalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute right-2 top-1 font-mono text-[9px] leading-none tabular-nums", style: { transform: "rotate(-90deg)", transformOrigin: "top right" }, children:
|
|
688
|
-
pointerInDrawingArea && /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 border-t border-accent", style: { top: pointer.y - verticalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 rounded bg-accent px-1 font-mono text-[9px] leading-4 text-white shadow-sm", style: { transform: "rotate(-90deg)", transformOrigin: "top right" }, children:
|
|
790
|
+
verticalTicks.map(({ value, position }) => /* @__PURE__ */ jsx("div", { className: "absolute right-0 w-2 border-t border-text-dim", style: { top: position - verticalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute right-2 top-1 font-mono text-[9px] leading-none tabular-nums", style: { transform: "rotate(-90deg)", transformOrigin: "top right" }, children: formatRulerValue(value, rulerUnit) }) }, value)),
|
|
791
|
+
pointerInDrawingArea && /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 border-t border-accent", style: { top: pointer.y - verticalStart }, children: /* @__PURE__ */ jsx("span", { className: "absolute right-1 top-1 rounded bg-accent px-1 font-mono text-[9px] leading-4 text-white shadow-sm", style: { transform: "rotate(-90deg)", transformOrigin: "top right" }, children: formatRulerValue(pointerWorldY, rulerUnit, true) }) })
|
|
689
792
|
] }),
|
|
690
793
|
/* @__PURE__ */ jsxs("div", { className: "absolute border-b border-r border-border-light bg-accent/20", style: { width: RULER_SIZE, height: RULER_SIZE, left: viewport.rulerLeft, top: viewport.rulerTop }, children: [
|
|
794
|
+
/* @__PURE__ */ jsx("span", { className: "absolute bottom-0.5 left-1 font-mono text-[8px] uppercase text-accent", children: rulerUnit }),
|
|
691
795
|
/* @__PURE__ */ jsx("span", { className: "absolute left-1/2 top-1/2 h-2.5 -translate-x-1/2 -translate-y-1/2 border-l border-accent" }),
|
|
692
796
|
/* @__PURE__ */ jsx("span", { className: "absolute left-1/2 top-1/2 w-2.5 -translate-x-1/2 -translate-y-1/2 border-t border-accent" })
|
|
693
797
|
] }),
|
|
@@ -709,6 +813,7 @@ function SVGCanvas() {
|
|
|
709
813
|
const gridEnabled = useSketchStore_default((s) => s.gridEnabled);
|
|
710
814
|
const hydrateGrid = useSketchStore_default((s) => s.hydrateGrid);
|
|
711
815
|
const rulersEnabled = useSketchStore_default((s) => s.rulersEnabled);
|
|
816
|
+
const rulerUnit = useSketchStore_default((s) => s.rulerUnit);
|
|
712
817
|
const hydrateRulers = useSketchStore_default((s) => s.hydrateRulers);
|
|
713
818
|
const getCursor = useSketchStore_default((s) => s.getCursor);
|
|
714
819
|
const cursor = getCursor();
|
|
@@ -837,7 +942,7 @@ function SVGCanvas() {
|
|
|
837
942
|
]
|
|
838
943
|
}
|
|
839
944
|
),
|
|
840
|
-
/* @__PURE__ */ jsx2(CanvasRulers, { enabled: rulersEnabled, svgRef })
|
|
945
|
+
/* @__PURE__ */ jsx2(CanvasRulers, { enabled: rulersEnabled, svgRef, unit: rulerUnit })
|
|
841
946
|
] });
|
|
842
947
|
}
|
|
843
948
|
|
|
@@ -1210,20 +1315,6 @@ function useTranslation() {
|
|
|
1210
1315
|
|
|
1211
1316
|
// src/react/components/AppMenu.jsx
|
|
1212
1317
|
import { Fragment as Fragment4, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1213
|
-
var CANVAS_BACKGROUNDS_LIGHT = [
|
|
1214
|
-
{ color: "#ffffff", label: "menu.canvasBg.white" },
|
|
1215
|
-
{ color: "#fbf9fd", label: "menu.canvasBg.cream" },
|
|
1216
|
-
{ color: "#f5f3ed", label: "menu.canvasBg.paper" },
|
|
1217
|
-
{ color: "#f0f5fb", label: "menu.canvasBg.skyTint" },
|
|
1218
|
-
{ color: "#f0f5ef", label: "menu.canvasBg.sageTint" }
|
|
1219
|
-
];
|
|
1220
|
-
var CANVAS_BACKGROUNDS_DARK = [
|
|
1221
|
-
{ color: "#000000", label: "menu.canvasBg.black" },
|
|
1222
|
-
{ color: "#161718", label: "menu.canvasBg.darkGray" },
|
|
1223
|
-
{ color: "#15111f", label: "menu.canvasBg.blueBlack" },
|
|
1224
|
-
{ color: "#181605", label: "menu.canvasBg.darkYellow" },
|
|
1225
|
-
{ color: "#1B1615", label: "menu.canvasBg.darkBrown" }
|
|
1226
|
-
];
|
|
1227
1318
|
function DangerWarningDialog({ action, workspaceName, onCancel, onConfirm }) {
|
|
1228
1319
|
useEffect5(() => {
|
|
1229
1320
|
if (!action) return void 0;
|
|
@@ -1325,6 +1416,8 @@ function AppMenu() {
|
|
|
1325
1416
|
const toggleGrid = useSketchStore_default((s) => s.toggleGrid);
|
|
1326
1417
|
const rulersEnabled = useSketchStore_default((s) => s.rulersEnabled);
|
|
1327
1418
|
const toggleRulers = useSketchStore_default((s) => s.toggleRulers);
|
|
1419
|
+
const rulerUnit = useSketchStore_default((s) => s.rulerUnit);
|
|
1420
|
+
const setRulerUnit = useSketchStore_default((s) => s.setRulerUnit);
|
|
1328
1421
|
const viewMode = useSketchStore_default((s) => s.viewMode);
|
|
1329
1422
|
const zenMode = useSketchStore_default((s) => s.zenMode);
|
|
1330
1423
|
const toolLock = useSketchStore_default((s) => s.toolLock);
|
|
@@ -1493,7 +1586,25 @@ function AppMenu() {
|
|
|
1493
1586
|
children: [
|
|
1494
1587
|
/* @__PURE__ */ jsx5("option", { value: "en", children: "English" }),
|
|
1495
1588
|
/* @__PURE__ */ jsx5("option", { value: "bg", children: "\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438" }),
|
|
1496
|
-
/* @__PURE__ */ jsx5("option", { value: "de", children: "Deutsch" })
|
|
1589
|
+
/* @__PURE__ */ jsx5("option", { value: "de", children: "Deutsch" }),
|
|
1590
|
+
/* @__PURE__ */ jsx5("option", { value: "hi", children: "\u0939\u093F\u0928\u094D\u0926\u0940" })
|
|
1591
|
+
]
|
|
1592
|
+
}
|
|
1593
|
+
)
|
|
1594
|
+
] }),
|
|
1595
|
+
/* @__PURE__ */ jsxs5("div", { className: "w-full flex items-center justify-between px-3 py-2 border-b border-border-light text-text-secondary text-[11px]", children: [
|
|
1596
|
+
/* @__PURE__ */ jsx5("span", { children: "Ruler unit" }),
|
|
1597
|
+
/* @__PURE__ */ jsxs5(
|
|
1598
|
+
"select",
|
|
1599
|
+
{
|
|
1600
|
+
"aria-label": "Ruler unit",
|
|
1601
|
+
className: "cursor-pointer rounded border border-border-light bg-surface-hover px-1 text-[10px] uppercase text-text-primary outline-none",
|
|
1602
|
+
value: rulerUnit,
|
|
1603
|
+
onChange: (event) => setRulerUnit(event.target.value),
|
|
1604
|
+
children: [
|
|
1605
|
+
/* @__PURE__ */ jsx5("option", { value: "px", children: "px" }),
|
|
1606
|
+
/* @__PURE__ */ jsx5("option", { value: "cm", children: "cm" }),
|
|
1607
|
+
/* @__PURE__ */ jsx5("option", { value: "in", children: "in" })
|
|
1497
1608
|
]
|
|
1498
1609
|
}
|
|
1499
1610
|
)
|
|
@@ -1633,10 +1744,10 @@ function AppMenu() {
|
|
|
1633
1744
|
] }),
|
|
1634
1745
|
/* @__PURE__ */ jsxs5("div", { className: "px-3 py-2", children: [
|
|
1635
1746
|
/* @__PURE__ */ jsx5("p", { className: "text-text-dim text-xs uppercase tracking-wider mb-2", children: t("menu.canvasBackground") }),
|
|
1636
|
-
/* @__PURE__ */ jsx5("div", { className: "flex items-center gap-1.5", children:
|
|
1747
|
+
/* @__PURE__ */ jsx5("div", { className: "flex items-center gap-1.5", children: CANVAS_BACKGROUNDS[theme === "light" ? "light" : "dark"].map((bg) => /* @__PURE__ */ jsx5(
|
|
1637
1748
|
"button",
|
|
1638
1749
|
{
|
|
1639
|
-
onClick: () => setCanvasBackground(bg.color),
|
|
1750
|
+
onClick: () => setCanvasBackground(bg.color, theme === "light" ? "light" : "dark"),
|
|
1640
1751
|
title: t(bg.label),
|
|
1641
1752
|
className: `w-7 h-7 rounded-full border-2 cursor-pointer transition-all duration-200 ${canvasBackground === bg.color ? "border-accent scale-110" : "border-border hover:border-border-light"}`,
|
|
1642
1753
|
style: { backgroundColor: bg.color }
|
|
@@ -2081,7 +2192,7 @@ function PaintBucketSidebar() {
|
|
|
2081
2192
|
fill.label
|
|
2082
2193
|
] }, fill.value)) })
|
|
2083
2194
|
] }),
|
|
2084
|
-
/* @__PURE__ */ jsx9("div", { className: "max-w-[185px] px-2 text-[10px] leading-4 text-text-dim", children: "
|
|
2195
|
+
/* @__PURE__ */ jsx9("div", { className: "max-w-[185px] px-2 text-[10px] leading-4 text-text-dim", children: "Fill rectangles, circles, frames, and closed freehand shapes. Lines and arrows are left unchanged." })
|
|
2085
2196
|
] });
|
|
2086
2197
|
}
|
|
2087
2198
|
|
|
@@ -4995,7 +5106,7 @@ var _saveScene = null;
|
|
|
4995
5106
|
var _loadScene = null;
|
|
4996
5107
|
async function ensureSceneSerializer() {
|
|
4997
5108
|
if (_saveScene && _loadScene) return;
|
|
4998
|
-
const m = await import("./SceneSerializer-
|
|
5109
|
+
const m = await import("./SceneSerializer-JEYTYXZQ.js");
|
|
4999
5110
|
_saveScene = m.saveScene;
|
|
5000
5111
|
_loadScene = m.loadScene;
|
|
5001
5112
|
}
|