@mhamz.01/easyflow-whiteboard 2.48.0 → 2.51.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 +1 -0
- package/dist/components/node/custom-node-overlay-layer.d.ts.map +1 -1
- package/dist/components/node/custom-node-overlay-layer.js +35 -8
- package/dist/components/whiteboard/whiteboard-test.d.ts.map +1 -1
- package/dist/components/whiteboard/whiteboard-test.js +3 -1
- package/dist/hooks/useCanvasInit.d.ts +2 -1
- package/dist/hooks/useCanvasInit.d.ts.map +1 -1
- package/dist/hooks/useCanvasInit.js +2 -1
- package/package.json +1 -1
|
@@ -38,6 +38,7 @@ interface CanvasOverlayLayerProps {
|
|
|
38
38
|
} | null;
|
|
39
39
|
selectedCanvasObjects?: FabricObject[];
|
|
40
40
|
fabricCanvas?: React.RefObject<Canvas | null>;
|
|
41
|
+
canvasReady?: boolean;
|
|
41
42
|
}
|
|
42
43
|
export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, onDocumentsUpdate, canvasZoom, canvasViewport, selectionBox, selectedCanvasObjects, fabricCanvas, }: CanvasOverlayLayerProps): import("react/jsx-runtime").JSX.Element;
|
|
43
44
|
export {};
|
|
@@ -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;AAS9C,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;
|
|
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;AAS9C,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;IAC9C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;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,2CA2jBzB"}
|
|
@@ -9,6 +9,7 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
9
9
|
const [localDocuments, setLocalDocuments] = useState(documents);
|
|
10
10
|
const [selectedIds, setSelectedIds] = useState(new Set());
|
|
11
11
|
const [dragging, setDragging] = useState(null);
|
|
12
|
+
const [canvasReady, setCanvasReady] = useState(false);
|
|
12
13
|
const dragStateRef = useRef({
|
|
13
14
|
isDragging: false,
|
|
14
15
|
itemIds: [],
|
|
@@ -24,6 +25,23 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
24
25
|
// ── Sync props → local state ────────────────────────────────────────────────
|
|
25
26
|
useEffect(() => { setLocalTasks(tasks); }, [tasks]);
|
|
26
27
|
useEffect(() => { setLocalDocuments(documents); }, [documents]);
|
|
28
|
+
// effect — polls until fabricCanvas.current is available:
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (canvasReady)
|
|
31
|
+
return;
|
|
32
|
+
if (fabricCanvas?.current) {
|
|
33
|
+
setCanvasReady(true);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
// Poll every 50ms until canvas is ready (only needed on first load)
|
|
37
|
+
const interval = setInterval(() => {
|
|
38
|
+
if (fabricCanvas?.current) {
|
|
39
|
+
setCanvasReady(true);
|
|
40
|
+
clearInterval(interval);
|
|
41
|
+
}
|
|
42
|
+
}, 50);
|
|
43
|
+
return () => clearInterval(interval);
|
|
44
|
+
}, [fabricCanvas, canvasReady]);
|
|
27
45
|
// ── Event Forwarding (Fixes Zooming on Nodes) ───────────────────────────────
|
|
28
46
|
const handleOverlayWheel = (e) => {
|
|
29
47
|
if (e.ctrlKey || e.metaKey || e.shiftKey) {
|
|
@@ -84,7 +102,7 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
84
102
|
return () => {
|
|
85
103
|
overlayEl.removeEventListener("wheel", handleGlobalWheel);
|
|
86
104
|
};
|
|
87
|
-
}, [fabricCanvas, canvasZoom]); // Re-bind when zoom changes to keep closure fresh
|
|
105
|
+
}, [fabricCanvas, canvasZoom, canvasReady]); // Re-bind when zoom changes to keep closure fresh
|
|
88
106
|
// ── Fabric → Overlay Sync (Fixes Dragging from Fabric area) ──────────────────
|
|
89
107
|
useEffect(() => {
|
|
90
108
|
const canvas = fabricCanvas?.current;
|
|
@@ -115,26 +133,35 @@ export default function CanvasOverlayLayer({ tasks, documents, onTasksUpdate, on
|
|
|
115
133
|
setSelectedIds(new Set());
|
|
116
134
|
return;
|
|
117
135
|
}
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
136
|
+
// At zoom=1 with identity VPT, getActiveObject() can return null before
|
|
137
|
+
// Fabric updates _activeObject. Use e.transform as the primary check —
|
|
138
|
+
// it is populated by Fabric's hit-test regardless of zoom level.
|
|
139
|
+
const transformTarget = e.transform?.target;
|
|
140
|
+
const activeObject = canvas.getActiveObject();
|
|
141
|
+
const activeObjects = canvas.getActiveObjects();
|
|
142
|
+
const isPartOfActiveSelection = transformTarget === target || // most reliable — direct from event
|
|
143
|
+
activeObject === target || // selection box group
|
|
144
|
+
activeObjects.includes(target); // individual object in multi-select
|
|
145
|
+
if (!isPartOfActiveSelection) {
|
|
124
146
|
setSelectedIds(new Set());
|
|
125
147
|
}
|
|
126
148
|
};
|
|
149
|
+
const handleSelectionCleared = () => {
|
|
150
|
+
setSelectedIds(new Set());
|
|
151
|
+
};
|
|
127
152
|
canvas.on("object:moving", handleObjectMoving);
|
|
128
153
|
canvas.on("mouse:down", handleMouseDown);
|
|
154
|
+
canvas.on("selection:cleared", handleSelectionCleared);
|
|
129
155
|
return () => {
|
|
130
156
|
canvas.off("object:moving", handleObjectMoving);
|
|
131
157
|
canvas.off("mouse:down", handleMouseDown);
|
|
158
|
+
canvas.off("selection:cleared", handleSelectionCleared);
|
|
132
159
|
};
|
|
133
160
|
// ── selectedIds REMOVED from deps — read via selectedIdsRef instead ──────
|
|
134
161
|
// Having selectedIds here caused the effect to re-register on every selection
|
|
135
162
|
// change, creating a new closure each time. The second drag captured a stale
|
|
136
163
|
// or empty selectedIds from the closure at re-registration time.
|
|
137
|
-
}, [canvasZoom, fabricCanvas]);
|
|
164
|
+
}, [canvasZoom, fabricCanvas, canvasReady]);
|
|
138
165
|
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
139
166
|
const getItemPosition = (id) => {
|
|
140
167
|
const task = localTasks.find((t) => t.id === id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whiteboard-test.d.ts","sourceRoot":"","sources":["../../../src/components/whiteboard/whiteboard-test.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAkBlE,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAIxE,UAAU,IAAI;IACZ,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,UAAU,qBAAqB;IAC7B,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,GAAG,EAAE,CAAC;QACb,SAAS,EAAE,GAAG,EAAE,CAAC;KAClB,KAAK,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,WAAW,EACX,MAAM,EACN,cAAc,GACf,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"whiteboard-test.d.ts","sourceRoot":"","sources":["../../../src/components/whiteboard/whiteboard-test.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mCAAmC,CAAC;AAkBlE,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAIxE,UAAU,IAAI;IACZ,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,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,UAAU,qBAAqB;IAC7B,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,GAAG,EAAE,CAAC;QACb,SAAS,EAAE,GAAG,EAAE,CAAC;KAClB,KAAK,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACvC,WAAW,EACX,MAAM,EACN,cAAc,GACf,EAAE,qBAAqB,2CAqPvB"}
|
|
@@ -44,6 +44,7 @@ export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs,
|
|
|
44
44
|
const pushHistory = useWhiteboardStore((state) => state.pushHistory);
|
|
45
45
|
// State
|
|
46
46
|
const [tasks, setTasks] = useState([]);
|
|
47
|
+
const [canvasReady, setCanvasReady] = useState(false);
|
|
47
48
|
const [documents, setDocuments] = useState([]);
|
|
48
49
|
const [canvasZoom, setCanvasZoom] = useState(1);
|
|
49
50
|
const [canvasViewport, setCanvasViewport] = useState({ x: 0, y: 0 });
|
|
@@ -63,6 +64,7 @@ export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs,
|
|
|
63
64
|
setTasks,
|
|
64
65
|
setDocuments,
|
|
65
66
|
initialData,
|
|
67
|
+
onReady: () => setCanvasReady(true),
|
|
66
68
|
});
|
|
67
69
|
// CHANGE 3: Pass onSave and saveDebounceMs to usePersistence (replaces localStorage.setItem)
|
|
68
70
|
usePersistence({
|
|
@@ -194,5 +196,5 @@ export default function FabricWhiteboard({ initialData, onSave, saveDebounceMs,
|
|
|
194
196
|
backgroundImage: `radial-gradient(circle, rgba(255,255,255,0.2) 1.2px, transparent 1.2px)`,
|
|
195
197
|
backgroundSize: "40px 40px",
|
|
196
198
|
zIndex: 0,
|
|
197
|
-
} }), _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 }) })] })] }) }));
|
|
199
|
+
} }), _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, canvasReady: canvasReady }), _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 }) })] })] }) }));
|
|
198
200
|
}
|
|
@@ -15,7 +15,8 @@ interface UseCanvasInitProps {
|
|
|
15
15
|
setTasks: (tasks: any[]) => void;
|
|
16
16
|
setDocuments: (docs: any[]) => void;
|
|
17
17
|
initialData?: WhiteboardInitialData;
|
|
18
|
+
onReady?: () => void;
|
|
18
19
|
}
|
|
19
|
-
export declare const useCanvasInit: ({ canvasRef, fabricCanvasRef, activeTool, suppressHistoryRef, isRestoringRef, pushHistory, setTasks, setDocuments, initialData, }: UseCanvasInitProps) => void;
|
|
20
|
+
export declare const useCanvasInit: ({ canvasRef, fabricCanvasRef, activeTool, suppressHistoryRef, isRestoringRef, pushHistory, setTasks, setDocuments, initialData, onReady, }: UseCanvasInitProps) => void;
|
|
20
21
|
export {};
|
|
21
22
|
//# sourceMappingURL=useCanvasInit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCanvasInit.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasInit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,
|
|
1
|
+
{"version":3,"file":"useCanvasInit.d.ts","sourceRoot":"","sources":["../../src/hooks/useCanvasInit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,SAAS,EAAY,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAKhC,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAK,MAAM,CAAC;IACnB,KAAK,CAAC,EAAM,GAAG,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;CACnB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAW,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACxD,eAAe,EAAK,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC7C,UAAU,EAAU,MAAM,CAAC;IAC3B,kBAAkB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,cAAc,EAAM,SAAS,CAAC,OAAO,CAAC,CAAC;IACvC,WAAW,EAAS,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAY,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC3C,YAAY,EAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAQ,qBAAqB,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAID,eAAO,MAAM,aAAa,GAAI,4IAW3B,kBAAkB,SA0HpB,CAAC"}
|
|
@@ -2,7 +2,7 @@ import { useEffect } from "react";
|
|
|
2
2
|
import { Canvas } from "fabric";
|
|
3
3
|
import { initializeFabricCanvas, addWelcomeContent } from "../lib/fabric-utils";
|
|
4
4
|
// ─── Hook ─────────────────────────────────────────────────────────────────────
|
|
5
|
-
export const useCanvasInit = ({ canvasRef, fabricCanvasRef, activeTool, suppressHistoryRef, isRestoringRef, pushHistory, setTasks, setDocuments, initialData, }) => {
|
|
5
|
+
export const useCanvasInit = ({ canvasRef, fabricCanvasRef, activeTool, suppressHistoryRef, isRestoringRef, pushHistory, setTasks, setDocuments, initialData, onReady, }) => {
|
|
6
6
|
useEffect(() => {
|
|
7
7
|
if (!canvasRef.current || fabricCanvasRef.current)
|
|
8
8
|
return;
|
|
@@ -68,6 +68,7 @@ export const useCanvasInit = ({ canvasRef, fabricCanvasRef, activeTool, suppress
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
isRestoringRef.current = false;
|
|
71
|
+
onReady?.();
|
|
71
72
|
}
|
|
72
73
|
else {
|
|
73
74
|
if (!disposed) {
|