@mhamz.01/easyflow-whiteboard 1.12.0 → 1.14.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.
- package/dist/components/node/custom-node-overlay-layer.d.ts.map +1 -1
- package/dist/components/node/custom-node-overlay-layer.js +12 -61
- package/dist/components/whiteboard/whiteboard-test.d.ts.map +1 -1
- package/dist/components/whiteboard/whiteboard-test.js +4 -0
- package/dist/hooks/useSelection.d.ts +2 -1
- package/dist/hooks/useSelection.d.ts.map +1 -1
- package/dist/hooks/useSelection.js +15 -7
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAaD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"custom-node-overlay-layer.d.ts","sourceRoot":"","sources":["../../../src/components/node/custom-node-overlay-layer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM9C,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,uBAAuB;IAC/B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;IACxC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzE,qBAAqB,CAAC,EAAE,YAAY,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAaD,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,KAAK,EACL,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,UAAc,EACd,cAA+B,EAC/B,YAAmB,EACnB,qBAA0B,EAC1B,YAAY,GACb,EAAE,uBAAuB,2CAsdzB"}
|
|
@@ -22,57 +22,6 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
22
22
|
// ── Sync props → local state ────────────────────────────────────────────────
|
|
23
23
|
useEffect(() => { setLocalTasks(tasks); }, [tasks]);
|
|
24
24
|
useEffect(() => { setLocalDocuments(documents); }, [documents]);
|
|
25
|
-
// ----Sync with Fabric canvas-------------------------------------------------
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
const canvas = fabricCanvas?.current;
|
|
28
|
-
if (!canvas)
|
|
29
|
-
return;
|
|
30
|
-
const handleSelectionCleared = () => {
|
|
31
|
-
setSelectedIds(new Set());
|
|
32
|
-
};
|
|
33
|
-
const handleMouseDown = (e) => {
|
|
34
|
-
if (!e.target) {
|
|
35
|
-
setSelectedIds(new Set());
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
canvas.on("selection:cleared", handleSelectionCleared);
|
|
39
|
-
canvas.on("mouse:down", handleMouseDown);
|
|
40
|
-
return () => {
|
|
41
|
-
canvas.off("selection:cleared", handleSelectionCleared);
|
|
42
|
-
canvas.off("mouse:down", handleMouseDown);
|
|
43
|
-
};
|
|
44
|
-
}, [fabricCanvas]);
|
|
45
|
-
// 3. Update your existing keyboard handler to include clearing on click outside
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
const handleKeyDown = (e) => {
|
|
48
|
-
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)
|
|
49
|
-
return;
|
|
50
|
-
// Clear selection on Escape
|
|
51
|
-
if (e.key === "Escape") {
|
|
52
|
-
setSelectedIds(new Set());
|
|
53
|
-
fabricCanvas?.current?.discardActiveObject();
|
|
54
|
-
fabricCanvas?.current?.renderAll();
|
|
55
|
-
}
|
|
56
|
-
// Select All
|
|
57
|
-
if ((e.ctrlKey || e.metaKey) && e.key === "a") {
|
|
58
|
-
e.preventDefault();
|
|
59
|
-
setSelectedIds(new Set([...localTasks.map((t) => t.id), ...localDocuments.map((d) => d.id)]));
|
|
60
|
-
}
|
|
61
|
-
// Delete
|
|
62
|
-
if ((e.key === "Delete" || e.key === "Backspace") && selectedIds.size > 0) {
|
|
63
|
-
e.preventDefault();
|
|
64
|
-
const updatedTasks = localTasks.filter((t) => !selectedIds.has(t.id));
|
|
65
|
-
const updatedDocs = localDocuments.filter((d) => !selectedIds.has(d.id));
|
|
66
|
-
setLocalTasks(updatedTasks);
|
|
67
|
-
setLocalDocuments(updatedDocs);
|
|
68
|
-
setSelectedIds(new Set());
|
|
69
|
-
onTasksUpdate?.(updatedTasks);
|
|
70
|
-
onDocumentsUpdate?.(updatedDocs);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
window.addEventListener("keydown", handleKeyDown);
|
|
74
|
-
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
75
|
-
}, [localTasks, localDocuments, selectedIds, fabricCanvas, onTasksUpdate, onDocumentsUpdate]);
|
|
76
25
|
// ── Event Forwarding (Fixes Zooming on Nodes) ───────────────────────────────
|
|
77
26
|
const handleOverlayWheel = (e) => {
|
|
78
27
|
if (e.ctrlKey || e.metaKey || e.shiftKey) {
|
|
@@ -179,15 +128,22 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
179
128
|
return { x: doc.x, y: doc.y };
|
|
180
129
|
return undefined;
|
|
181
130
|
};
|
|
131
|
+
// In CanvasOverlayLayer, update isItemInSelectionBox to recalculate offset
|
|
182
132
|
const isItemInSelectionBox = (x, y, width, height, box) => {
|
|
133
|
+
// Get FRESH overlay offset (handles sidebar open/close)
|
|
134
|
+
const overlayRect = overlayRef.current?.getBoundingClientRect();
|
|
135
|
+
if (!overlayRect)
|
|
136
|
+
return false;
|
|
137
|
+
// Item position in screen space (relative to whiteboard container)
|
|
183
138
|
const itemX1 = x * canvasZoom + canvasViewport.x;
|
|
184
139
|
const itemY1 = y * canvasZoom + canvasViewport.y;
|
|
185
140
|
const itemX2 = itemX1 + width * canvasZoom;
|
|
186
141
|
const itemY2 = itemY1 + height * canvasZoom;
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
const
|
|
190
|
-
const
|
|
142
|
+
// Selection box adjusted for overlay offset
|
|
143
|
+
const boxX1 = Math.min(box.x1, box.x2) - overlayRect.left;
|
|
144
|
+
const boxY1 = Math.min(box.y1, box.y2) - overlayRect.top;
|
|
145
|
+
const boxX2 = Math.max(box.x1, box.x2) - overlayRect.left;
|
|
146
|
+
const boxY2 = Math.max(box.y1, box.y2) - overlayRect.top;
|
|
191
147
|
return !(boxX2 < itemX1 || boxX1 > itemX2 || boxY2 < itemY1 || boxY1 > itemY2);
|
|
192
148
|
};
|
|
193
149
|
// ── Selection box detection ──────────────────────────────────────────────────
|
|
@@ -395,13 +351,8 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
395
351
|
}, children: children }, id));
|
|
396
352
|
};
|
|
397
353
|
return (_jsx("div", { ref: overlayRef, className: "absolute inset-0 pointer-events-none", style: { zIndex: 50 }, onWheel: handleOverlayWheel, onClick: (e) => {
|
|
398
|
-
|
|
399
|
-
if (e.target === e.currentTarget) {
|
|
354
|
+
if (e.target === e.currentTarget)
|
|
400
355
|
setSelectedIds(new Set());
|
|
401
|
-
// Also clear Fabric selection
|
|
402
|
-
fabricCanvas?.current?.discardActiveObject();
|
|
403
|
-
fabricCanvas?.current?.renderAll();
|
|
404
|
-
}
|
|
405
356
|
}, children: _jsxs("div", { className: "absolute top-0 left-0 pointer-events-none", style: {
|
|
406
357
|
transform: `translate(${canvasViewport.x}px, ${canvasViewport.y}px)`,
|
|
407
358
|
transformOrigin: "top left",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whiteboard-test.d.ts","sourceRoot":"","sources":["../../../src/components/whiteboard/whiteboard-test.tsx"],"names":[],"mappings":"AA4CA,MAAM,CAAC,OAAO,UAAU,gBAAgB,
|
|
1
|
+
{"version":3,"file":"whiteboard-test.d.ts","sourceRoot":"","sources":["../../../src/components/whiteboard/whiteboard-test.tsx"],"names":[],"mappings":"AA4CA,MAAM,CAAC,OAAO,UAAU,gBAAgB,4CAqQvC"}
|
|
@@ -134,6 +134,7 @@ export default function FabricWhiteboard() {
|
|
|
134
134
|
setSelectionBox,
|
|
135
135
|
setSelectedCanvasObjects,
|
|
136
136
|
isDrawingRef,
|
|
137
|
+
clearCustomNodeSelection: () => setSelectedIds(new Set()), // ← ADD THIS
|
|
137
138
|
});
|
|
138
139
|
// Text style updates
|
|
139
140
|
useTextStyle({
|
|
@@ -205,3 +206,6 @@ export default function FabricWhiteboard() {
|
|
|
205
206
|
zIndex: 0,
|
|
206
207
|
} }), _jsx("canvas", { ref: canvasRef, className: "absolute inset-0", style: { zIndex: 1 } }), _jsx(CanvasOverlayLayer, { tasks: tasks, documents: documents, onTasksUpdate: setTasks, onDocumentsUpdate: setDocuments, canvasZoom: canvasZoom, canvasViewport: canvasViewport, selectionBox: selectionBox, selectedCanvasObjects: selectedCanvasObjects, fabricCanvas: fabricCanvasRef }), _jsxs("div", { className: "absolute inset-0 pointer-events-none", style: { zIndex: 100 }, children: [_jsx("div", { className: "pointer-events-auto", children: _jsx(WhiteboardToolbar, { fabricCanvas: fabricCanvasRef, isRestoringRef: isRestoringRef, onAddTask: handleAddTaskFromDropdown, onAddDocument: handleAddDocumentFromDropdown }) }), _jsx("div", { className: "pointer-events-auto", children: _jsx(ToolOptionsPanel, { fabricCanvas: fabricCanvasRef }) }), _jsx("div", { className: "pointer-events-auto", children: _jsx(ZoomControls, { zoom: canvasZoom, onZoomIn: handleZoomIn, onZoomOut: handleZoomOut, onResetZoom: handleResetZoom }) })] })] }) }));
|
|
207
208
|
}
|
|
209
|
+
function setSelectedIds(arg0) {
|
|
210
|
+
throw new Error("Function not implemented.");
|
|
211
|
+
}
|
|
@@ -15,7 +15,8 @@ interface UseSelectionProps {
|
|
|
15
15
|
} | null) => void;
|
|
16
16
|
setSelectedCanvasObjects: (objects: FabricObject[]) => void;
|
|
17
17
|
isDrawingRef: React.MutableRefObject<boolean>;
|
|
18
|
+
clearCustomNodeSelection?: () => void;
|
|
18
19
|
}
|
|
19
|
-
export declare const useSelection: ({ fabricCanvas, activeTool, canvasZoom, canvasViewport, setSelectionBox, setSelectedCanvasObjects, isDrawingRef, }: UseSelectionProps) => void;
|
|
20
|
+
export declare const useSelection: ({ fabricCanvas, activeTool, canvasZoom, canvasViewport, setSelectionBox, setSelectedCanvasObjects, isDrawingRef, clearCustomNodeSelection, }: UseSelectionProps) => void;
|
|
20
21
|
export {};
|
|
21
22
|
//# sourceMappingURL=useSelection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSelection.d.ts","sourceRoot":"","sources":["../../src/hooks/useSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAQ,YAAY,EAAe,MAAM,QAAQ,CAAC;AAMjE,UAAU,iBAAiB;IACzB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,eAAe,EAAE,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1F,wBAAwB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAC5D,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"useSelection.d.ts","sourceRoot":"","sources":["../../src/hooks/useSelection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAQ,YAAY,EAAe,MAAM,QAAQ,CAAC;AAMjE,UAAU,iBAAiB;IACzB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,eAAe,EAAE,CAAC,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1F,wBAAwB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAC5D,YAAY,EAAE,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC9C,wBAAwB,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,eAAO,MAAM,YAAY,GAAI,8IAS1B,iBAAiB,SA2KnB,CAAC"}
|
|
@@ -5,7 +5,8 @@ import { Frame } from "../lib/fabric-frame";
|
|
|
5
5
|
import { Arrow } from "../lib/fabric-arrow";
|
|
6
6
|
import { BidirectionalArrow } from "../lib/fabric-bidirectional-arrow";
|
|
7
7
|
import { useWhiteboardStore } from "../store/whiteboard-store";
|
|
8
|
-
export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewport, setSelectionBox, setSelectedCanvasObjects, isDrawingRef,
|
|
8
|
+
export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewport, setSelectionBox, setSelectedCanvasObjects, isDrawingRef, clearCustomNodeSelection, // ← Add this
|
|
9
|
+
}) => {
|
|
9
10
|
const setSelectedObjectType = useWhiteboardStore((state) => state.setSelectedObjectType);
|
|
10
11
|
const setActiveTool = useWhiteboardStore((state) => state.setActiveTool);
|
|
11
12
|
useEffect(() => {
|
|
@@ -54,19 +55,15 @@ export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewp
|
|
|
54
55
|
});
|
|
55
56
|
selRect.setCoords();
|
|
56
57
|
canvas.renderAll();
|
|
57
|
-
//
|
|
58
|
-
// FIX: Get canvas element offset from viewport
|
|
59
|
-
// ═══════════════════════════════════════════════════════════════
|
|
58
|
+
// Get FRESH canvas offset on every move (handles sidebar open/close)
|
|
60
59
|
const canvasElement = canvas.getElement();
|
|
61
60
|
const rect = canvasElement.getBoundingClientRect();
|
|
62
|
-
// Calculate selection box in screen coordinates (including canvas offset)
|
|
63
61
|
setSelectionBox({
|
|
64
62
|
x1: Math.min(selStart.x, p.x) * canvasZoom + canvasViewport.x + rect.left,
|
|
65
63
|
y1: Math.min(selStart.y, p.y) * canvasZoom + canvasViewport.y + rect.top,
|
|
66
64
|
x2: Math.max(selStart.x, p.x) * canvasZoom + canvasViewport.x + rect.left,
|
|
67
65
|
y2: Math.max(selStart.y, p.y) * canvasZoom + canvasViewport.y + rect.top,
|
|
68
66
|
});
|
|
69
|
-
// ═══════════════════════════════════════════════════════════════
|
|
70
67
|
});
|
|
71
68
|
};
|
|
72
69
|
const onUp = () => {
|
|
@@ -113,16 +110,25 @@ export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewp
|
|
|
113
110
|
setSelectedObjectType(null);
|
|
114
111
|
setSelectionBox(null);
|
|
115
112
|
setSelectedCanvasObjects([]);
|
|
113
|
+
// ← ADD: Clear custom node selection too
|
|
114
|
+
clearCustomNodeSelection?.();
|
|
116
115
|
if (!isDrawingRef.current && activeTool !== "select" && activeTool !== "pan") {
|
|
117
116
|
setActiveTool("select");
|
|
118
117
|
}
|
|
119
118
|
};
|
|
119
|
+
// ← ADD: Clear custom nodes when clicking empty canvas
|
|
120
|
+
const handleCanvasClick = (e) => {
|
|
121
|
+
if (!e.target && activeTool === "select") {
|
|
122
|
+
clearCustomNodeSelection?.();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
120
125
|
canvas.on("selection:created", onSelected);
|
|
121
126
|
canvas.on("selection:updated", onSelected);
|
|
122
127
|
canvas.on("selection:cleared", onDeselected);
|
|
123
128
|
canvas.on("mouse:down", onDown);
|
|
124
129
|
canvas.on("mouse:move", onMove);
|
|
125
130
|
canvas.on("mouse:up", onUp);
|
|
131
|
+
canvas.on("mouse:down", handleCanvasClick); // ← ADD
|
|
126
132
|
return () => {
|
|
127
133
|
canvas.off("selection:created", onSelected);
|
|
128
134
|
canvas.off("selection:updated", onSelected);
|
|
@@ -130,6 +136,7 @@ export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewp
|
|
|
130
136
|
canvas.off("mouse:down", onDown);
|
|
131
137
|
canvas.off("mouse:move", onMove);
|
|
132
138
|
canvas.off("mouse:up", onUp);
|
|
139
|
+
canvas.off("mouse:down", handleCanvasClick); // ← ADD
|
|
133
140
|
if (rafId !== null)
|
|
134
141
|
cancelAnimationFrame(rafId);
|
|
135
142
|
if (selRect)
|
|
@@ -144,6 +151,7 @@ export const useSelection = ({ fabricCanvas, activeTool, canvasZoom, canvasViewp
|
|
|
144
151
|
setSelectedCanvasObjects,
|
|
145
152
|
setSelectedObjectType,
|
|
146
153
|
setActiveTool,
|
|
147
|
-
isDrawingRef
|
|
154
|
+
isDrawingRef,
|
|
155
|
+
clearCustomNodeSelection // ← ADD
|
|
148
156
|
]);
|
|
149
157
|
};
|