@bwp-web/canvas 0.8.0 → 0.8.1

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"}
@@ -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
@@ -518,21 +518,26 @@ function setBackgroundContrast(canvas, value) {
518
518
  const contrastIdx = currentFilters.findIndex(
519
519
  (f) => f instanceof import_fabric4.filters.Contrast
520
520
  );
521
+ let changed = false;
521
522
  if (contrast === 0) {
522
523
  if (contrastIdx >= 0) {
523
524
  bg.filters = currentFilters.filter(
524
525
  (f) => !(f instanceof import_fabric4.filters.Contrast)
525
526
  );
526
527
  bg.applyFilters();
528
+ changed = true;
527
529
  }
528
530
  } else if (contrastIdx >= 0) {
529
531
  currentFilters[contrastIdx].contrast = contrast;
530
532
  bg.applyFilters();
533
+ changed = true;
531
534
  } else {
532
535
  bg.filters = [...currentFilters, new import_fabric4.filters.Contrast({ contrast })];
533
536
  bg.applyFilters();
537
+ changed = true;
534
538
  }
535
539
  canvas.requestRenderAll();
540
+ if (changed) canvas.fire("background:modified");
536
541
  }
537
542
  function getBackgroundContrast(canvas) {
538
543
  const bg = getBackgroundImage(canvas);
@@ -547,14 +552,18 @@ function setBackgroundInverted(canvas, inverted) {
547
552
  if (!bg) return;
548
553
  const currentFilters = bg.filters ?? [];
549
554
  const hasInvert = currentFilters.some((f) => f instanceof import_fabric4.filters.Invert);
555
+ let changed = false;
550
556
  if (inverted && !hasInvert) {
551
557
  bg.filters = [...currentFilters, new import_fabric4.filters.Invert()];
552
558
  bg.applyFilters();
559
+ changed = true;
553
560
  } else if (!inverted && hasInvert) {
554
561
  bg.filters = currentFilters.filter((f) => !(f instanceof import_fabric4.filters.Invert));
555
562
  bg.applyFilters();
563
+ changed = true;
556
564
  }
557
565
  canvas.requestRenderAll();
566
+ if (changed) canvas.fire("background:modified");
558
567
  }
559
568
  function getBackgroundInverted(canvas) {
560
569
  const bg = getBackgroundImage(canvas);
@@ -620,6 +629,7 @@ async function setBackgroundImage(canvas, url, options) {
620
629
  setBackgroundContrast(canvas, prevContrast);
621
630
  }
622
631
  canvas.requestRenderAll();
632
+ canvas.fire("background:modified");
623
633
  return img;
624
634
  }
625
635
 
@@ -2610,6 +2620,7 @@ function useEditCanvas(options) {
2610
2620
  canvas.on("object:added", () => setIsDirty(true));
2611
2621
  canvas.on("object:removed", () => setIsDirty(true));
2612
2622
  canvas.on("object:modified", () => setIsDirty(true));
2623
+ canvas.on("background:modified", () => setIsDirty(true));
2613
2624
  }
2614
2625
  if (opts?.history) {
2615
2626
  const syncHistoryState = () => {
@@ -2623,6 +2634,7 @@ function useEditCanvas(options) {
2623
2634
  canvas.on("object:added", syncHistoryState);
2624
2635
  canvas.on("object:removed", syncHistoryState);
2625
2636
  canvas.on("object:modified", syncHistoryState);
2637
+ canvas.on("background:modified", syncHistoryState);
2626
2638
  }
2627
2639
  if (opts?.vertexEdit !== false) {
2628
2640
  const vertexOpts = typeof opts?.vertexEdit === "object" ? opts.vertexEdit : void 0;
@@ -2754,6 +2766,8 @@ function useEditCanvas(options) {
2754
2766
  isDirty,
2755
2767
  /** Reset the dirty flag (e.g., after a successful save). */
2756
2768
  resetDirty: (0, import_react3.useCallback)(() => setIsDirty(false), []),
2769
+ /** Manually mark the canvas as dirty (e.g., after a custom operation not tracked automatically). */
2770
+ markDirty: (0, import_react3.useCallback)(() => setIsDirty(true), []),
2757
2771
  /** Undo the last change. Requires `history: true`. */
2758
2772
  undo: (0, import_react3.useCallback)(async () => {
2759
2773
  const h = historyRef.current;
@@ -2813,6 +2827,7 @@ function useViewCanvas(options) {
2813
2827
  canvas.on("object:added", () => {
2814
2828
  lockCanvas(canvas);
2815
2829
  });
2830
+ canvas.hoverCursor = "pointer";
2816
2831
  canvas.on("mouse:wheel", () => {
2817
2832
  setZoom(canvas.getZoom());
2818
2833
  });
@@ -3266,6 +3281,31 @@ function toPx(v) {
3266
3281
  if (v === void 0) return void 0;
3267
3282
  return typeof v === "number" ? `${v}px` : v;
3268
3283
  }
3284
+ function deriveAngle(top, right, bottom, left) {
3285
+ const hasTop = top !== void 0;
3286
+ const hasRight = right !== void 0;
3287
+ const hasBottom = bottom !== void 0;
3288
+ const hasLeft = left !== void 0;
3289
+ if (hasTop && hasRight) return 45;
3290
+ if (hasTop && hasLeft) return 135;
3291
+ if (hasBottom && hasRight) return 315;
3292
+ if (hasBottom && hasLeft) return 225;
3293
+ if (hasTop) return 90;
3294
+ if (hasRight) return 0;
3295
+ if (hasBottom) return 270;
3296
+ if (hasLeft) return 180;
3297
+ return 45;
3298
+ }
3299
+ function ellipsePosition(angleDeg) {
3300
+ const rad = angleDeg * Math.PI / 180;
3301
+ return {
3302
+ pctX: 50 + 50 * Math.cos(rad),
3303
+ pctY: 50 - 50 * Math.sin(rad)
3304
+ };
3305
+ }
3306
+ function toNum(v) {
3307
+ return typeof v === "number" ? v : 0;
3308
+ }
3269
3309
  function OverlayBadge({
3270
3310
  children,
3271
3311
  maxScale = 2,
@@ -3274,6 +3314,7 @@ function OverlayBadge({
3274
3314
  right,
3275
3315
  bottom,
3276
3316
  left,
3317
+ circular = false,
3277
3318
  sx,
3278
3319
  ...rest
3279
3320
  }) {
@@ -3304,7 +3345,8 @@ function OverlayBadge({
3304
3345
  const overlayScale = parseFloat(
3305
3346
  getComputedStyle(el).getPropertyValue("--overlay-scale")
3306
3347
  ) || 1;
3307
- el.style.transform = `scale(${ownScale / overlayScale})`;
3348
+ const scale = `scale(${ownScale / overlayScale})`;
3349
+ el.style.transform = circular ? `translate(-50%, -50%) ${scale}` : scale;
3308
3350
  });
3309
3351
  }
3310
3352
  const observer = new ResizeObserver(update);
@@ -3314,17 +3356,29 @@ function OverlayBadge({
3314
3356
  observer.disconnect();
3315
3357
  baseSize.current = null;
3316
3358
  };
3317
- }, [maxScale, minScale]);
3359
+ }, [maxScale, minScale, circular]);
3360
+ const positionSx = circular ? (() => {
3361
+ const angle = deriveAngle(top, right, bottom, left);
3362
+ const { pctX, pctY } = ellipsePosition(angle);
3363
+ const leftOffset = toNum(left) - toNum(right);
3364
+ const topOffset = toNum(top) - toNum(bottom);
3365
+ return {
3366
+ left: `calc(${pctX}% + ${leftOffset}px)`,
3367
+ top: `calc(${pctY}% + ${topOffset}px)`
3368
+ };
3369
+ })() : {
3370
+ top: toPx(top),
3371
+ right: toPx(right),
3372
+ bottom: toPx(bottom),
3373
+ left: toPx(left)
3374
+ };
3318
3375
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3319
3376
  import_material4.Stack,
3320
3377
  {
3321
3378
  ref,
3322
3379
  sx: {
3323
3380
  position: "absolute",
3324
- top: toPx(top),
3325
- right: toPx(right),
3326
- bottom: toPx(bottom),
3327
- left: toPx(left),
3381
+ ...positionSx,
3328
3382
  transformOrigin: "center center",
3329
3383
  pointerEvents: "auto",
3330
3384
  width: "max-content",