@bwp-web/canvas 0.8.2 → 0.9.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/context/CanvasRefContext.d.ts +17 -0
- package/dist/context/CanvasRefContext.d.ts.map +1 -0
- package/dist/context/EditCanvasContext.d.ts +53 -5
- package/dist/context/EditCanvasContext.d.ts.map +1 -1
- package/dist/context/ViewCanvasContext.d.ts +53 -6
- package/dist/context/ViewCanvasContext.d.ts.map +1 -1
- package/dist/context/index.d.ts +5 -4
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/useCanvasRef.d.ts +15 -0
- package/dist/context/useCanvasRef.d.ts.map +1 -0
- package/dist/hooks/useCanvasClick.d.ts +14 -0
- package/dist/hooks/useCanvasClick.d.ts.map +1 -1
- package/dist/hooks/useCanvasEvents.d.ts +13 -0
- package/dist/hooks/useCanvasEvents.d.ts.map +1 -1
- package/dist/hooks/useCanvasTooltip.d.ts +13 -0
- package/dist/hooks/useCanvasTooltip.d.ts.map +1 -1
- package/dist/hooks/useEditCanvas.d.ts +28 -3
- package/dist/hooks/useEditCanvas.d.ts.map +1 -1
- package/dist/hooks/useViewCanvas.d.ts +22 -0
- package/dist/hooks/useViewCanvas.d.ts.map +1 -1
- package/dist/index.cjs +432 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +417 -161
- package/dist/index.js.map +1 -1
- package/dist/overlay/FixedSizeContent.d.ts +1 -1
- package/dist/overlay/ObjectOverlay.d.ts +16 -3
- package/dist/overlay/ObjectOverlay.d.ts.map +1 -1
- package/dist/overlay/OverlayBadge.d.ts +1 -1
- package/dist/overlay/OverlayContent.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -79,11 +79,16 @@ __export(index_exports, {
|
|
|
79
79
|
snapCursorPoint: () => snapCursorPoint,
|
|
80
80
|
useCanvasClick: () => useCanvasClick,
|
|
81
81
|
useCanvasEvents: () => useCanvasEvents,
|
|
82
|
+
useCanvasRef: () => useCanvasRef,
|
|
82
83
|
useCanvasTooltip: () => useCanvasTooltip,
|
|
83
84
|
useEditCanvas: () => useEditCanvas,
|
|
84
85
|
useEditCanvasContext: () => useEditCanvasContext,
|
|
86
|
+
useEditCanvasState: () => useEditCanvasState,
|
|
87
|
+
useEditCanvasViewport: () => useEditCanvasViewport,
|
|
85
88
|
useViewCanvas: () => useViewCanvas,
|
|
86
89
|
useViewCanvasContext: () => useViewCanvasContext,
|
|
90
|
+
useViewCanvasState: () => useViewCanvasState,
|
|
91
|
+
useViewCanvasViewport: () => useViewCanvasViewport,
|
|
87
92
|
util: () => import_fabric19.util
|
|
88
93
|
});
|
|
89
94
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -2528,6 +2533,7 @@ function useEditCanvas(options) {
|
|
|
2528
2533
|
const vertexEditCleanupRef = (0, import_react3.useRef)(null);
|
|
2529
2534
|
const keyboardCleanupRef = (0, import_react3.useRef)(null);
|
|
2530
2535
|
const historyRef = (0, import_react3.useRef)(null);
|
|
2536
|
+
const isInitialLoadRef = (0, import_react3.useRef)(false);
|
|
2531
2537
|
const optionsRef = (0, import_react3.useRef)(options);
|
|
2532
2538
|
optionsRef.current = options;
|
|
2533
2539
|
const savedSelectabilityRef = (0, import_react3.useRef)(
|
|
@@ -2540,6 +2546,11 @@ function useEditCanvas(options) {
|
|
|
2540
2546
|
const [isDirty, setIsDirty] = (0, import_react3.useState)(false);
|
|
2541
2547
|
const [canUndo, setCanUndo] = (0, import_react3.useState)(false);
|
|
2542
2548
|
const [canRedo, setCanRedo] = (0, import_react3.useState)(false);
|
|
2549
|
+
const [objects, setObjects] = (0, import_react3.useState)([]);
|
|
2550
|
+
const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
|
|
2551
|
+
const [lockLightMode, setLockLightModeState] = (0, import_react3.useState)(
|
|
2552
|
+
void 0
|
|
2553
|
+
);
|
|
2543
2554
|
const setMode = (0, import_react3.useCallback)((setup) => {
|
|
2544
2555
|
vertexEditCleanupRef.current?.();
|
|
2545
2556
|
vertexEditCleanupRef.current = null;
|
|
@@ -2624,11 +2635,14 @@ function useEditCanvas(options) {
|
|
|
2624
2635
|
canvas.on("selection:created", (e) => setSelected(e.selected ?? []));
|
|
2625
2636
|
canvas.on("selection:updated", (e) => setSelected(e.selected ?? []));
|
|
2626
2637
|
canvas.on("selection:cleared", () => setSelected([]));
|
|
2627
|
-
if (opts?.trackChanges) {
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
canvas.on("
|
|
2638
|
+
if (opts?.trackChanges !== false) {
|
|
2639
|
+
const markDirtyIfNotLoading = () => {
|
|
2640
|
+
if (!isInitialLoadRef.current) setIsDirty(true);
|
|
2641
|
+
};
|
|
2642
|
+
canvas.on("object:added", markDirtyIfNotLoading);
|
|
2643
|
+
canvas.on("object:removed", markDirtyIfNotLoading);
|
|
2644
|
+
canvas.on("object:modified", markDirtyIfNotLoading);
|
|
2645
|
+
canvas.on("background:modified", markDirtyIfNotLoading);
|
|
2632
2646
|
}
|
|
2633
2647
|
if (opts?.history) {
|
|
2634
2648
|
const syncHistoryState = () => {
|
|
@@ -2666,8 +2680,31 @@ function useEditCanvas(options) {
|
|
|
2666
2680
|
}
|
|
2667
2681
|
}
|
|
2668
2682
|
function invokeOnReady() {
|
|
2669
|
-
const
|
|
2670
|
-
|
|
2683
|
+
const initPromise = (async () => {
|
|
2684
|
+
if (opts?.canvasData) {
|
|
2685
|
+
setIsLoading(true);
|
|
2686
|
+
isInitialLoadRef.current = true;
|
|
2687
|
+
try {
|
|
2688
|
+
const loaded = await loadCanvas(canvas, opts.canvasData, {
|
|
2689
|
+
filter: opts.filter,
|
|
2690
|
+
borderRadius: opts.borderRadius
|
|
2691
|
+
});
|
|
2692
|
+
setObjects(loaded);
|
|
2693
|
+
} finally {
|
|
2694
|
+
isInitialLoadRef.current = false;
|
|
2695
|
+
setIsLoading(false);
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
})();
|
|
2699
|
+
initPromise.then(async () => {
|
|
2700
|
+
const onReadyResult = opts?.onReady?.(canvas);
|
|
2701
|
+
await Promise.resolve(onReadyResult);
|
|
2702
|
+
if (opts?.invertBackground !== void 0) {
|
|
2703
|
+
setBackgroundInverted(canvas, opts.invertBackground);
|
|
2704
|
+
}
|
|
2705
|
+
if (canvas.lockLightMode !== void 0) {
|
|
2706
|
+
setLockLightModeState(canvas.lockLightMode);
|
|
2707
|
+
}
|
|
2671
2708
|
if (opts?.autoFitToBackground !== false && canvas.backgroundImage) {
|
|
2672
2709
|
fitViewportToBackground(canvas);
|
|
2673
2710
|
syncZoom(canvasRef, setZoom);
|
|
@@ -2697,37 +2734,25 @@ function useEditCanvas(options) {
|
|
|
2697
2734
|
alignmentCleanupRef.current = null;
|
|
2698
2735
|
}
|
|
2699
2736
|
}, [options?.enableAlignment]);
|
|
2737
|
+
(0, import_react3.useEffect)(() => {
|
|
2738
|
+
const canvas = canvasRef.current;
|
|
2739
|
+
if (!canvas || options?.invertBackground === void 0) return;
|
|
2740
|
+
setBackgroundInverted(canvas, options.invertBackground);
|
|
2741
|
+
}, [options?.invertBackground]);
|
|
2742
|
+
const setLockLightMode = (0, import_react3.useCallback)((value) => {
|
|
2743
|
+
const canvas = canvasRef.current;
|
|
2744
|
+
if (canvas) {
|
|
2745
|
+
canvas.lockLightMode = value;
|
|
2746
|
+
}
|
|
2747
|
+
setLockLightModeState(value);
|
|
2748
|
+
}, []);
|
|
2700
2749
|
const setViewportMode = (0, import_react3.useCallback)((mode) => {
|
|
2701
2750
|
viewportRef.current?.setMode(mode);
|
|
2702
2751
|
setViewportModeState(mode);
|
|
2703
2752
|
}, []);
|
|
2704
2753
|
const { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject, zoomToFit } = useViewportActions(canvasRef, viewportRef, setZoom);
|
|
2705
|
-
const
|
|
2706
|
-
|
|
2707
|
-
const canvas = canvasRef.current;
|
|
2708
|
-
if (!canvas) throw new Error("Canvas not ready");
|
|
2709
|
-
const opts = optionsRef.current;
|
|
2710
|
-
const resizeOpts = opts?.backgroundResize !== false ? typeof opts?.backgroundResize === "object" ? { ...opts.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveContrast ? { preserveContrast: true } : void 0;
|
|
2711
|
-
const img = await setBackgroundImage(canvas, url, resizeOpts);
|
|
2712
|
-
if (opts?.autoFitToBackground !== false) {
|
|
2713
|
-
fitViewportToBackground(canvas);
|
|
2714
|
-
syncZoom(canvasRef, setZoom);
|
|
2715
|
-
}
|
|
2716
|
-
return img;
|
|
2717
|
-
},
|
|
2718
|
-
[]
|
|
2719
|
-
);
|
|
2720
|
-
return {
|
|
2721
|
-
/** Pass this to `<Canvas onReady={...} />` */
|
|
2722
|
-
onReady,
|
|
2723
|
-
/** Ref to the underlying Fabric canvas instance. */
|
|
2724
|
-
canvasRef,
|
|
2725
|
-
/** Current zoom level (reactive). */
|
|
2726
|
-
zoom,
|
|
2727
|
-
/** Currently selected objects (reactive). */
|
|
2728
|
-
selected,
|
|
2729
|
-
/** Viewport controls. */
|
|
2730
|
-
viewport: {
|
|
2754
|
+
const viewport = (0, import_react3.useMemo)(
|
|
2755
|
+
() => ({
|
|
2731
2756
|
/** Current viewport mode (reactive). */
|
|
2732
2757
|
mode: viewportMode,
|
|
2733
2758
|
/** Switch between 'select' and 'pan' viewport modes. */
|
|
@@ -2742,61 +2767,125 @@ function useEditCanvas(options) {
|
|
|
2742
2767
|
panToObject,
|
|
2743
2768
|
/** Zoom and pan to fit a specific object in the viewport. */
|
|
2744
2769
|
zoomToFit
|
|
2770
|
+
}),
|
|
2771
|
+
[
|
|
2772
|
+
viewportMode,
|
|
2773
|
+
setViewportMode,
|
|
2774
|
+
resetViewport2,
|
|
2775
|
+
zoomIn,
|
|
2776
|
+
zoomOut,
|
|
2777
|
+
panToObject,
|
|
2778
|
+
zoomToFit
|
|
2779
|
+
]
|
|
2780
|
+
);
|
|
2781
|
+
const resetDirty = (0, import_react3.useCallback)(() => setIsDirty(false), []);
|
|
2782
|
+
const markDirty = (0, import_react3.useCallback)(() => setIsDirty(true), []);
|
|
2783
|
+
const undo = (0, import_react3.useCallback)(async () => {
|
|
2784
|
+
const h = historyRef.current;
|
|
2785
|
+
if (!h) return;
|
|
2786
|
+
await h.undo();
|
|
2787
|
+
setCanUndo(h.canUndo());
|
|
2788
|
+
setCanRedo(h.canRedo());
|
|
2789
|
+
}, []);
|
|
2790
|
+
const redo = (0, import_react3.useCallback)(async () => {
|
|
2791
|
+
const h = historyRef.current;
|
|
2792
|
+
if (!h) return;
|
|
2793
|
+
await h.redo();
|
|
2794
|
+
setCanUndo(h.canUndo());
|
|
2795
|
+
setCanRedo(h.canRedo());
|
|
2796
|
+
}, []);
|
|
2797
|
+
const setBackground = (0, import_react3.useCallback)(
|
|
2798
|
+
async (url, bgOpts) => {
|
|
2799
|
+
const canvas = canvasRef.current;
|
|
2800
|
+
if (!canvas) throw new Error("Canvas not ready");
|
|
2801
|
+
const opts = optionsRef.current;
|
|
2802
|
+
const resizeOpts = opts?.backgroundResize !== false ? typeof opts?.backgroundResize === "object" ? { ...opts.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveContrast ? { preserveContrast: true } : void 0;
|
|
2803
|
+
const img = await setBackgroundImage(canvas, url, resizeOpts);
|
|
2804
|
+
if (opts?.autoFitToBackground !== false) {
|
|
2805
|
+
fitViewportToBackground(canvas);
|
|
2806
|
+
syncZoom(canvasRef, setZoom);
|
|
2807
|
+
}
|
|
2808
|
+
return img;
|
|
2745
2809
|
},
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2810
|
+
[]
|
|
2811
|
+
);
|
|
2812
|
+
return (0, import_react3.useMemo)(
|
|
2813
|
+
() => ({
|
|
2814
|
+
/** Pass this to `<Canvas onReady={...} />` */
|
|
2815
|
+
onReady,
|
|
2816
|
+
/** Ref to the underlying Fabric canvas instance. */
|
|
2817
|
+
canvasRef,
|
|
2818
|
+
/** Current zoom level (reactive). */
|
|
2819
|
+
zoom,
|
|
2820
|
+
/** Loaded objects (reactive). Populated when `canvasData` is provided. */
|
|
2821
|
+
objects,
|
|
2822
|
+
/** Whether canvas data is currently being loaded. */
|
|
2823
|
+
isLoading,
|
|
2824
|
+
/** Currently selected objects (reactive). */
|
|
2825
|
+
selected,
|
|
2826
|
+
/** Viewport controls. */
|
|
2827
|
+
viewport,
|
|
2828
|
+
/** Whether vertex edit mode is currently active (reactive). */
|
|
2829
|
+
isEditingVertices,
|
|
2830
|
+
/**
|
|
2831
|
+
* Activate an interaction mode or return to select mode.
|
|
2832
|
+
*
|
|
2833
|
+
* Pass a setup function to activate a creation mode:
|
|
2834
|
+
* ```ts
|
|
2835
|
+
* canvas.setMode((c, viewport) =>
|
|
2836
|
+
* enableClickToCreate(c, factory, { viewport })
|
|
2837
|
+
* );
|
|
2838
|
+
* ```
|
|
2839
|
+
*
|
|
2840
|
+
* Pass `null` to deactivate and return to select mode:
|
|
2841
|
+
* ```ts
|
|
2842
|
+
* canvas.setMode(null);
|
|
2843
|
+
* ```
|
|
2844
|
+
*/
|
|
2845
|
+
setMode,
|
|
2846
|
+
/**
|
|
2847
|
+
* Set a background image from a URL. Automatically resizes if the image
|
|
2848
|
+
* exceeds the configured limits (opt out via `backgroundResize: false`),
|
|
2849
|
+
* and fits the viewport after setting if `autoFitToBackground` is enabled.
|
|
2850
|
+
*
|
|
2851
|
+
* Pass `{ preserveContrast: true }` to keep the current background contrast
|
|
2852
|
+
* when replacing the image.
|
|
2853
|
+
*/
|
|
2854
|
+
setBackground,
|
|
2855
|
+
/** Whether the canvas has been modified since the last `resetDirty()` call. Enabled by default (disable via `trackChanges: false`). */
|
|
2856
|
+
isDirty,
|
|
2857
|
+
/** Reset the dirty flag (e.g., after a successful save). */
|
|
2858
|
+
resetDirty,
|
|
2859
|
+
/** Manually mark the canvas as dirty (e.g., after a custom operation not tracked automatically). */
|
|
2860
|
+
markDirty,
|
|
2861
|
+
/** Undo the last change. Requires `history: true`. */
|
|
2862
|
+
undo,
|
|
2863
|
+
/** Redo a previously undone change. Requires `history: true`. */
|
|
2864
|
+
redo,
|
|
2865
|
+
/** Whether an undo operation is available (reactive). Requires `history: true`. */
|
|
2866
|
+
canUndo,
|
|
2867
|
+
/** Whether a redo operation is available (reactive). Requires `history: true`. */
|
|
2868
|
+
canRedo,
|
|
2869
|
+
/** Whether the canvas is locked to light mode. Read from loaded canvas data. */
|
|
2870
|
+
lockLightMode,
|
|
2871
|
+
/** Update lockLightMode on both the canvas instance and React state. */
|
|
2872
|
+
setLockLightMode
|
|
2873
|
+
}),
|
|
2874
|
+
// Only reactive state in deps — refs and stable callbacks are omitted
|
|
2875
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2876
|
+
[
|
|
2877
|
+
zoom,
|
|
2878
|
+
objects,
|
|
2879
|
+
isLoading,
|
|
2880
|
+
selected,
|
|
2881
|
+
viewport,
|
|
2882
|
+
isEditingVertices,
|
|
2883
|
+
isDirty,
|
|
2884
|
+
canUndo,
|
|
2885
|
+
canRedo,
|
|
2886
|
+
lockLightMode
|
|
2887
|
+
]
|
|
2888
|
+
);
|
|
2800
2889
|
}
|
|
2801
2890
|
|
|
2802
2891
|
// src/hooks/useViewCanvas.ts
|
|
@@ -2813,6 +2902,8 @@ function useViewCanvas(options) {
|
|
|
2813
2902
|
const optionsRef = (0, import_react4.useRef)(options);
|
|
2814
2903
|
optionsRef.current = options;
|
|
2815
2904
|
const [zoom, setZoom] = (0, import_react4.useState)(1);
|
|
2905
|
+
const [objects, setObjects] = (0, import_react4.useState)([]);
|
|
2906
|
+
const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
|
|
2816
2907
|
const onReady = (0, import_react4.useCallback)(
|
|
2817
2908
|
(canvas) => {
|
|
2818
2909
|
canvasRef.current = canvas;
|
|
@@ -2839,20 +2930,57 @@ function useViewCanvas(options) {
|
|
|
2839
2930
|
canvas.on("mouse:wheel", () => {
|
|
2840
2931
|
setZoom(canvas.getZoom());
|
|
2841
2932
|
});
|
|
2842
|
-
const
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2933
|
+
const initPromise = (async () => {
|
|
2934
|
+
if (opts?.canvasData) {
|
|
2935
|
+
setIsLoading(true);
|
|
2936
|
+
try {
|
|
2937
|
+
const loaded = await loadCanvas(canvas, opts.canvasData, {
|
|
2938
|
+
filter: opts.filter,
|
|
2939
|
+
borderRadius: opts.borderRadius
|
|
2940
|
+
});
|
|
2941
|
+
lockCanvas(canvas);
|
|
2942
|
+
setObjects(loaded);
|
|
2943
|
+
} finally {
|
|
2944
|
+
setIsLoading(false);
|
|
2848
2945
|
}
|
|
2849
|
-
}
|
|
2850
|
-
}
|
|
2946
|
+
}
|
|
2947
|
+
})();
|
|
2948
|
+
initPromise.then(async () => {
|
|
2949
|
+
const onReadyResult = opts?.onReady?.(canvas);
|
|
2950
|
+
await Promise.resolve(onReadyResult);
|
|
2951
|
+
if (opts?.invertBackground !== void 0) {
|
|
2952
|
+
setBackgroundInverted(canvas, opts.invertBackground);
|
|
2953
|
+
}
|
|
2954
|
+
if (opts?.autoFitToBackground !== false && canvas.backgroundImage) {
|
|
2955
|
+
fitViewportToBackground(canvas);
|
|
2956
|
+
syncZoom(canvasRef, setZoom);
|
|
2957
|
+
}
|
|
2958
|
+
});
|
|
2851
2959
|
},
|
|
2852
2960
|
// onReady and panAndZoom are intentionally excluded — we only initialize once
|
|
2853
2961
|
[]
|
|
2854
2962
|
);
|
|
2963
|
+
(0, import_react4.useEffect)(() => {
|
|
2964
|
+
const canvas = canvasRef.current;
|
|
2965
|
+
if (!canvas || options?.invertBackground === void 0) return;
|
|
2966
|
+
setBackgroundInverted(canvas, options.invertBackground);
|
|
2967
|
+
}, [options?.invertBackground]);
|
|
2855
2968
|
const { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject, zoomToFit } = useViewportActions(canvasRef, viewportRef, setZoom);
|
|
2969
|
+
const viewport = (0, import_react4.useMemo)(
|
|
2970
|
+
() => ({
|
|
2971
|
+
/** Reset viewport to default (no pan, zoom = 1), or fit to background if one is set. */
|
|
2972
|
+
reset: resetViewport2,
|
|
2973
|
+
/** Zoom in toward the canvas center. Default step: 0.2. */
|
|
2974
|
+
zoomIn,
|
|
2975
|
+
/** Zoom out from the canvas center. Default step: 0.2. */
|
|
2976
|
+
zoomOut,
|
|
2977
|
+
/** Pan the viewport to center on a specific object. */
|
|
2978
|
+
panToObject,
|
|
2979
|
+
/** Zoom and pan to fit a specific object in the viewport. */
|
|
2980
|
+
zoomToFit
|
|
2981
|
+
}),
|
|
2982
|
+
[resetViewport2, zoomIn, zoomOut, panToObject, zoomToFit]
|
|
2983
|
+
);
|
|
2856
2984
|
const findObject = (id) => {
|
|
2857
2985
|
const c = canvasRef.current;
|
|
2858
2986
|
if (!c) return void 0;
|
|
@@ -2868,9 +2996,9 @@ function useViewCanvas(options) {
|
|
|
2868
2996
|
(styles) => {
|
|
2869
2997
|
const c = canvasRef.current;
|
|
2870
2998
|
if (!c) return;
|
|
2871
|
-
const
|
|
2999
|
+
const objects2 = c.getObjects();
|
|
2872
3000
|
const idMap = /* @__PURE__ */ new Map();
|
|
2873
|
-
for (const obj of
|
|
3001
|
+
for (const obj of objects2) {
|
|
2874
3002
|
if (obj.data?.id) idMap.set(obj.data.id, obj);
|
|
2875
3003
|
}
|
|
2876
3004
|
let updated = false;
|
|
@@ -2900,42 +3028,58 @@ function useViewCanvas(options) {
|
|
|
2900
3028
|
},
|
|
2901
3029
|
[]
|
|
2902
3030
|
);
|
|
2903
|
-
return
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
setObjectStyleByType
|
|
2929
|
-
};
|
|
3031
|
+
return (0, import_react4.useMemo)(
|
|
3032
|
+
() => ({
|
|
3033
|
+
/** Pass this to `<Canvas onReady={...} />` */
|
|
3034
|
+
onReady,
|
|
3035
|
+
/** Ref to the underlying Fabric canvas instance. */
|
|
3036
|
+
canvasRef,
|
|
3037
|
+
/** Current zoom level (reactive). */
|
|
3038
|
+
zoom,
|
|
3039
|
+
/** Loaded objects (reactive). Populated when `canvasData` is provided. */
|
|
3040
|
+
objects,
|
|
3041
|
+
/** Whether canvas data is currently being loaded. */
|
|
3042
|
+
isLoading,
|
|
3043
|
+
/** Viewport controls. */
|
|
3044
|
+
viewport,
|
|
3045
|
+
/** Update a single object's visual style by its `data.id`. */
|
|
3046
|
+
setObjectStyle,
|
|
3047
|
+
/** Batch-update multiple objects' visual styles in one render. Keyed by `data.id`. */
|
|
3048
|
+
setObjectStyles,
|
|
3049
|
+
/** Apply a visual style to all objects whose `data.type` matches. */
|
|
3050
|
+
setObjectStyleByType
|
|
3051
|
+
}),
|
|
3052
|
+
// Only reactive state in deps — refs and stable callbacks are omitted
|
|
3053
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3054
|
+
[zoom, objects, isLoading, viewport]
|
|
3055
|
+
);
|
|
2930
3056
|
}
|
|
2931
3057
|
|
|
2932
3058
|
// src/hooks/useCanvasEvents.ts
|
|
3059
|
+
var import_react6 = require("react");
|
|
3060
|
+
|
|
3061
|
+
// src/context/CanvasRefContext.ts
|
|
2933
3062
|
var import_react5 = require("react");
|
|
2934
|
-
|
|
2935
|
-
|
|
3063
|
+
var CanvasRefContext = (0, import_react5.createContext)(null);
|
|
3064
|
+
function useCanvasRefContext() {
|
|
3065
|
+
return (0, import_react5.useContext)(CanvasRefContext);
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3068
|
+
// src/context/useCanvasRef.ts
|
|
3069
|
+
function useCanvasRef() {
|
|
3070
|
+
return useCanvasRefContext();
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
// src/hooks/useCanvasEvents.ts
|
|
3074
|
+
function useCanvasEvents(canvasRefOrEvents, maybeEvents) {
|
|
3075
|
+
const isContextOverload = maybeEvents === void 0;
|
|
3076
|
+
const contextCanvasRef = useCanvasRef();
|
|
3077
|
+
const resolvedCanvasRef = isContextOverload ? contextCanvasRef : canvasRefOrEvents;
|
|
3078
|
+
const events = isContextOverload ? canvasRefOrEvents : maybeEvents;
|
|
3079
|
+
const eventsRef = (0, import_react6.useRef)(events);
|
|
2936
3080
|
eventsRef.current = events;
|
|
2937
|
-
(0,
|
|
2938
|
-
const canvas =
|
|
3081
|
+
(0, import_react6.useEffect)(() => {
|
|
3082
|
+
const canvas = resolvedCanvasRef?.current;
|
|
2939
3083
|
if (!canvas) return;
|
|
2940
3084
|
const wrappers = /* @__PURE__ */ new Map();
|
|
2941
3085
|
for (const key of Object.keys(eventsRef.current)) {
|
|
@@ -2951,22 +3095,26 @@ function useCanvasEvents(canvasRef, events) {
|
|
|
2951
3095
|
canvas.off(name, handler);
|
|
2952
3096
|
});
|
|
2953
3097
|
};
|
|
2954
|
-
}, [
|
|
3098
|
+
}, [resolvedCanvasRef]);
|
|
2955
3099
|
}
|
|
2956
3100
|
|
|
2957
3101
|
// src/hooks/useCanvasTooltip.ts
|
|
2958
|
-
var
|
|
2959
|
-
function useCanvasTooltip(
|
|
2960
|
-
const
|
|
3102
|
+
var import_react7 = require("react");
|
|
3103
|
+
function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
|
|
3104
|
+
const isContextOverload = maybeOptions === void 0;
|
|
3105
|
+
const contextCanvasRef = useCanvasRef();
|
|
3106
|
+
const resolvedCanvasRef = isContextOverload ? contextCanvasRef : canvasRefOrOptions;
|
|
3107
|
+
const options = isContextOverload ? canvasRefOrOptions : maybeOptions;
|
|
3108
|
+
const [state, setState] = (0, import_react7.useState)({
|
|
2961
3109
|
visible: false,
|
|
2962
3110
|
content: null,
|
|
2963
3111
|
position: { x: 0, y: 0 }
|
|
2964
3112
|
});
|
|
2965
|
-
const hoveredObjectRef = (0,
|
|
2966
|
-
const optionsRef = (0,
|
|
3113
|
+
const hoveredObjectRef = (0, import_react7.useRef)(null);
|
|
3114
|
+
const optionsRef = (0, import_react7.useRef)(options);
|
|
2967
3115
|
optionsRef.current = options;
|
|
2968
|
-
(0,
|
|
2969
|
-
const canvas =
|
|
3116
|
+
(0, import_react7.useEffect)(() => {
|
|
3117
|
+
const canvas = resolvedCanvasRef?.current;
|
|
2970
3118
|
if (!canvas) return;
|
|
2971
3119
|
function calculatePosition(target) {
|
|
2972
3120
|
const bounds = target.getBoundingRect();
|
|
@@ -3014,19 +3162,24 @@ function useCanvasTooltip(canvasRef, options) {
|
|
|
3014
3162
|
canvas.off("after:render", updatePosition);
|
|
3015
3163
|
canvas.off("mouse:wheel", updatePosition);
|
|
3016
3164
|
};
|
|
3017
|
-
}, [
|
|
3165
|
+
}, [resolvedCanvasRef]);
|
|
3018
3166
|
return state;
|
|
3019
3167
|
}
|
|
3020
3168
|
|
|
3021
3169
|
// src/hooks/useCanvasClick.ts
|
|
3022
|
-
var
|
|
3023
|
-
function useCanvasClick(
|
|
3024
|
-
const
|
|
3170
|
+
var import_react8 = require("react");
|
|
3171
|
+
function useCanvasClick(canvasRefOrOnClick, onClickOrOptions, maybeOptions) {
|
|
3172
|
+
const isContextOverload = typeof canvasRefOrOnClick === "function";
|
|
3173
|
+
const contextCanvasRef = useCanvasRef();
|
|
3174
|
+
const resolvedCanvasRef = isContextOverload ? contextCanvasRef : canvasRefOrOnClick;
|
|
3175
|
+
const onClick = isContextOverload ? canvasRefOrOnClick : onClickOrOptions;
|
|
3176
|
+
const options = isContextOverload ? onClickOrOptions : maybeOptions;
|
|
3177
|
+
const onClickRef = (0, import_react8.useRef)(onClick);
|
|
3025
3178
|
onClickRef.current = onClick;
|
|
3026
|
-
const optionsRef = (0,
|
|
3179
|
+
const optionsRef = (0, import_react8.useRef)(options);
|
|
3027
3180
|
optionsRef.current = options;
|
|
3028
|
-
(0,
|
|
3029
|
-
const canvas =
|
|
3181
|
+
(0, import_react8.useEffect)(() => {
|
|
3182
|
+
const canvas = resolvedCanvasRef?.current;
|
|
3030
3183
|
if (!canvas) return;
|
|
3031
3184
|
let mouseDown = null;
|
|
3032
3185
|
let isPanning = false;
|
|
@@ -3066,66 +3219,169 @@ function useCanvasClick(canvasRef, onClick, options) {
|
|
|
3066
3219
|
canvas.off("mouse:move", handleMouseMove);
|
|
3067
3220
|
canvas.off("mouse:up", handleMouseUp);
|
|
3068
3221
|
};
|
|
3069
|
-
}, [
|
|
3222
|
+
}, [resolvedCanvasRef]);
|
|
3070
3223
|
}
|
|
3071
3224
|
|
|
3072
3225
|
// src/context/EditCanvasContext.tsx
|
|
3073
|
-
var
|
|
3226
|
+
var import_react9 = require("react");
|
|
3074
3227
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3075
|
-
var
|
|
3228
|
+
var EditViewportContext = (0, import_react9.createContext)(null);
|
|
3229
|
+
var EditStateContext = (0, import_react9.createContext)(null);
|
|
3076
3230
|
function EditCanvasProvider({
|
|
3077
3231
|
options,
|
|
3078
3232
|
children
|
|
3079
3233
|
}) {
|
|
3080
3234
|
const canvas = useEditCanvas(options);
|
|
3081
|
-
|
|
3235
|
+
const viewportValue = (0, import_react9.useMemo)(
|
|
3236
|
+
() => ({ zoom: canvas.zoom, viewport: canvas.viewport }),
|
|
3237
|
+
[canvas.zoom, canvas.viewport]
|
|
3238
|
+
);
|
|
3239
|
+
const stateValue = (0, import_react9.useMemo)(
|
|
3240
|
+
() => ({
|
|
3241
|
+
onReady: canvas.onReady,
|
|
3242
|
+
objects: canvas.objects,
|
|
3243
|
+
isLoading: canvas.isLoading,
|
|
3244
|
+
selected: canvas.selected,
|
|
3245
|
+
isEditingVertices: canvas.isEditingVertices,
|
|
3246
|
+
setMode: canvas.setMode,
|
|
3247
|
+
setBackground: canvas.setBackground,
|
|
3248
|
+
isDirty: canvas.isDirty,
|
|
3249
|
+
resetDirty: canvas.resetDirty,
|
|
3250
|
+
markDirty: canvas.markDirty,
|
|
3251
|
+
undo: canvas.undo,
|
|
3252
|
+
redo: canvas.redo,
|
|
3253
|
+
canUndo: canvas.canUndo,
|
|
3254
|
+
canRedo: canvas.canRedo,
|
|
3255
|
+
lockLightMode: canvas.lockLightMode,
|
|
3256
|
+
setLockLightMode: canvas.setLockLightMode
|
|
3257
|
+
}),
|
|
3258
|
+
// Only reactive state — stable callbacks omitted
|
|
3259
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3260
|
+
[
|
|
3261
|
+
canvas.objects,
|
|
3262
|
+
canvas.isLoading,
|
|
3263
|
+
canvas.selected,
|
|
3264
|
+
canvas.isEditingVertices,
|
|
3265
|
+
canvas.isDirty,
|
|
3266
|
+
canvas.canUndo,
|
|
3267
|
+
canvas.canRedo,
|
|
3268
|
+
canvas.lockLightMode
|
|
3269
|
+
]
|
|
3270
|
+
);
|
|
3271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CanvasRefContext.Provider, { value: canvas.canvasRef, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditViewportContext.Provider, { value: viewportValue, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditStateContext.Provider, { value: stateValue, children }) }) });
|
|
3082
3272
|
}
|
|
3083
3273
|
function useEditCanvasContext() {
|
|
3084
|
-
const
|
|
3085
|
-
|
|
3274
|
+
const canvasRef = (0, import_react9.useContext)(CanvasRefContext);
|
|
3275
|
+
const viewport = (0, import_react9.useContext)(EditViewportContext);
|
|
3276
|
+
const state = (0, import_react9.useContext)(EditStateContext);
|
|
3277
|
+
if (canvasRef === null || viewport === null || state === null) {
|
|
3086
3278
|
throw new Error(
|
|
3087
3279
|
"useEditCanvasContext must be used within an <EditCanvasProvider>"
|
|
3088
3280
|
);
|
|
3089
3281
|
}
|
|
3282
|
+
return (0, import_react9.useMemo)(
|
|
3283
|
+
() => ({ canvasRef, ...viewport, ...state }),
|
|
3284
|
+
[canvasRef, viewport, state]
|
|
3285
|
+
);
|
|
3286
|
+
}
|
|
3287
|
+
function useEditCanvasViewport() {
|
|
3288
|
+
const ctx = (0, import_react9.useContext)(EditViewportContext);
|
|
3289
|
+
if (ctx === null) {
|
|
3290
|
+
throw new Error(
|
|
3291
|
+
"useEditCanvasViewport must be used within an <EditCanvasProvider>"
|
|
3292
|
+
);
|
|
3293
|
+
}
|
|
3294
|
+
return ctx;
|
|
3295
|
+
}
|
|
3296
|
+
function useEditCanvasState() {
|
|
3297
|
+
const ctx = (0, import_react9.useContext)(EditStateContext);
|
|
3298
|
+
if (ctx === null) {
|
|
3299
|
+
throw new Error(
|
|
3300
|
+
"useEditCanvasState must be used within an <EditCanvasProvider>"
|
|
3301
|
+
);
|
|
3302
|
+
}
|
|
3090
3303
|
return ctx;
|
|
3091
3304
|
}
|
|
3092
3305
|
|
|
3093
3306
|
// src/context/ViewCanvasContext.tsx
|
|
3094
|
-
var
|
|
3307
|
+
var import_react10 = require("react");
|
|
3095
3308
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
3096
|
-
var
|
|
3309
|
+
var ViewViewportContext = (0, import_react10.createContext)(null);
|
|
3310
|
+
var ViewStateContext = (0, import_react10.createContext)(null);
|
|
3097
3311
|
function ViewCanvasProvider({
|
|
3098
3312
|
options,
|
|
3099
3313
|
children
|
|
3100
3314
|
}) {
|
|
3101
3315
|
const canvas = useViewCanvas(options);
|
|
3102
|
-
|
|
3316
|
+
const viewportValue = (0, import_react10.useMemo)(
|
|
3317
|
+
() => ({ zoom: canvas.zoom, viewport: canvas.viewport }),
|
|
3318
|
+
[canvas.zoom, canvas.viewport]
|
|
3319
|
+
);
|
|
3320
|
+
const stateValue = (0, import_react10.useMemo)(
|
|
3321
|
+
() => ({
|
|
3322
|
+
onReady: canvas.onReady,
|
|
3323
|
+
objects: canvas.objects,
|
|
3324
|
+
isLoading: canvas.isLoading,
|
|
3325
|
+
setObjectStyle: canvas.setObjectStyle,
|
|
3326
|
+
setObjectStyles: canvas.setObjectStyles,
|
|
3327
|
+
setObjectStyleByType: canvas.setObjectStyleByType
|
|
3328
|
+
}),
|
|
3329
|
+
// Only reactive state — stable callbacks omitted
|
|
3330
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3331
|
+
[canvas.objects, canvas.isLoading]
|
|
3332
|
+
);
|
|
3333
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CanvasRefContext.Provider, { value: canvas.canvasRef, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ViewViewportContext.Provider, { value: viewportValue, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ViewStateContext.Provider, { value: stateValue, children }) }) });
|
|
3103
3334
|
}
|
|
3104
3335
|
function useViewCanvasContext() {
|
|
3105
|
-
const
|
|
3106
|
-
|
|
3336
|
+
const canvasRef = (0, import_react10.useContext)(CanvasRefContext);
|
|
3337
|
+
const viewport = (0, import_react10.useContext)(ViewViewportContext);
|
|
3338
|
+
const state = (0, import_react10.useContext)(ViewStateContext);
|
|
3339
|
+
if (canvasRef === null || viewport === null || state === null) {
|
|
3107
3340
|
throw new Error(
|
|
3108
3341
|
"useViewCanvasContext must be used within a <ViewCanvasProvider>"
|
|
3109
3342
|
);
|
|
3110
3343
|
}
|
|
3344
|
+
return (0, import_react10.useMemo)(
|
|
3345
|
+
() => ({ canvasRef, ...viewport, ...state }),
|
|
3346
|
+
[canvasRef, viewport, state]
|
|
3347
|
+
);
|
|
3348
|
+
}
|
|
3349
|
+
function useViewCanvasViewport() {
|
|
3350
|
+
const ctx = (0, import_react10.useContext)(ViewViewportContext);
|
|
3351
|
+
if (ctx === null) {
|
|
3352
|
+
throw new Error(
|
|
3353
|
+
"useViewCanvasViewport must be used within a <ViewCanvasProvider>"
|
|
3354
|
+
);
|
|
3355
|
+
}
|
|
3356
|
+
return ctx;
|
|
3357
|
+
}
|
|
3358
|
+
function useViewCanvasState() {
|
|
3359
|
+
const ctx = (0, import_react10.useContext)(ViewStateContext);
|
|
3360
|
+
if (ctx === null) {
|
|
3361
|
+
throw new Error(
|
|
3362
|
+
"useViewCanvasState must be used within a <ViewCanvasProvider>"
|
|
3363
|
+
);
|
|
3364
|
+
}
|
|
3111
3365
|
return ctx;
|
|
3112
3366
|
}
|
|
3113
3367
|
|
|
3114
3368
|
// src/overlay/ObjectOverlay.tsx
|
|
3115
|
-
var
|
|
3369
|
+
var import_react11 = require("react");
|
|
3116
3370
|
var import_material = require("@mui/material");
|
|
3117
3371
|
var import_fabric18 = require("fabric");
|
|
3118
3372
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
3119
3373
|
function ObjectOverlay({
|
|
3120
|
-
canvasRef,
|
|
3374
|
+
canvasRef: canvasRefProp,
|
|
3121
3375
|
object,
|
|
3122
3376
|
sx,
|
|
3123
3377
|
children,
|
|
3124
3378
|
...rest
|
|
3125
3379
|
}) {
|
|
3126
|
-
const
|
|
3127
|
-
|
|
3128
|
-
|
|
3380
|
+
const contextCanvasRef = useCanvasRef();
|
|
3381
|
+
const canvasRef = canvasRefProp ?? contextCanvasRef;
|
|
3382
|
+
const stackRef = (0, import_react11.useRef)(null);
|
|
3383
|
+
(0, import_react11.useEffect)(() => {
|
|
3384
|
+
const canvas = canvasRef?.current;
|
|
3129
3385
|
if (!canvas || !object) return;
|
|
3130
3386
|
function update() {
|
|
3131
3387
|
const el = stackRef.current;
|
|
@@ -3179,7 +3435,7 @@ function ObjectOverlay({
|
|
|
3179
3435
|
|
|
3180
3436
|
// src/overlay/OverlayContent.tsx
|
|
3181
3437
|
var import_material2 = require("@mui/material");
|
|
3182
|
-
var
|
|
3438
|
+
var import_react12 = require("react");
|
|
3183
3439
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
3184
3440
|
function OverlayContent({
|
|
3185
3441
|
children,
|
|
@@ -3188,9 +3444,9 @@ function OverlayContent({
|
|
|
3188
3444
|
sx,
|
|
3189
3445
|
...rest
|
|
3190
3446
|
}) {
|
|
3191
|
-
const outerRef = (0,
|
|
3192
|
-
const innerRef = (0,
|
|
3193
|
-
(0,
|
|
3447
|
+
const outerRef = (0, import_react12.useRef)(null);
|
|
3448
|
+
const innerRef = (0, import_react12.useRef)(null);
|
|
3449
|
+
(0, import_react12.useEffect)(() => {
|
|
3194
3450
|
const outer = outerRef.current;
|
|
3195
3451
|
const inner = innerRef.current;
|
|
3196
3452
|
if (!outer || !inner) return;
|
|
@@ -3251,7 +3507,7 @@ function OverlayContent({
|
|
|
3251
3507
|
|
|
3252
3508
|
// src/overlay/FixedSizeContent.tsx
|
|
3253
3509
|
var import_material3 = require("@mui/material");
|
|
3254
|
-
var
|
|
3510
|
+
var import_react13 = require("react");
|
|
3255
3511
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
3256
3512
|
function FixedSizeContent({
|
|
3257
3513
|
children,
|
|
@@ -3260,9 +3516,9 @@ function FixedSizeContent({
|
|
|
3260
3516
|
sx,
|
|
3261
3517
|
...rest
|
|
3262
3518
|
}) {
|
|
3263
|
-
const ref = (0,
|
|
3264
|
-
const totalContentHeightRef = (0,
|
|
3265
|
-
(0,
|
|
3519
|
+
const ref = (0, import_react13.useRef)(null);
|
|
3520
|
+
const totalContentHeightRef = (0, import_react13.useRef)(0);
|
|
3521
|
+
(0, import_react13.useEffect)(() => {
|
|
3266
3522
|
const el = ref.current;
|
|
3267
3523
|
if (!el) return;
|
|
3268
3524
|
let clipAncestor = el.parentElement;
|
|
@@ -3325,7 +3581,7 @@ function FixedSizeContent({
|
|
|
3325
3581
|
|
|
3326
3582
|
// src/overlay/OverlayBadge.tsx
|
|
3327
3583
|
var import_material4 = require("@mui/material");
|
|
3328
|
-
var
|
|
3584
|
+
var import_react14 = require("react");
|
|
3329
3585
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
3330
3586
|
function toPx(v) {
|
|
3331
3587
|
if (v === void 0) return void 0;
|
|
@@ -3368,9 +3624,9 @@ function OverlayBadge({
|
|
|
3368
3624
|
sx,
|
|
3369
3625
|
...rest
|
|
3370
3626
|
}) {
|
|
3371
|
-
const ref = (0,
|
|
3372
|
-
const baseSize = (0,
|
|
3373
|
-
(0,
|
|
3627
|
+
const ref = (0, import_react14.useRef)(null);
|
|
3628
|
+
const baseSize = (0, import_react14.useRef)(null);
|
|
3629
|
+
(0, import_react14.useEffect)(() => {
|
|
3374
3630
|
const el = ref.current;
|
|
3375
3631
|
if (!el) return;
|
|
3376
3632
|
const ancestor = el.parentElement;
|
|
@@ -3505,11 +3761,16 @@ var import_fabric19 = require("fabric");
|
|
|
3505
3761
|
snapCursorPoint,
|
|
3506
3762
|
useCanvasClick,
|
|
3507
3763
|
useCanvasEvents,
|
|
3764
|
+
useCanvasRef,
|
|
3508
3765
|
useCanvasTooltip,
|
|
3509
3766
|
useEditCanvas,
|
|
3510
3767
|
useEditCanvasContext,
|
|
3768
|
+
useEditCanvasState,
|
|
3769
|
+
useEditCanvasViewport,
|
|
3511
3770
|
useViewCanvas,
|
|
3512
3771
|
useViewCanvasContext,
|
|
3772
|
+
useViewCanvasState,
|
|
3773
|
+
useViewCanvasViewport,
|
|
3513
3774
|
util
|
|
3514
3775
|
});
|
|
3515
3776
|
//# sourceMappingURL=index.cjs.map
|