@bwp-web/canvas 0.9.3 → 0.9.4

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.js CHANGED
@@ -1527,7 +1527,8 @@ function enableDragToCreate(canvas, factory, options) {
1527
1527
  import {
1528
1528
  Circle,
1529
1529
  Line,
1530
- Point as Point7
1530
+ Point as Point7,
1531
+ Rect as Rect5
1531
1532
  } from "fabric";
1532
1533
 
1533
1534
  // src/shapes/rectangle.ts
@@ -1741,7 +1742,43 @@ function enableDrawToCreate(canvas, options) {
1741
1742
  let exited = false;
1742
1743
  const angleSnapEnabled = options?.angleSnap !== false;
1743
1744
  const angleInterval = typeof options?.angleSnap === "object" ? options.angleSnap.interval ?? DEFAULT_ANGLE_SNAP_INTERVAL : DEFAULT_ANGLE_SNAP_INTERVAL;
1744
- const shiftTracker = createShiftKeyTracker();
1745
+ const dragEnabled = options?.dragOnHold !== false;
1746
+ let dragPending = false;
1747
+ let isDragMode = false;
1748
+ let dragStartX = 0;
1749
+ let dragStartY = 0;
1750
+ let dragLastEndX = 0;
1751
+ let dragLastEndY = 0;
1752
+ let dragPreviewRect = null;
1753
+ const computeDragDimensions = (endX, endY) => {
1754
+ let width = Math.max(0, endX - dragStartX);
1755
+ let height = Math.max(0, endY - dragStartY);
1756
+ if (shiftTracker.held) {
1757
+ const size = Math.max(width, height);
1758
+ width = size;
1759
+ height = size;
1760
+ }
1761
+ return { width, height };
1762
+ };
1763
+ const updateDragPreview = (endX, endY) => {
1764
+ dragLastEndX = endX;
1765
+ dragLastEndY = endY;
1766
+ if (!isDragMode || !dragPreviewRect) return;
1767
+ const { width, height } = computeDragDimensions(endX, endY);
1768
+ dragPreviewRect.set({
1769
+ left: dragStartX + width / 2,
1770
+ top: dragStartY + height / 2,
1771
+ width,
1772
+ height
1773
+ });
1774
+ dragPreviewRect.setCoords();
1775
+ canvas.requestRenderAll();
1776
+ };
1777
+ const shiftTracker = createShiftKeyTracker(() => {
1778
+ if (isDragMode) {
1779
+ updateDragPreview(dragLastEndX, dragLastEndY);
1780
+ }
1781
+ });
1745
1782
  const points = [];
1746
1783
  const markers = [];
1747
1784
  const edgeLines = [];
@@ -1809,20 +1846,7 @@ function enableDrawToCreate(canvas, options) {
1809
1846
  options?.onCreated?.(obj);
1810
1847
  points.length = 0;
1811
1848
  };
1812
- const handleMouseDown = (event) => {
1813
- let { x, y } = event.scenePoint;
1814
- if (angleSnapEnabled && shiftTracker.held && points.length > 0) {
1815
- const ref = points[points.length - 1];
1816
- const angleSnapped = snapAngleToInterval({ x, y }, ref, angleInterval);
1817
- ({ x, y } = snapAlongRay(
1818
- angleSnapped,
1819
- ref,
1820
- (sx, sy) => snapping.snap(sx, sy)
1821
- ));
1822
- } else {
1823
- ({ x, y } = snapping.snap(x, y));
1824
- }
1825
- snapping.clearSnapResult();
1849
+ const placeVertex = (x, y) => {
1826
1850
  if (points.length >= 3) {
1827
1851
  const dx = x - points[0].x;
1828
1852
  const dy = y - points[0].y;
@@ -1859,7 +1883,63 @@ function enableDrawToCreate(canvas, options) {
1859
1883
  }
1860
1884
  canvas.requestRenderAll();
1861
1885
  };
1886
+ const handleMouseDown = (event) => {
1887
+ if (dragEnabled && points.length === 0) {
1888
+ const snapped = snapping.snap(event.scenePoint.x, event.scenePoint.y);
1889
+ dragStartX = snapped.x;
1890
+ dragStartY = snapped.y;
1891
+ dragLastEndX = dragStartX;
1892
+ dragLastEndY = dragStartY;
1893
+ dragPending = true;
1894
+ snapping.clearSnapResult();
1895
+ return;
1896
+ }
1897
+ let { x, y } = event.scenePoint;
1898
+ if (angleSnapEnabled && shiftTracker.held && points.length > 0) {
1899
+ const ref = points[points.length - 1];
1900
+ const angleSnapped = snapAngleToInterval({ x, y }, ref, angleInterval);
1901
+ ({ x, y } = snapAlongRay(
1902
+ angleSnapped,
1903
+ ref,
1904
+ (sx, sy) => snapping.snap(sx, sy)
1905
+ ));
1906
+ } else {
1907
+ ({ x, y } = snapping.snap(x, y));
1908
+ }
1909
+ snapping.clearSnapResult();
1910
+ placeVertex(x, y);
1911
+ };
1862
1912
  const handleMouseMove = (event) => {
1913
+ if (dragPending) {
1914
+ const dx = Math.abs(event.scenePoint.x - dragStartX);
1915
+ const dy = Math.abs(event.scenePoint.y - dragStartY);
1916
+ if (dx >= MIN_DRAG_SIZE || dy >= MIN_DRAG_SIZE) {
1917
+ isDragMode = true;
1918
+ dragPending = false;
1919
+ previousSelection = canvas.selection;
1920
+ canvas.selection = false;
1921
+ dragPreviewRect = new Rect5({
1922
+ ...DEFAULT_GUIDELINE_SHAPE_STYLE,
1923
+ left: dragStartX,
1924
+ top: dragStartY,
1925
+ width: 0,
1926
+ height: 0,
1927
+ selectable: false,
1928
+ evented: false
1929
+ });
1930
+ snapping.excludeSet.add(dragPreviewRect);
1931
+ canvas.add(dragPreviewRect);
1932
+ }
1933
+ return;
1934
+ }
1935
+ if (isDragMode && dragPreviewRect) {
1936
+ const { x: endX, y: endY } = snapping.snapWithGuidelines(
1937
+ event.scenePoint.x,
1938
+ event.scenePoint.y
1939
+ );
1940
+ updateDragPreview(endX, endY);
1941
+ return;
1942
+ }
1863
1943
  if (points.length === 0) return;
1864
1944
  const lastPoint = points[points.length - 1];
1865
1945
  let { x, y } = event.scenePoint;
@@ -1902,6 +1982,47 @@ function enableDrawToCreate(canvas, options) {
1902
1982
  }
1903
1983
  canvas.requestRenderAll();
1904
1984
  };
1985
+ const handleMouseUp = () => {
1986
+ if (isDragMode && dragPreviewRect) {
1987
+ isDragMode = false;
1988
+ snapping.clearSnapResult();
1989
+ const { width, height } = computeDragDimensions(
1990
+ dragLastEndX,
1991
+ dragLastEndY
1992
+ );
1993
+ snapping.excludeSet.delete(dragPreviewRect);
1994
+ canvas.remove(dragPreviewRect);
1995
+ dragPreviewRect = null;
1996
+ if (width < MIN_DRAG_SIZE && height < MIN_DRAG_SIZE) {
1997
+ canvas.selection = previousSelection;
1998
+ canvas.requestRenderAll();
1999
+ placeVertex(dragStartX, dragStartY);
2000
+ return;
2001
+ }
2002
+ const obj = createPolygonFromVertices(
2003
+ canvas,
2004
+ [
2005
+ { x: dragStartX, y: dragStartY },
2006
+ { x: dragStartX + width, y: dragStartY },
2007
+ { x: dragStartX + width, y: dragStartY + height },
2008
+ { x: dragStartX, y: dragStartY + height }
2009
+ ],
2010
+ options?.style
2011
+ );
2012
+ if (options?.data) {
2013
+ obj.data = options.data;
2014
+ }
2015
+ canvas.selection = previousSelection;
2016
+ canvas.requestRenderAll();
2017
+ restoreViewport(options?.viewport);
2018
+ options?.onCreated?.(obj);
2019
+ return;
2020
+ }
2021
+ if (dragPending) {
2022
+ dragPending = false;
2023
+ placeVertex(dragStartX, dragStartY);
2024
+ }
2025
+ };
1905
2026
  const handleKeyDown = (e) => {
1906
2027
  if (e.key === "Escape" || e.key === "Backspace") {
1907
2028
  e.stopImmediatePropagation();
@@ -1911,20 +2032,29 @@ function enableDrawToCreate(canvas, options) {
1911
2032
  };
1912
2033
  canvas.on("mouse:down", handleMouseDown);
1913
2034
  canvas.on("mouse:move", handleMouseMove);
2035
+ canvas.on("mouse:up", handleMouseUp);
1914
2036
  document.addEventListener("keydown", handleKeyDown, true);
1915
2037
  function cleanup(reason) {
1916
2038
  if (exited) return;
1917
2039
  exited = true;
1918
2040
  canvas.off("mouse:down", handleMouseDown);
1919
2041
  canvas.off("mouse:move", handleMouseMove);
2042
+ canvas.off("mouse:up", handleMouseUp);
1920
2043
  document.removeEventListener("keydown", handleKeyDown, true);
1921
2044
  shiftTracker.cleanup();
1922
2045
  snapping.cleanup();
1923
2046
  removePreviewElements();
1924
- if (points.length > 0) {
2047
+ if (dragPreviewRect) {
2048
+ snapping.excludeSet.delete(dragPreviewRect);
2049
+ canvas.remove(dragPreviewRect);
2050
+ dragPreviewRect = null;
2051
+ }
2052
+ if (points.length > 0 || isDragMode || dragPending) {
1925
2053
  canvas.selection = previousSelection;
1926
2054
  }
1927
2055
  points.length = 0;
2056
+ dragPending = false;
2057
+ isDragMode = false;
1928
2058
  canvas.requestRenderAll();
1929
2059
  restoreViewport(options?.viewport);
1930
2060
  if (reason === "cancel") {
@@ -2126,7 +2256,7 @@ function enableVertexEdit(canvas, polygon, options, onExit) {
2126
2256
  // src/serialization.ts
2127
2257
  import {
2128
2258
  FabricImage as FabricImage2,
2129
- Rect as Rect5,
2259
+ Rect as Rect6,
2130
2260
  filters as filters2
2131
2261
  } from "fabric";
2132
2262
  var strokeBaseMap = /* @__PURE__ */ new WeakMap();
@@ -2160,7 +2290,7 @@ function enableScaledBorderRadius(canvas, options) {
2160
2290
  const radius = options?.radius ?? DEFAULT_VIEW_BORDER_RADIUS;
2161
2291
  function applyScaledBorderRadius() {
2162
2292
  canvas.forEachObject((obj) => {
2163
- if (!(obj instanceof Rect5)) return;
2293
+ if (!(obj instanceof Rect6)) return;
2164
2294
  if (!borderRadiusBaseMap.has(obj)) return;
2165
2295
  const rx = radius / (obj.scaleX ?? 1);
2166
2296
  const ry = radius / (obj.scaleY ?? 1);
@@ -2171,7 +2301,7 @@ function enableScaledBorderRadius(canvas, options) {
2171
2301
  return () => {
2172
2302
  canvas.off("before:render", applyScaledBorderRadius);
2173
2303
  canvas.forEachObject((obj) => {
2174
- if (!(obj instanceof Rect5)) return;
2304
+ if (!(obj instanceof Rect6)) return;
2175
2305
  const base = borderRadiusBaseMap.get(obj);
2176
2306
  if (base !== void 0) {
2177
2307
  obj.set({ rx: base.rx, ry: base.ry });
@@ -2198,7 +2328,7 @@ function prepareStrokeWidths(canvas) {
2198
2328
  function prepareBorderRadii(canvas) {
2199
2329
  const appliedRadii = /* @__PURE__ */ new Map();
2200
2330
  canvas.forEachObject((obj) => {
2201
- if (!(obj instanceof Rect5)) return;
2331
+ if (!(obj instanceof Rect6)) return;
2202
2332
  const base = borderRadiusBaseMap.get(obj);
2203
2333
  if (base !== void 0) {
2204
2334
  appliedRadii.set(obj, { rx: obj.rx ?? 0, ry: obj.ry ?? 0 });
@@ -2349,11 +2479,11 @@ async function loadCanvas(canvas, json, options) {
2349
2479
  delete data.strokeWidthBase;
2350
2480
  }
2351
2481
  obj.set(DEFAULT_CONTROL_STYLE);
2352
- if (obj.shapeType === "circle" && obj instanceof Rect5) {
2482
+ if (obj.shapeType === "circle" && obj instanceof Rect6) {
2353
2483
  restoreCircleConstraints(obj);
2354
2484
  }
2355
2485
  const borderRadius = options?.borderRadius ?? DEFAULT_VIEW_BORDER_RADIUS;
2356
- if (borderRadius !== false && obj instanceof Rect5 && obj.shapeType !== "circle" && obj.data?.type !== "DEVICE") {
2486
+ if (borderRadius !== false && obj instanceof Rect6 && obj.shapeType !== "circle" && obj.data?.type !== "DEVICE") {
2357
2487
  borderRadiusBaseMap.set(obj, { rx: obj.rx ?? 0, ry: obj.ry ?? 0 });
2358
2488
  const rx = borderRadius / (obj.scaleX ?? 1);
2359
2489
  const ry = borderRadius / (obj.scaleY ?? 1);
@@ -2749,7 +2879,7 @@ function useEditCanvas(options) {
2749
2879
  canvasRef,
2750
2880
  /** Current zoom level (reactive). */
2751
2881
  zoom,
2752
- /** Loaded objects (reactive). Populated when `canvasData` is provided. */
2882
+ /** Canvas objects (reactive). Populated from `canvasData` on load, and kept in sync as objects are added or removed at runtime. */
2753
2883
  objects,
2754
2884
  /** Whether canvas data is currently being loaded. */
2755
2885
  isLoading,
@@ -3647,7 +3777,7 @@ import {
3647
3777
  Canvas as Canvas2,
3648
3778
  FabricObject as FabricObject5,
3649
3779
  FabricImage as FabricImage3,
3650
- Rect as Rect6,
3780
+ Rect as Rect7,
3651
3781
  Polygon as Polygon5,
3652
3782
  Point as Point9,
3653
3783
  util as util5
@@ -3670,7 +3800,7 @@ export {
3670
3800
  OverlayContent,
3671
3801
  Point9 as Point,
3672
3802
  Polygon5 as Polygon,
3673
- Rect6 as Rect,
3803
+ Rect7 as Rect,
3674
3804
  ViewCanvasProvider,
3675
3805
  createCircle,
3676
3806
  createCircleAtPoint,