@bwp-web/canvas 0.4.2 → 0.5.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/index.cjs CHANGED
@@ -27,11 +27,12 @@ __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
- FabricCanvas: () => import_fabric19.Canvas,
31
- FabricImage: () => import_fabric19.FabricImage,
32
- FabricObject: () => import_fabric19.FabricObject,
33
- Polygon: () => import_fabric19.Polygon,
34
- Rect: () => import_fabric19.Rect,
30
+ FabricCanvas: () => import_fabric20.Canvas,
31
+ FabricImage: () => import_fabric20.FabricImage,
32
+ FabricObject: () => import_fabric20.FabricObject,
33
+ Point: () => import_fabric20.Point,
34
+ Polygon: () => import_fabric20.Polygon,
35
+ Rect: () => import_fabric20.Rect,
35
36
  createCircle: () => createCircle,
36
37
  createCircleAtPoint: () => createCircleAtPoint,
37
38
  createPolygon: () => createPolygon,
@@ -54,8 +55,9 @@ __export(index_exports, {
54
55
  enableScaledStrokes: () => enableScaledStrokes,
55
56
  enableVertexEdit: () => enableVertexEdit,
56
57
  fitViewportToBackground: () => fitViewportToBackground,
58
+ getBackgroundContrast: () => getBackgroundContrast,
57
59
  getBackgroundInverted: () => getBackgroundInverted,
58
- getBackgroundOpacity: () => getBackgroundOpacity,
60
+ getBackgroundSrc: () => getBackgroundSrc,
59
61
  getBaseStrokeWidth: () => getBaseStrokeWidth,
60
62
  getSnapPoints: () => getSnapPoints,
61
63
  loadCanvas: () => loadCanvas,
@@ -63,15 +65,17 @@ __export(index_exports, {
63
65
  resetViewport: () => resetViewport,
64
66
  resizeImageUrl: () => resizeImageUrl,
65
67
  serializeCanvas: () => serializeCanvas,
68
+ setBackgroundContrast: () => setBackgroundContrast,
66
69
  setBackgroundImage: () => setBackgroundImage,
67
70
  setBackgroundInverted: () => setBackgroundInverted,
68
- setBackgroundOpacity: () => setBackgroundOpacity,
69
71
  snapCursorPoint: () => snapCursorPoint,
70
72
  useCanvasClick: () => useCanvasClick,
71
73
  useCanvasEvents: () => useCanvasEvents,
72
74
  useCanvasTooltip: () => useCanvasTooltip,
73
75
  useEditCanvas: () => useEditCanvas,
74
- useViewCanvas: () => useViewCanvas
76
+ useObjectOverlay: () => useObjectOverlay,
77
+ useViewCanvas: () => useViewCanvas,
78
+ util: () => import_fabric20.util
75
79
  });
76
80
  module.exports = __toCommonJS(index_exports);
77
81
 
@@ -106,27 +110,56 @@ function enableKeyboardShortcuts(canvas) {
106
110
  // src/Canvas/Canvas.tsx
107
111
  var import_jsx_runtime = require("react/jsx-runtime");
108
112
  function Canvas({
109
- width = 800,
110
- height = 600,
113
+ width,
114
+ height,
111
115
  className,
112
116
  style,
113
117
  onReady
114
118
  }) {
115
119
  const canvasRef = (0, import_react.useRef)(null);
120
+ const wrapperRef = (0, import_react.useRef)(null);
121
+ const isFixedSize = width !== void 0 && height !== void 0;
116
122
  (0, import_react.useEffect)(() => {
117
123
  const el = canvasRef.current;
118
- if (!el) {
119
- return;
120
- }
121
- const fabricCanvas = new import_fabric2.Canvas(el, { width, height });
124
+ const wrapper = wrapperRef.current;
125
+ if (!el || !wrapper) return;
126
+ const initialWidth = isFixedSize ? width : wrapper.clientWidth || 800;
127
+ const initialHeight = isFixedSize ? height : wrapper.clientHeight || 600;
128
+ const fabricCanvas = new import_fabric2.Canvas(el, {
129
+ width: initialWidth,
130
+ height: initialHeight
131
+ });
122
132
  onReady?.(fabricCanvas);
123
133
  const cleanupShortcuts = enableKeyboardShortcuts(fabricCanvas);
134
+ let observer;
135
+ let rafId = 0;
136
+ if (!isFixedSize) {
137
+ let currentWidth = initialWidth;
138
+ let currentHeight = initialHeight;
139
+ observer = new ResizeObserver((entries) => {
140
+ cancelAnimationFrame(rafId);
141
+ rafId = requestAnimationFrame(() => {
142
+ const entry = entries[0];
143
+ if (!entry) return;
144
+ const { width: newWidth, height: newHeight } = entry.contentRect;
145
+ if (newWidth > 0 && newHeight > 0 && (newWidth !== currentWidth || newHeight !== currentHeight)) {
146
+ currentWidth = newWidth;
147
+ currentHeight = newHeight;
148
+ fabricCanvas.setDimensions({ width: newWidth, height: newHeight });
149
+ }
150
+ });
151
+ });
152
+ observer.observe(wrapper);
153
+ }
124
154
  return () => {
155
+ cancelAnimationFrame(rafId);
156
+ observer?.disconnect();
125
157
  cleanupShortcuts();
126
158
  fabricCanvas.dispose();
127
159
  };
128
160
  }, []);
129
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("canvas", { ref: canvasRef }) });
161
+ const wrapperStyle = isFixedSize ? { ...style } : { width: "100%", height: "100%", ...style };
162
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref: wrapperRef, className, style: wrapperStyle, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("canvas", { ref: canvasRef }) });
130
163
  }
131
164
 
132
165
  // src/hooks/useEditCanvas.ts
@@ -140,7 +173,7 @@ var import_fabric3 = require("fabric");
140
173
  var DEFAULT_MIN_ZOOM = 0.2;
141
174
  var DEFAULT_MAX_ZOOM = 10;
142
175
  var DEFAULT_ZOOM_FACTOR = 1.03;
143
- var DEFAULT_ZOOM_STEP = 0.2;
176
+ var DEFAULT_ZOOM_STEP = 1.2;
144
177
  var DEFAULT_VIEWPORT_PADDING = 0.05;
145
178
  var BASE_CANVAS_SIZE = 1e3;
146
179
  var DEFAULT_SNAP_MARGIN = 6;
@@ -322,20 +355,68 @@ function enablePanAndZoom(canvas, options) {
322
355
  setEnabled(value) {
323
356
  enabled = value;
324
357
  },
325
- zoomIn(step = DEFAULT_ZOOM_STEP) {
326
- const z = Math.min(canvas.getZoom() + step, bounds.maxZoom);
358
+ zoomIn(factor = DEFAULT_ZOOM_STEP) {
359
+ const z = Math.min(canvas.getZoom() * factor, bounds.maxZoom);
327
360
  canvas.zoomToPoint(
328
361
  new import_fabric3.Point(canvas.getWidth() / 2, canvas.getHeight() / 2),
329
362
  z
330
363
  );
331
364
  },
332
- zoomOut(step = DEFAULT_ZOOM_STEP) {
333
- const z = Math.max(canvas.getZoom() - step, bounds.minZoom);
365
+ zoomOut(factor = DEFAULT_ZOOM_STEP) {
366
+ const z = Math.max(canvas.getZoom() / factor, bounds.minZoom);
334
367
  canvas.zoomToPoint(
335
368
  new import_fabric3.Point(canvas.getWidth() / 2, canvas.getHeight() / 2),
336
369
  z
337
370
  );
338
371
  },
372
+ panToObject(object, panOpts) {
373
+ const zoom = canvas.getZoom();
374
+ const objectCenter = object.getCenterPoint();
375
+ const canvasCenterX = canvas.getWidth() / 2;
376
+ const canvasCenterY = canvas.getHeight() / 2;
377
+ const targetX = canvasCenterX - objectCenter.x * zoom;
378
+ const targetY = canvasCenterY - objectCenter.y * zoom;
379
+ if (!panOpts?.animate) {
380
+ const vt2 = canvas.viewportTransform;
381
+ if (!vt2) return;
382
+ canvas.setViewportTransform([
383
+ vt2[0],
384
+ vt2[1],
385
+ vt2[2],
386
+ vt2[3],
387
+ targetX,
388
+ targetY
389
+ ]);
390
+ return;
391
+ }
392
+ const duration = panOpts.duration ?? 300;
393
+ const vt = canvas.viewportTransform;
394
+ if (!vt) return;
395
+ const startX = vt[4];
396
+ const startY = vt[5];
397
+ const startTime = performance.now();
398
+ function step(now) {
399
+ const elapsed = now - startTime;
400
+ const t = Math.min(elapsed / duration, 1);
401
+ const eased = 1 - Math.pow(1 - t, 3);
402
+ const currentX = startX + (targetX - startX) * eased;
403
+ const currentY = startY + (targetY - startY) * eased;
404
+ const currentVt = canvas.viewportTransform;
405
+ if (!currentVt) return;
406
+ canvas.setViewportTransform([
407
+ currentVt[0],
408
+ currentVt[1],
409
+ currentVt[2],
410
+ currentVt[3],
411
+ currentX,
412
+ currentY
413
+ ]);
414
+ if (t < 1) {
415
+ requestAnimationFrame(step);
416
+ }
417
+ }
418
+ requestAnimationFrame(step);
419
+ },
339
420
  cleanup() {
340
421
  canvas.off("mouse:wheel", handleWheel);
341
422
  canvas.off("mouse:down", panHandlers.handleMouseDown);
@@ -354,6 +435,11 @@ var import_fabric4 = require("fabric");
354
435
  function getBackgroundImage(canvas) {
355
436
  return canvas.backgroundImage;
356
437
  }
438
+ function getBackgroundSrc(canvas) {
439
+ const bg = getBackgroundImage(canvas);
440
+ if (!bg) return null;
441
+ return bg.getSrc() || null;
442
+ }
357
443
  function fitViewportToBackground(canvas, options) {
358
444
  const bg = getBackgroundImage(canvas);
359
445
  if (!bg) return;
@@ -376,15 +462,37 @@ function fitViewportToBackground(canvas, options) {
376
462
  canvas.setViewportTransform([scale, 0, 0, scale, offsetX, offsetY]);
377
463
  canvas.requestRenderAll();
378
464
  }
379
- function setBackgroundOpacity(canvas, opacity) {
465
+ function setBackgroundContrast(canvas, value) {
380
466
  const bg = getBackgroundImage(canvas);
381
467
  if (!bg) return;
382
- bg.set("opacity", Math.min(1, Math.max(0, opacity)));
468
+ const contrast = Math.min(Math.max(value, 0), 2) - 1;
469
+ const currentFilters = bg.filters ?? [];
470
+ const contrastIdx = currentFilters.findIndex(
471
+ (f) => f instanceof import_fabric4.filters.Contrast
472
+ );
473
+ if (contrast === 0) {
474
+ if (contrastIdx >= 0) {
475
+ bg.filters = currentFilters.filter(
476
+ (f) => !(f instanceof import_fabric4.filters.Contrast)
477
+ );
478
+ bg.applyFilters();
479
+ }
480
+ } else if (contrastIdx >= 0) {
481
+ currentFilters[contrastIdx].contrast = contrast;
482
+ bg.applyFilters();
483
+ } else {
484
+ bg.filters = [...currentFilters, new import_fabric4.filters.Contrast({ contrast })];
485
+ bg.applyFilters();
486
+ }
383
487
  canvas.requestRenderAll();
384
488
  }
385
- function getBackgroundOpacity(canvas) {
489
+ function getBackgroundContrast(canvas) {
386
490
  const bg = getBackgroundImage(canvas);
387
- return bg?.opacity ?? 1;
491
+ if (!bg) return 1;
492
+ const contrastFilter = bg.filters?.find(
493
+ (f) => f instanceof import_fabric4.filters.Contrast
494
+ );
495
+ return 1 + (contrastFilter?.contrast ?? 0);
388
496
  }
389
497
  function setBackgroundInverted(canvas, inverted) {
390
498
  const bg = getBackgroundImage(canvas);
@@ -450,7 +558,7 @@ function resizeImageUrl(url, options) {
450
558
  });
451
559
  }
452
560
  async function setBackgroundImage(canvas, url, options) {
453
- const prevOpacity = options?.preserveOpacity ? getBackgroundOpacity(canvas) : void 0;
561
+ const prevContrast = options?.preserveContrast ? getBackgroundContrast(canvas) : void 0;
454
562
  let imageUrl = url;
455
563
  if (options !== void 0) {
456
564
  const result = await resizeImageUrl(url, options);
@@ -458,8 +566,8 @@ async function setBackgroundImage(canvas, url, options) {
458
566
  }
459
567
  const img = await import_fabric4.FabricImage.fromURL(imageUrl, { crossOrigin: "anonymous" });
460
568
  canvas.backgroundImage = img;
461
- if (prevOpacity !== void 0 && prevOpacity !== 1) {
462
- img.set("opacity", prevOpacity);
569
+ if (prevContrast !== void 0 && prevContrast !== 1) {
570
+ setBackgroundContrast(canvas, prevContrast);
463
571
  }
464
572
  canvas.requestRenderAll();
465
573
  return img;
@@ -489,7 +597,10 @@ function createViewportActions(canvasRef, viewportRef, setZoom) {
489
597
  viewportRef.current?.zoomOut(step);
490
598
  syncZoom(canvasRef, setZoom);
491
599
  };
492
- return { resetViewport: resetViewport2, zoomIn, zoomOut };
600
+ const panToObject = (object, panOpts) => {
601
+ viewportRef.current?.panToObject(object, panOpts);
602
+ };
603
+ return { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject };
493
604
  }
494
605
  function resolveAlignmentEnabled(enableAlignment, alignmentProp) {
495
606
  if (enableAlignment !== void 0) return enableAlignment;
@@ -1381,21 +1492,39 @@ function enableDragToCreate(canvas, factory, options) {
1381
1492
  options?.onCreated?.(obj);
1382
1493
  previewRect = null;
1383
1494
  };
1495
+ const handleKeyDown = (e) => {
1496
+ if (e.key === "Escape") {
1497
+ e.stopImmediatePropagation();
1498
+ e.preventDefault();
1499
+ cleanup("cancel");
1500
+ }
1501
+ };
1384
1502
  canvas.on("mouse:down", handleMouseDown);
1385
1503
  canvas.on("mouse:move", handleMouseMove);
1386
1504
  canvas.on("mouse:up", handleMouseUp);
1387
- return () => {
1505
+ document.addEventListener("keydown", handleKeyDown, true);
1506
+ let exited = false;
1507
+ function cleanup(reason) {
1508
+ if (exited) return;
1509
+ exited = true;
1388
1510
  canvas.off("mouse:down", handleMouseDown);
1389
1511
  canvas.off("mouse:move", handleMouseMove);
1390
1512
  canvas.off("mouse:up", handleMouseUp);
1513
+ document.removeEventListener("keydown", handleKeyDown, true);
1391
1514
  shiftTracker.cleanup();
1392
1515
  snapping.cleanup();
1393
1516
  if (isDrawing && previewRect) {
1517
+ snapping.excludeSet.delete(previewRect);
1394
1518
  canvas.remove(previewRect);
1519
+ canvas.selection = previousSelection;
1395
1520
  canvas.requestRenderAll();
1396
1521
  }
1397
1522
  restoreViewport(options?.viewport);
1398
- };
1523
+ if (reason === "cancel") {
1524
+ options?.onCancel?.();
1525
+ }
1526
+ }
1527
+ return () => cleanup();
1399
1528
  }
1400
1529
 
1401
1530
  // src/interactions/drawToCreate.ts
@@ -1671,6 +1800,9 @@ function enableDrawToCreate(canvas, options) {
1671
1800
  removePreviewElements();
1672
1801
  snapping.clearSnapResult();
1673
1802
  const polygon = createPolygonFromVertices(canvas, points, options?.style);
1803
+ if (options?.data) {
1804
+ polygon.data = options.data;
1805
+ }
1674
1806
  canvas.selection = previousSelection;
1675
1807
  canvas.requestRenderAll();
1676
1808
  restoreViewport(options?.viewport);
@@ -2041,6 +2173,7 @@ function serializeCanvas(canvas, options) {
2041
2173
  }
2042
2174
  });
2043
2175
  const json = canvas.toObject(properties);
2176
+ delete json.backgroundColor;
2044
2177
  scaledWidths.forEach((scaled, obj) => {
2045
2178
  obj.strokeWidth = scaled;
2046
2179
  });
@@ -2055,6 +2188,17 @@ async function loadCanvas(canvas, json, options) {
2055
2188
  });
2056
2189
  for (const obj of toRemove) canvas.remove(obj);
2057
2190
  }
2191
+ canvas.forEachObject((obj) => {
2192
+ if (obj.originX === "center" && obj.originY === "center") return;
2193
+ const center = obj.getCenterPoint();
2194
+ obj.set({
2195
+ originX: "center",
2196
+ originY: "center",
2197
+ left: center.x,
2198
+ top: center.y
2199
+ });
2200
+ obj.setCoords();
2201
+ });
2058
2202
  canvas.forEachObject((obj) => {
2059
2203
  obj.set(DEFAULT_CONTROL_STYLE);
2060
2204
  if (obj.shapeType === "circle" && obj instanceof import_fabric16.Rect) {
@@ -2062,6 +2206,7 @@ async function loadCanvas(canvas, json, options) {
2062
2206
  }
2063
2207
  });
2064
2208
  canvas.requestRenderAll();
2209
+ return canvas.getObjects();
2065
2210
  }
2066
2211
 
2067
2212
  // src/hooks/useEditCanvas.ts
@@ -2207,7 +2352,7 @@ function useEditCanvas(options) {
2207
2352
  viewportRef.current?.setMode(mode);
2208
2353
  setViewportModeState(mode);
2209
2354
  }, []);
2210
- const { resetViewport: resetViewport2, zoomIn, zoomOut } = createViewportActions(
2355
+ const { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject } = createViewportActions(
2211
2356
  canvasRef,
2212
2357
  viewportRef,
2213
2358
  setZoom
@@ -2216,7 +2361,7 @@ function useEditCanvas(options) {
2216
2361
  async (url, bgOpts) => {
2217
2362
  const canvas = canvasRef.current;
2218
2363
  if (!canvas) throw new Error("Canvas not ready");
2219
- const resizeOpts = options?.backgroundResize !== false ? typeof options?.backgroundResize === "object" ? { ...options.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveOpacity ? { preserveOpacity: true } : void 0;
2364
+ const resizeOpts = options?.backgroundResize !== false ? typeof options?.backgroundResize === "object" ? { ...options.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveContrast ? { preserveContrast: true } : void 0;
2220
2365
  const img = await setBackgroundImage(canvas, url, resizeOpts);
2221
2366
  if (options?.autoFitToBackground !== false) {
2222
2367
  fitViewportToBackground(canvas);
@@ -2247,7 +2392,9 @@ function useEditCanvas(options) {
2247
2392
  /** Zoom in toward the canvas center. Default step: 0.2. */
2248
2393
  zoomIn,
2249
2394
  /** Zoom out from the canvas center. Default step: 0.2. */
2250
- zoomOut
2395
+ zoomOut,
2396
+ /** Pan the viewport to center on a specific object. */
2397
+ panToObject
2251
2398
  },
2252
2399
  /** Whether vertex edit mode is currently active (reactive). */
2253
2400
  isEditingVertices,
@@ -2272,7 +2419,7 @@ function useEditCanvas(options) {
2272
2419
  * exceeds the configured limits (opt out via `backgroundResize: false`),
2273
2420
  * and fits the viewport after setting if `autoFitToBackground` is enabled.
2274
2421
  *
2275
- * Pass `{ preserveOpacity: true }` to keep the current background opacity
2422
+ * Pass `{ preserveContrast: true }` to keep the current background contrast
2276
2423
  * when replacing the image.
2277
2424
  */
2278
2425
  setBackground,
@@ -2337,7 +2484,7 @@ function useViewCanvas(options) {
2337
2484
  // eslint-disable-next-line react-hooks/exhaustive-deps
2338
2485
  []
2339
2486
  );
2340
- const { resetViewport: resetViewport2, zoomIn, zoomOut } = createViewportActions(
2487
+ const { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject } = createViewportActions(
2341
2488
  canvasRef,
2342
2489
  viewportRef,
2343
2490
  setZoom
@@ -2403,7 +2550,9 @@ function useViewCanvas(options) {
2403
2550
  /** Zoom in toward the canvas center. Default step: 0.2. */
2404
2551
  zoomIn,
2405
2552
  /** Zoom out from the canvas center. Default step: 0.2. */
2406
- zoomOut
2553
+ zoomOut,
2554
+ /** Pan the viewport to center on a specific object. */
2555
+ panToObject
2407
2556
  },
2408
2557
  /** Update a single object's visual style by its `data.id`. */
2409
2558
  setObjectStyle,
@@ -2554,8 +2703,68 @@ function useCanvasClick(canvasRef, onClick, options) {
2554
2703
  }, [canvasRef]);
2555
2704
  }
2556
2705
 
2557
- // src/index.ts
2706
+ // src/hooks/useObjectOverlay.ts
2707
+ var import_react7 = require("react");
2558
2708
  var import_fabric19 = require("fabric");
2709
+ function useObjectOverlay(canvasRef, object, options) {
2710
+ const containerRef = (0, import_react7.useRef)(null);
2711
+ const optionsRef = (0, import_react7.useRef)(options);
2712
+ optionsRef.current = options;
2713
+ (0, import_react7.useEffect)(() => {
2714
+ const canvas = canvasRef.current;
2715
+ if (!canvas || !object) return;
2716
+ function update() {
2717
+ const el = containerRef.current;
2718
+ if (!el || !canvas || !object) return;
2719
+ const zoom = canvas.getZoom();
2720
+ const vt = canvas.viewportTransform;
2721
+ if (!vt) return;
2722
+ const center = object.getCenterPoint();
2723
+ const actualWidth = (object.width ?? 0) * (object.scaleX ?? 1);
2724
+ const actualHeight = (object.height ?? 0) * (object.scaleY ?? 1);
2725
+ const screenCoords = import_fabric19.util.transformPoint(center, vt);
2726
+ const screenWidth = actualWidth * zoom;
2727
+ const screenHeight = actualHeight * zoom;
2728
+ el.style.left = `${screenCoords.x - screenWidth / 2}px`;
2729
+ el.style.top = `${screenCoords.y - screenHeight / 2}px`;
2730
+ el.style.width = `${screenWidth}px`;
2731
+ el.style.height = `${screenHeight}px`;
2732
+ const angle = object.angle ?? 0;
2733
+ el.style.rotate = angle !== 0 ? `${angle}deg` : "";
2734
+ const opts = optionsRef.current;
2735
+ if (opts?.autoScaleContent) {
2736
+ const contentScale = Math.min(screenWidth, screenHeight) / 100;
2737
+ const clampedScale = Math.max(0.1, Math.min(contentScale, 2));
2738
+ el.style.setProperty("--overlay-scale", String(clampedScale));
2739
+ if (opts.textSelector) {
2740
+ const textMinScale = opts.textMinScale ?? 0.5;
2741
+ const textEls = el.querySelectorAll(opts.textSelector);
2742
+ const display = clampedScale < textMinScale ? "none" : "";
2743
+ textEls.forEach((t) => {
2744
+ t.style.display = display;
2745
+ });
2746
+ }
2747
+ }
2748
+ }
2749
+ update();
2750
+ canvas.on("after:render", update);
2751
+ canvas.on("mouse:wheel", update);
2752
+ object.on("moving", update);
2753
+ object.on("scaling", update);
2754
+ object.on("rotating", update);
2755
+ return () => {
2756
+ canvas.off("after:render", update);
2757
+ canvas.off("mouse:wheel", update);
2758
+ object.off("moving", update);
2759
+ object.off("scaling", update);
2760
+ object.off("rotating", update);
2761
+ };
2762
+ }, [canvasRef, object]);
2763
+ return containerRef;
2764
+ }
2765
+
2766
+ // src/index.ts
2767
+ var import_fabric20 = require("fabric");
2559
2768
  // Annotate the CommonJS export names for ESM import in node:
2560
2769
  0 && (module.exports = {
2561
2770
  Canvas,
@@ -2568,6 +2777,7 @@ var import_fabric19 = require("fabric");
2568
2777
  FabricCanvas,
2569
2778
  FabricImage,
2570
2779
  FabricObject,
2780
+ Point,
2571
2781
  Polygon,
2572
2782
  Rect,
2573
2783
  createCircle,
@@ -2592,8 +2802,9 @@ var import_fabric19 = require("fabric");
2592
2802
  enableScaledStrokes,
2593
2803
  enableVertexEdit,
2594
2804
  fitViewportToBackground,
2805
+ getBackgroundContrast,
2595
2806
  getBackgroundInverted,
2596
- getBackgroundOpacity,
2807
+ getBackgroundSrc,
2597
2808
  getBaseStrokeWidth,
2598
2809
  getSnapPoints,
2599
2810
  loadCanvas,
@@ -2601,14 +2812,16 @@ var import_fabric19 = require("fabric");
2601
2812
  resetViewport,
2602
2813
  resizeImageUrl,
2603
2814
  serializeCanvas,
2815
+ setBackgroundContrast,
2604
2816
  setBackgroundImage,
2605
2817
  setBackgroundInverted,
2606
- setBackgroundOpacity,
2607
2818
  snapCursorPoint,
2608
2819
  useCanvasClick,
2609
2820
  useCanvasEvents,
2610
2821
  useCanvasTooltip,
2611
2822
  useEditCanvas,
2612
- useViewCanvas
2823
+ useObjectOverlay,
2824
+ useViewCanvas,
2825
+ util
2613
2826
  });
2614
2827
  //# sourceMappingURL=index.cjs.map