@bwp-web/canvas 0.9.3 → 0.10.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/hooks/useEditCanvas.d.ts +1 -1
- package/dist/hooks/useEditCanvas.d.ts.map +1 -1
- package/dist/index.cjs +146 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +156 -26
- package/dist/index.js.map +1 -1
- package/dist/interactions/drawToCreate.d.ts +14 -0
- package/dist/interactions/drawToCreate.d.ts.map +1 -1
- package/package.json +1 -1
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
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
/**
|
|
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
|
|
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
|
-
|
|
3803
|
+
Rect7 as Rect,
|
|
3674
3804
|
ViewCanvasProvider,
|
|
3675
3805
|
createCircle,
|
|
3676
3806
|
createCircleAtPoint,
|