@bwp-web/canvas 0.8.0 → 0.8.2

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.
@@ -27,6 +27,8 @@ export declare function fitViewportToBackground(canvas: FabricCanvas, options?:
27
27
  * - **2**: maximum contrast (darks are truly dark, lights truly light).
28
28
  *
29
29
  * Clamped to the 0–2 range.
30
+ *
31
+ * Fires `background:modified` on the canvas when the contrast actually changes.
30
32
  */
31
33
  export declare function setBackgroundContrast(canvas: FabricCanvas, value: number): void;
32
34
  /**
@@ -38,6 +40,8 @@ export declare function setBackgroundContrast(canvas: FabricCanvas, value: numbe
38
40
  export declare function getBackgroundContrast(canvas: FabricCanvas): number;
39
41
  /**
40
42
  * Add or remove the Invert filter from the canvas background image.
43
+ *
44
+ * Fires `background:modified` on the canvas when the invert state actually changes.
41
45
  */
42
46
  export declare function setBackgroundInverted(canvas: FabricCanvas, inverted: boolean): void;
43
47
  /**
@@ -93,6 +97,8 @@ export interface SetBackgroundImageOptions extends ResizeImageOptions {
93
97
  * preserve the current background contrast when replacing the image.
94
98
  * Omit to load the URL as-is without resizing.
95
99
  *
100
+ * Fires `background:modified` on the canvas after the image is set.
101
+ *
96
102
  * Returns the created FabricImage for further manipulation.
97
103
  */
98
104
  export declare function setBackgroundImage(canvas: FabricCanvas, url: string, options?: SetBackgroundImageOptions): Promise<FabricImage>;
@@ -1 +1 @@
1
- {"version":3,"file":"background.d.ts","sourceRoot":"","sources":["../src/background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,WAAW,EAAW,MAAM,QAAQ,CAAC;AAWtE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAIpE;AAID,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,IAAI,CAiCN;AAID;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,GACZ,IAAI,CA6BN;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAUlE;AAID;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,OAAO,GAChB,IAAI,CAgBN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAInE;AAID,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAkDvB;AAID,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,WAAW,CAAC,CA4BtB"}
1
+ {"version":3,"file":"background.d.ts","sourceRoot":"","sources":["../src/background.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,WAAW,EAAW,MAAM,QAAQ,CAAC;AAWtE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI,CAIpE;AAID,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,IAAI,CAiCN;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,MAAM,GACZ,IAAI,CAmCN;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAUlE;AAID;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,OAAO,GAChB,IAAI,CAqBN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAInE;AAID,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,GAAG,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAkDvB;AAID,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,WAAW,CAAC,CA6BtB"}
@@ -0,0 +1,45 @@
1
+ import { type ReactNode } from 'react';
2
+ import { useEditCanvas, type UseEditCanvasOptions } from '../hooks/useEditCanvas';
3
+ /** The full return value of {@link useEditCanvas}, exposed via context. */
4
+ export type EditCanvasContextValue = ReturnType<typeof useEditCanvas>;
5
+ export interface EditCanvasProviderProps {
6
+ /** Options forwarded to the underlying {@link useEditCanvas} hook. */
7
+ options?: UseEditCanvasOptions;
8
+ children: ReactNode;
9
+ }
10
+ /**
11
+ * Calls {@link useEditCanvas} internally and provides the full canvas API
12
+ * to all descendants via React context.
13
+ *
14
+ * Use {@link useEditCanvasContext} in any descendant to access `canvasRef`,
15
+ * `isDirty`, `viewport`, `setMode`, `setBackground`, and every other value
16
+ * that `useEditCanvas` returns — without prop drilling or bridge contexts.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <EditCanvasProvider options={{ trackChanges: true, history: true }}>
21
+ * <MyCanvas />
22
+ * <MySidebar />
23
+ * <MyToolbar />
24
+ * </EditCanvasProvider>
25
+ *
26
+ * function MyCanvas() {
27
+ * const { onReady } = useEditCanvasContext();
28
+ * return <Canvas onReady={onReady} />;
29
+ * }
30
+ *
31
+ * function MySidebar() {
32
+ * const { isDirty, resetDirty } = useEditCanvasContext();
33
+ * return <SaveButton disabled={!isDirty} onClick={() => { save(); resetDirty(); }} />;
34
+ * }
35
+ * ```
36
+ */
37
+ export declare function EditCanvasProvider({ options, children, }: EditCanvasProviderProps): import("react/jsx-runtime").JSX.Element;
38
+ /**
39
+ * Access the full {@link useEditCanvas} API from any descendant of
40
+ * {@link EditCanvasProvider}.
41
+ *
42
+ * Throws if called outside of a provider.
43
+ */
44
+ export declare function useEditCanvasContext(): EditCanvasContextValue;
45
+ //# sourceMappingURL=EditCanvasContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditCanvasContext.d.ts","sourceRoot":"","sources":["../../src/context/EditCanvasContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAItE,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,2CAOzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CAQ7D"}
@@ -0,0 +1,44 @@
1
+ import { type ReactNode } from 'react';
2
+ import { useViewCanvas, type UseViewCanvasOptions } from '../hooks/useViewCanvas';
3
+ /** The full return value of {@link useViewCanvas}, exposed via context. */
4
+ export type ViewCanvasContextValue = ReturnType<typeof useViewCanvas>;
5
+ export interface ViewCanvasProviderProps {
6
+ /** Options forwarded to the underlying {@link useViewCanvas} hook. */
7
+ options?: UseViewCanvasOptions;
8
+ children: ReactNode;
9
+ }
10
+ /**
11
+ * Calls {@link useViewCanvas} internally and provides the full canvas API
12
+ * to all descendants via React context.
13
+ *
14
+ * Use {@link useViewCanvasContext} in any descendant to access `canvasRef`,
15
+ * `viewport`, `setObjectStyle`, and every other value that `useViewCanvas`
16
+ * returns — without prop drilling or bridge contexts.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * <ViewCanvasProvider options={{ scaledStrokes: true }}>
21
+ * <MyCanvas />
22
+ * <MyToolbar />
23
+ * </ViewCanvasProvider>
24
+ *
25
+ * function MyCanvas() {
26
+ * const { onReady } = useViewCanvasContext();
27
+ * return <Canvas onReady={onReady} />;
28
+ * }
29
+ *
30
+ * function MyToolbar() {
31
+ * const { viewport } = useViewCanvasContext();
32
+ * return <ZoomControls onZoomIn={viewport.zoomIn} onZoomOut={viewport.zoomOut} />;
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function ViewCanvasProvider({ options, children, }: ViewCanvasProviderProps): import("react/jsx-runtime").JSX.Element;
37
+ /**
38
+ * Access the full {@link useViewCanvas} API from any descendant of
39
+ * {@link ViewCanvasProvider}.
40
+ *
41
+ * Throws if called outside of a provider.
42
+ */
43
+ export declare function useViewCanvasContext(): ViewCanvasContextValue;
44
+ //# sourceMappingURL=ViewCanvasContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ViewCanvasContext.d.ts","sourceRoot":"","sources":["../../src/context/ViewCanvasContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AAItE,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,QAAQ,GACT,EAAE,uBAAuB,2CAOzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,sBAAsB,CAQ7D"}
@@ -0,0 +1,5 @@
1
+ export { EditCanvasProvider, useEditCanvasContext } from './EditCanvasContext';
2
+ export type { EditCanvasProviderProps, EditCanvasContextValue, } from './EditCanvasContext';
3
+ export { ViewCanvasProvider, useViewCanvasContext } from './ViewCanvasContext';
4
+ export type { ViewCanvasProviderProps, ViewCanvasContextValue, } from './ViewCanvasContext';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC/E,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC"}
@@ -13,5 +13,8 @@ declare module 'fabric' {
13
13
  interface Canvas {
14
14
  lockLightMode?: boolean;
15
15
  }
16
+ interface CanvasEvents {
17
+ 'background:modified': object;
18
+ }
16
19
  }
17
20
  //# sourceMappingURL=fabricAugmentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fabricAugmentation.d.ts","sourceRoot":"","sources":["../src/fabricAugmentation.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAC;AAEhB,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC,mDAAmD;AACnD,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,eAAe,GACf,UAAU,CAAC;AAEf,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,YAAY;QACpB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,IAAI,CAAC,EAAE;YACL,IAAI,EAAE,cAAc,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACZ,CAAC;KACH;IACD,UAAU,MAAM;QACd,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB;CACF"}
1
+ {"version":3,"file":"fabricAugmentation.d.ts","sourceRoot":"","sources":["../src/fabricAugmentation.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,CAAC;AAEhB,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC,mDAAmD;AACnD,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,eAAe,GACf,UAAU,CAAC;AAEf,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,YAAY;QACpB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,IAAI,CAAC,EAAE;YACL,IAAI,EAAE,cAAc,CAAC;YACrB,EAAE,EAAE,MAAM,CAAC;SACZ,CAAC;KACH;IACD,UAAU,MAAM;QACd,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB;IACD,UAAU,YAAY;QACpB,qBAAqB,EAAE,MAAM,CAAC;KAC/B;CACF"}
@@ -55,8 +55,10 @@ export interface UseEditCanvasOptions {
55
55
  */
56
56
  backgroundResize?: boolean | ResizeImageOptions;
57
57
  /**
58
- * Track object add/remove/modify events and expose an `isDirty` flag.
59
- * Call `resetDirty()` after a successful save to clear the flag.
58
+ * Track canvas mutations and expose an `isDirty` flag.
59
+ * Listens for `object:added`, `object:removed`, `object:modified`, and
60
+ * `background:modified` events. Call `resetDirty()` after a successful
61
+ * save to clear the flag, or `markDirty()` to set it manually.
60
62
  * Default: disabled.
61
63
  */
62
64
  trackChanges?: boolean;
@@ -153,6 +155,8 @@ export declare function useEditCanvas(options?: UseEditCanvasOptions): {
153
155
  isDirty: boolean;
154
156
  /** Reset the dirty flag (e.g., after a successful save). */
155
157
  resetDirty: () => void;
158
+ /** Manually mark the canvas as dirty (e.g., after a custom operation not tracked automatically). */
159
+ markDirty: () => void;
156
160
  /** Undo the last change. Requires `history: true`. */
157
161
  undo: () => Promise<void>;
158
162
  /** Redo a previously undone change. Requires `history: true`. */
@@ -1 +1 @@
1
- {"version":3,"file":"useEditCanvas.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditCanvas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,KAAK,YAAY,EAAW,MAAM,QAAQ,CAAC;AAC5E,OAAO,EAEL,KAAK,iBAAiB,EAEtB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAEL,KAAK,sBAAsB,EAE3B,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACzC,mIAAmI;IACnI,SAAS,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAC;IAC7C;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IAC7C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAC;IAChD;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB;IA+QxD,8CAA8C;sBAnMrC,YAAY;IAqMrB,oDAAoD;;IAEpD,qCAAqC;;IAErC,6CAA6C;;IAE7C,yBAAyB;;QAEvB,wCAAwC;;QAExC,wDAAwD;wBAhDjB,YAAY;QAkDnD,wFAAwF;;QAExF,2DAA2D;;QAE3D,0DAA0D;;QAE1D,uDAAuD;;QAEvD,6DAA6D;;;IAG/D,+DAA+D;;IAE/D;;;;;;;;;;;;;;OAcG;qBArR+B,SAAS,GAAG,IAAI;IAuRlD;;;;;;;OAOG;yBA7ES,MAAM,WAAW;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE;IA+E3D,8GAA8G;;IAE9G,4DAA4D;;IAE5D,sDAAsD;;IAQtD,iEAAiE;;IAQjE,mFAAmF;;IAEnF,kFAAkF;;EAGrF"}
1
+ {"version":3,"file":"useEditCanvas.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditCanvas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,KAAK,YAAY,EAAW,MAAM,QAAQ,CAAC;AAC5E,OAAO,EAEL,KAAK,iBAAiB,EAEtB,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AAMrB,OAAO,EAEL,KAAK,sBAAsB,EAE3B,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACzC,mIAAmI;IACnI,SAAS,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAC;IAC7C;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,GAAG,mBAAmB,CAAC;IAC7C;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAC;IAChD;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB;IAiRxD,8CAA8C;sBArMrC,YAAY;IAuMrB,oDAAoD;;IAEpD,qCAAqC;;IAErC,6CAA6C;;IAE7C,yBAAyB;;QAEvB,wCAAwC;;QAExC,wDAAwD;wBAhDjB,YAAY;QAkDnD,wFAAwF;;QAExF,2DAA2D;;QAE3D,0DAA0D;;QAE1D,uDAAuD;;QAEvD,6DAA6D;;;IAG/D,+DAA+D;;IAE/D;;;;;;;;;;;;;;OAcG;qBAvR+B,SAAS,GAAG,IAAI;IAyRlD;;;;;;;OAOG;yBA7ES,MAAM,WAAW;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE;IA+E3D,8GAA8G;;IAE9G,4DAA4D;;IAE5D,oGAAoG;;IAEpG,sDAAsD;;IAQtD,iEAAiE;;IAQjE,mFAAmF;;IAEnF,kFAAkF;;EAGrF"}
@@ -1 +1 @@
1
- {"version":3,"file":"useViewCanvas.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewCanvas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,aAAa,CAAC;AASrB,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC/B;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB;IAuHxD,8CAA8C;sBA9GrC,YAAY;IAgHrB,oDAAoD;;IAEpD,qCAAqC;;IAErC,yBAAyB;;QAEvB,wFAAwF;;QAExF,2DAA2D;;QAE3D,0DAA0D;;QAE1D,uDAAuD;;QAEvD,6DAA6D;;;IAG/D,8DAA8D;yBAnExB,MAAM,SAAS,eAAe;IAqEpE,sFAAsF;8BA5D7E,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IA8DxC,qEAAqE;iCAvC9D,MAAM,SAAS,eAAe;EA0CxC"}
1
+ {"version":3,"file":"useViewCanvas.d.ts","sourceRoot":"","sources":["../../src/hooks/useViewCanvas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,aAAa,CAAC;AASrB,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC/B;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,oBAAoB;IA0HxD,8CAA8C;sBAjHrC,YAAY;IAmHrB,oDAAoD;;IAEpD,qCAAqC;;IAErC,yBAAyB;;QAEvB,wFAAwF;;QAExF,2DAA2D;;QAE3D,0DAA0D;;QAE1D,uDAAuD;;QAEvD,6DAA6D;;;IAG/D,8DAA8D;yBAnExB,MAAM,SAAS,eAAe;IAqEpE,sFAAsF;8BA5D7E,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC;IA8DxC,qEAAqE;iCAvC9D,MAAM,SAAS,eAAe;EA0CxC"}
package/dist/index.cjs CHANGED
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  DEFAULT_DRAG_SHAPE_STYLE: () => DEFAULT_DRAG_SHAPE_STYLE,
28
28
  DEFAULT_GUIDELINE_SHAPE_STYLE: () => DEFAULT_GUIDELINE_SHAPE_STYLE,
29
29
  DEFAULT_SHAPE_STYLE: () => DEFAULT_SHAPE_STYLE,
30
+ EditCanvasProvider: () => EditCanvasProvider,
30
31
  FabricCanvas: () => import_fabric19.Canvas,
31
32
  FabricImage: () => import_fabric19.FabricImage,
32
33
  FabricObject: () => import_fabric19.FabricObject,
@@ -37,6 +38,7 @@ __export(index_exports, {
37
38
  Point: () => import_fabric19.Point,
38
39
  Polygon: () => import_fabric19.Polygon,
39
40
  Rect: () => import_fabric19.Rect,
41
+ ViewCanvasProvider: () => ViewCanvasProvider,
40
42
  createCircle: () => createCircle,
41
43
  createCircleAtPoint: () => createCircleAtPoint,
42
44
  createHistoryTracker: () => createHistoryTracker,
@@ -79,7 +81,9 @@ __export(index_exports, {
79
81
  useCanvasEvents: () => useCanvasEvents,
80
82
  useCanvasTooltip: () => useCanvasTooltip,
81
83
  useEditCanvas: () => useEditCanvas,
84
+ useEditCanvasContext: () => useEditCanvasContext,
82
85
  useViewCanvas: () => useViewCanvas,
86
+ useViewCanvasContext: () => useViewCanvasContext,
83
87
  util: () => import_fabric19.util
84
88
  });
85
89
  module.exports = __toCommonJS(index_exports);
@@ -518,21 +522,26 @@ function setBackgroundContrast(canvas, value) {
518
522
  const contrastIdx = currentFilters.findIndex(
519
523
  (f) => f instanceof import_fabric4.filters.Contrast
520
524
  );
525
+ let changed = false;
521
526
  if (contrast === 0) {
522
527
  if (contrastIdx >= 0) {
523
528
  bg.filters = currentFilters.filter(
524
529
  (f) => !(f instanceof import_fabric4.filters.Contrast)
525
530
  );
526
531
  bg.applyFilters();
532
+ changed = true;
527
533
  }
528
534
  } else if (contrastIdx >= 0) {
529
535
  currentFilters[contrastIdx].contrast = contrast;
530
536
  bg.applyFilters();
537
+ changed = true;
531
538
  } else {
532
539
  bg.filters = [...currentFilters, new import_fabric4.filters.Contrast({ contrast })];
533
540
  bg.applyFilters();
541
+ changed = true;
534
542
  }
535
543
  canvas.requestRenderAll();
544
+ if (changed) canvas.fire("background:modified");
536
545
  }
537
546
  function getBackgroundContrast(canvas) {
538
547
  const bg = getBackgroundImage(canvas);
@@ -547,14 +556,18 @@ function setBackgroundInverted(canvas, inverted) {
547
556
  if (!bg) return;
548
557
  const currentFilters = bg.filters ?? [];
549
558
  const hasInvert = currentFilters.some((f) => f instanceof import_fabric4.filters.Invert);
559
+ let changed = false;
550
560
  if (inverted && !hasInvert) {
551
561
  bg.filters = [...currentFilters, new import_fabric4.filters.Invert()];
552
562
  bg.applyFilters();
563
+ changed = true;
553
564
  } else if (!inverted && hasInvert) {
554
565
  bg.filters = currentFilters.filter((f) => !(f instanceof import_fabric4.filters.Invert));
555
566
  bg.applyFilters();
567
+ changed = true;
556
568
  }
557
569
  canvas.requestRenderAll();
570
+ if (changed) canvas.fire("background:modified");
558
571
  }
559
572
  function getBackgroundInverted(canvas) {
560
573
  const bg = getBackgroundImage(canvas);
@@ -620,6 +633,7 @@ async function setBackgroundImage(canvas, url, options) {
620
633
  setBackgroundContrast(canvas, prevContrast);
621
634
  }
622
635
  canvas.requestRenderAll();
636
+ canvas.fire("background:modified");
623
637
  return img;
624
638
  }
625
639
 
@@ -2379,6 +2393,10 @@ async function loadCanvas(canvas, json, options) {
2379
2393
  });
2380
2394
  bg.setCoords();
2381
2395
  }
2396
+ if (bg.filters?.some((f) => f instanceof import_fabric16.filters.Invert)) {
2397
+ bg.filters = bg.filters.filter((f) => !(f instanceof import_fabric16.filters.Invert));
2398
+ bg.applyFilters();
2399
+ }
2382
2400
  }
2383
2401
  if (options?.filter) {
2384
2402
  const toRemove = [];
@@ -2610,6 +2628,7 @@ function useEditCanvas(options) {
2610
2628
  canvas.on("object:added", () => setIsDirty(true));
2611
2629
  canvas.on("object:removed", () => setIsDirty(true));
2612
2630
  canvas.on("object:modified", () => setIsDirty(true));
2631
+ canvas.on("background:modified", () => setIsDirty(true));
2613
2632
  }
2614
2633
  if (opts?.history) {
2615
2634
  const syncHistoryState = () => {
@@ -2623,6 +2642,7 @@ function useEditCanvas(options) {
2623
2642
  canvas.on("object:added", syncHistoryState);
2624
2643
  canvas.on("object:removed", syncHistoryState);
2625
2644
  canvas.on("object:modified", syncHistoryState);
2645
+ canvas.on("background:modified", syncHistoryState);
2626
2646
  }
2627
2647
  if (opts?.vertexEdit !== false) {
2628
2648
  const vertexOpts = typeof opts?.vertexEdit === "object" ? opts.vertexEdit : void 0;
@@ -2754,6 +2774,8 @@ function useEditCanvas(options) {
2754
2774
  isDirty,
2755
2775
  /** Reset the dirty flag (e.g., after a successful save). */
2756
2776
  resetDirty: (0, import_react3.useCallback)(() => setIsDirty(false), []),
2777
+ /** Manually mark the canvas as dirty (e.g., after a custom operation not tracked automatically). */
2778
+ markDirty: (0, import_react3.useCallback)(() => setIsDirty(true), []),
2757
2779
  /** Undo the last change. Requires `history: true`. */
2758
2780
  undo: (0, import_react3.useCallback)(async () => {
2759
2781
  const h = historyRef.current;
@@ -2813,6 +2835,7 @@ function useViewCanvas(options) {
2813
2835
  canvas.on("object:added", () => {
2814
2836
  lockCanvas(canvas);
2815
2837
  });
2838
+ canvas.hoverCursor = "pointer";
2816
2839
  canvas.on("mouse:wheel", () => {
2817
2840
  setZoom(canvas.getZoom());
2818
2841
  });
@@ -3046,11 +3069,53 @@ function useCanvasClick(canvasRef, onClick, options) {
3046
3069
  }, [canvasRef]);
3047
3070
  }
3048
3071
 
3049
- // src/overlay/ObjectOverlay.tsx
3072
+ // src/context/EditCanvasContext.tsx
3050
3073
  var import_react8 = require("react");
3074
+ var import_jsx_runtime2 = require("react/jsx-runtime");
3075
+ var EditCanvasContext = (0, import_react8.createContext)(null);
3076
+ function EditCanvasProvider({
3077
+ options,
3078
+ children
3079
+ }) {
3080
+ const canvas = useEditCanvas(options);
3081
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditCanvasContext.Provider, { value: canvas, children });
3082
+ }
3083
+ function useEditCanvasContext() {
3084
+ const ctx = (0, import_react8.useContext)(EditCanvasContext);
3085
+ if (ctx === null) {
3086
+ throw new Error(
3087
+ "useEditCanvasContext must be used within an <EditCanvasProvider>"
3088
+ );
3089
+ }
3090
+ return ctx;
3091
+ }
3092
+
3093
+ // src/context/ViewCanvasContext.tsx
3094
+ var import_react9 = require("react");
3095
+ var import_jsx_runtime3 = require("react/jsx-runtime");
3096
+ var ViewCanvasContext = (0, import_react9.createContext)(null);
3097
+ function ViewCanvasProvider({
3098
+ options,
3099
+ children
3100
+ }) {
3101
+ const canvas = useViewCanvas(options);
3102
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ViewCanvasContext.Provider, { value: canvas, children });
3103
+ }
3104
+ function useViewCanvasContext() {
3105
+ const ctx = (0, import_react9.useContext)(ViewCanvasContext);
3106
+ if (ctx === null) {
3107
+ throw new Error(
3108
+ "useViewCanvasContext must be used within a <ViewCanvasProvider>"
3109
+ );
3110
+ }
3111
+ return ctx;
3112
+ }
3113
+
3114
+ // src/overlay/ObjectOverlay.tsx
3115
+ var import_react10 = require("react");
3051
3116
  var import_material = require("@mui/material");
3052
3117
  var import_fabric18 = require("fabric");
3053
- var import_jsx_runtime2 = require("react/jsx-runtime");
3118
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3054
3119
  function ObjectOverlay({
3055
3120
  canvasRef,
3056
3121
  object,
@@ -3058,8 +3123,8 @@ function ObjectOverlay({
3058
3123
  children,
3059
3124
  ...rest
3060
3125
  }) {
3061
- const stackRef = (0, import_react8.useRef)(null);
3062
- (0, import_react8.useEffect)(() => {
3126
+ const stackRef = (0, import_react10.useRef)(null);
3127
+ (0, import_react10.useEffect)(() => {
3063
3128
  const canvas = canvasRef.current;
3064
3129
  if (!canvas || !object) return;
3065
3130
  function update() {
@@ -3094,7 +3159,7 @@ function ObjectOverlay({
3094
3159
  };
3095
3160
  }, [canvasRef, object]);
3096
3161
  if (!object) return null;
3097
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3162
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3098
3163
  import_material.Stack,
3099
3164
  {
3100
3165
  ref: stackRef,
@@ -3114,8 +3179,8 @@ function ObjectOverlay({
3114
3179
 
3115
3180
  // src/overlay/OverlayContent.tsx
3116
3181
  var import_material2 = require("@mui/material");
3117
- var import_react9 = require("react");
3118
- var import_jsx_runtime3 = require("react/jsx-runtime");
3182
+ var import_react11 = require("react");
3183
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3119
3184
  function OverlayContent({
3120
3185
  children,
3121
3186
  padding = 4,
@@ -3123,9 +3188,9 @@ function OverlayContent({
3123
3188
  sx,
3124
3189
  ...rest
3125
3190
  }) {
3126
- const outerRef = (0, import_react9.useRef)(null);
3127
- const innerRef = (0, import_react9.useRef)(null);
3128
- (0, import_react9.useEffect)(() => {
3191
+ const outerRef = (0, import_react11.useRef)(null);
3192
+ const innerRef = (0, import_react11.useRef)(null);
3193
+ (0, import_react11.useEffect)(() => {
3129
3194
  const outer = outerRef.current;
3130
3195
  const inner = innerRef.current;
3131
3196
  if (!outer || !inner) return;
@@ -3154,7 +3219,7 @@ function OverlayContent({
3154
3219
  fit();
3155
3220
  return () => observer.disconnect();
3156
3221
  }, [padding, maxScale]);
3157
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3222
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3158
3223
  import_material2.Stack,
3159
3224
  {
3160
3225
  ref: outerRef,
@@ -3167,7 +3232,7 @@ function OverlayContent({
3167
3232
  ...sx
3168
3233
  },
3169
3234
  ...rest,
3170
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3235
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3171
3236
  import_material2.Stack,
3172
3237
  {
3173
3238
  ref: innerRef,
@@ -3186,8 +3251,8 @@ function OverlayContent({
3186
3251
 
3187
3252
  // src/overlay/FixedSizeContent.tsx
3188
3253
  var import_material3 = require("@mui/material");
3189
- var import_react10 = require("react");
3190
- var import_jsx_runtime4 = require("react/jsx-runtime");
3254
+ var import_react12 = require("react");
3255
+ var import_jsx_runtime6 = require("react/jsx-runtime");
3191
3256
  function FixedSizeContent({
3192
3257
  children,
3193
3258
  hideOnOverflow = true,
@@ -3195,9 +3260,9 @@ function FixedSizeContent({
3195
3260
  sx,
3196
3261
  ...rest
3197
3262
  }) {
3198
- const ref = (0, import_react10.useRef)(null);
3199
- const totalContentHeightRef = (0, import_react10.useRef)(0);
3200
- (0, import_react10.useEffect)(() => {
3263
+ const ref = (0, import_react12.useRef)(null);
3264
+ const totalContentHeightRef = (0, import_react12.useRef)(0);
3265
+ (0, import_react12.useEffect)(() => {
3201
3266
  const el = ref.current;
3202
3267
  if (!el) return;
3203
3268
  let clipAncestor = el.parentElement;
@@ -3234,7 +3299,7 @@ function FixedSizeContent({
3234
3299
  check();
3235
3300
  return () => observer.disconnect();
3236
3301
  }, [hideOnOverflow, truncationPadding]);
3237
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3302
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3238
3303
  import_material3.Stack,
3239
3304
  {
3240
3305
  ref,
@@ -3260,12 +3325,37 @@ function FixedSizeContent({
3260
3325
 
3261
3326
  // src/overlay/OverlayBadge.tsx
3262
3327
  var import_material4 = require("@mui/material");
3263
- var import_react11 = require("react");
3264
- var import_jsx_runtime5 = require("react/jsx-runtime");
3328
+ var import_react13 = require("react");
3329
+ var import_jsx_runtime7 = require("react/jsx-runtime");
3265
3330
  function toPx(v) {
3266
3331
  if (v === void 0) return void 0;
3267
3332
  return typeof v === "number" ? `${v}px` : v;
3268
3333
  }
3334
+ function deriveAngle(top, right, bottom, left) {
3335
+ const hasTop = top !== void 0;
3336
+ const hasRight = right !== void 0;
3337
+ const hasBottom = bottom !== void 0;
3338
+ const hasLeft = left !== void 0;
3339
+ if (hasTop && hasRight) return 45;
3340
+ if (hasTop && hasLeft) return 135;
3341
+ if (hasBottom && hasRight) return 315;
3342
+ if (hasBottom && hasLeft) return 225;
3343
+ if (hasTop) return 90;
3344
+ if (hasRight) return 0;
3345
+ if (hasBottom) return 270;
3346
+ if (hasLeft) return 180;
3347
+ return 45;
3348
+ }
3349
+ function ellipsePosition(angleDeg) {
3350
+ const rad = angleDeg * Math.PI / 180;
3351
+ return {
3352
+ pctX: 50 + 50 * Math.cos(rad),
3353
+ pctY: 50 - 50 * Math.sin(rad)
3354
+ };
3355
+ }
3356
+ function toNum(v) {
3357
+ return typeof v === "number" ? v : 0;
3358
+ }
3269
3359
  function OverlayBadge({
3270
3360
  children,
3271
3361
  maxScale = 2,
@@ -3274,12 +3364,13 @@ function OverlayBadge({
3274
3364
  right,
3275
3365
  bottom,
3276
3366
  left,
3367
+ circular = false,
3277
3368
  sx,
3278
3369
  ...rest
3279
3370
  }) {
3280
- const ref = (0, import_react11.useRef)(null);
3281
- const baseSize = (0, import_react11.useRef)(null);
3282
- (0, import_react11.useEffect)(() => {
3371
+ const ref = (0, import_react13.useRef)(null);
3372
+ const baseSize = (0, import_react13.useRef)(null);
3373
+ (0, import_react13.useEffect)(() => {
3283
3374
  const el = ref.current;
3284
3375
  if (!el) return;
3285
3376
  const ancestor = el.parentElement;
@@ -3304,7 +3395,8 @@ function OverlayBadge({
3304
3395
  const overlayScale = parseFloat(
3305
3396
  getComputedStyle(el).getPropertyValue("--overlay-scale")
3306
3397
  ) || 1;
3307
- el.style.transform = `scale(${ownScale / overlayScale})`;
3398
+ const scale = `scale(${ownScale / overlayScale})`;
3399
+ el.style.transform = circular ? `translate(-50%, -50%) ${scale}` : scale;
3308
3400
  });
3309
3401
  }
3310
3402
  const observer = new ResizeObserver(update);
@@ -3314,17 +3406,29 @@ function OverlayBadge({
3314
3406
  observer.disconnect();
3315
3407
  baseSize.current = null;
3316
3408
  };
3317
- }, [maxScale, minScale]);
3318
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3409
+ }, [maxScale, minScale, circular]);
3410
+ const positionSx = circular ? (() => {
3411
+ const angle = deriveAngle(top, right, bottom, left);
3412
+ const { pctX, pctY } = ellipsePosition(angle);
3413
+ const leftOffset = toNum(left) - toNum(right);
3414
+ const topOffset = toNum(top) - toNum(bottom);
3415
+ return {
3416
+ left: `calc(${pctX}% + ${leftOffset}px)`,
3417
+ top: `calc(${pctY}% + ${topOffset}px)`
3418
+ };
3419
+ })() : {
3420
+ top: toPx(top),
3421
+ right: toPx(right),
3422
+ bottom: toPx(bottom),
3423
+ left: toPx(left)
3424
+ };
3425
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3319
3426
  import_material4.Stack,
3320
3427
  {
3321
3428
  ref,
3322
3429
  sx: {
3323
3430
  position: "absolute",
3324
- top: toPx(top),
3325
- right: toPx(right),
3326
- bottom: toPx(bottom),
3327
- left: toPx(left),
3431
+ ...positionSx,
3328
3432
  transformOrigin: "center center",
3329
3433
  pointerEvents: "auto",
3330
3434
  width: "max-content",
@@ -3349,6 +3453,7 @@ var import_fabric19 = require("fabric");
3349
3453
  DEFAULT_DRAG_SHAPE_STYLE,
3350
3454
  DEFAULT_GUIDELINE_SHAPE_STYLE,
3351
3455
  DEFAULT_SHAPE_STYLE,
3456
+ EditCanvasProvider,
3352
3457
  FabricCanvas,
3353
3458
  FabricImage,
3354
3459
  FabricObject,
@@ -3359,6 +3464,7 @@ var import_fabric19 = require("fabric");
3359
3464
  Point,
3360
3465
  Polygon,
3361
3466
  Rect,
3467
+ ViewCanvasProvider,
3362
3468
  createCircle,
3363
3469
  createCircleAtPoint,
3364
3470
  createHistoryTracker,
@@ -3401,7 +3507,9 @@ var import_fabric19 = require("fabric");
3401
3507
  useCanvasEvents,
3402
3508
  useCanvasTooltip,
3403
3509
  useEditCanvas,
3510
+ useEditCanvasContext,
3404
3511
  useViewCanvas,
3512
+ useViewCanvasContext,
3405
3513
  util
3406
3514
  });
3407
3515
  //# sourceMappingURL=index.cjs.map