@bwp-web/canvas 0.4.2 → 0.4.3
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/Canvas/Canvas.d.ts +11 -1
- package/dist/Canvas/Canvas.d.ts.map +1 -1
- package/dist/background.d.ts +5 -0
- package/dist/background.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/shared.d.ts +3 -2
- package/dist/hooks/shared.d.ts.map +1 -1
- package/dist/hooks/useEditCanvas.d.ts +2 -0
- package/dist/hooks/useEditCanvas.d.ts.map +1 -1
- package/dist/hooks/useObjectOverlay.d.ts +49 -0
- package/dist/hooks/useObjectOverlay.d.ts.map +1 -0
- package/dist/hooks/useViewCanvas.d.ts +3 -1
- package/dist/hooks/useViewCanvas.d.ts.map +1 -1
- package/dist/index.cjs +201 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +196 -17
- package/dist/index.js.map +1 -1
- package/dist/interactions/dragToCreate.d.ts +2 -0
- package/dist/interactions/dragToCreate.d.ts.map +1 -1
- package/dist/interactions/drawToCreate.d.ts +7 -1
- package/dist/interactions/drawToCreate.d.ts.map +1 -1
- package/dist/serialization.d.ts +1 -1
- package/dist/serialization.d.ts.map +1 -1
- package/dist/viewport.d.ts +12 -1
- package/dist/viewport.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export { useCanvasTooltip } from './hooks';
|
|
|
11
11
|
export type { UseCanvasTooltipOptions, CanvasTooltipState } from './hooks';
|
|
12
12
|
export { useCanvasClick } from './hooks';
|
|
13
13
|
export type { UseCanvasClickOptions } from './hooks';
|
|
14
|
+
export { useObjectOverlay } from './hooks';
|
|
15
|
+
export type { UseObjectOverlayOptions } from './hooks';
|
|
14
16
|
export type { Point2D, ShapeStyleOptions, SnappingOptions, InteractionModeOptions, SnappableInteractionOptions, DragBounds, ModeSetup, } from './types';
|
|
15
17
|
export { createRectangle, createRectangleAtPoint, editRectangle, } from './shapes';
|
|
16
18
|
export type { RectangleOptions, RectangleAtPointOptions } from './shapes';
|
|
@@ -26,7 +28,7 @@ export type { DrawToCreateOptions } from './interactions';
|
|
|
26
28
|
export { enableVertexEdit } from './interactions';
|
|
27
29
|
export type { VertexEditOptions } from './interactions';
|
|
28
30
|
export { enablePanAndZoom, resetViewport } from './viewport';
|
|
29
|
-
export type { ViewportController, ViewportMode, PanAndZoomOptions, } from './viewport';
|
|
31
|
+
export type { ViewportController, ViewportMode, PanAndZoomOptions, PanToObjectOptions, } from './viewport';
|
|
30
32
|
export { getSnapPoints, registerSnapPointExtractor } from './alignment';
|
|
31
33
|
export type { SnapPointExtractor } from './alignment';
|
|
32
34
|
export { enableObjectAlignment } from './alignment';
|
|
@@ -38,8 +40,8 @@ export type { CursorSnapResult, CursorSnapOptions, GuidelineStyle, } from './ali
|
|
|
38
40
|
export { deleteObjects, enableKeyboardShortcuts } from './keyboard';
|
|
39
41
|
export { enableScaledStrokes, serializeCanvas, loadCanvas, getBaseStrokeWidth, } from './serialization';
|
|
40
42
|
export type { SerializeOptions, LoadCanvasOptions } from './serialization';
|
|
41
|
-
export { fitViewportToBackground, setBackgroundOpacity, getBackgroundOpacity, setBackgroundInverted, getBackgroundInverted, resizeImageUrl, setBackgroundImage, } from './background';
|
|
43
|
+
export { fitViewportToBackground, getBackgroundSrc, setBackgroundOpacity, getBackgroundOpacity, setBackgroundInverted, getBackgroundInverted, resizeImageUrl, setBackgroundImage, } from './background';
|
|
42
44
|
export type { FitViewportOptions, ResizeResult, ResizeImageOptions, SetBackgroundImageOptions, } from './background';
|
|
43
45
|
export { DEFAULT_CONTROL_STYLE, DEFAULT_SHAPE_STYLE, DEFAULT_CIRCLE_STYLE, DEFAULT_DRAG_SHAPE_STYLE, DEFAULT_GUIDELINE_SHAPE_STYLE, DEFAULT_ALIGNMENT_STYLE, } from './styles';
|
|
44
|
-
export { Canvas as FabricCanvas, FabricObject, FabricImage, Rect, Polygon, } from 'fabric';
|
|
46
|
+
export { Canvas as FabricCanvas, FabricObject, FabricImage, Rect, Polygon, Point, util, } from 'fabric';
|
|
45
47
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,YAAY,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -29,27 +29,56 @@ function enableKeyboardShortcuts(canvas) {
|
|
|
29
29
|
// src/Canvas/Canvas.tsx
|
|
30
30
|
import { jsx } from "react/jsx-runtime";
|
|
31
31
|
function Canvas({
|
|
32
|
-
width
|
|
33
|
-
height
|
|
32
|
+
width,
|
|
33
|
+
height,
|
|
34
34
|
className,
|
|
35
35
|
style,
|
|
36
36
|
onReady
|
|
37
37
|
}) {
|
|
38
38
|
const canvasRef = useRef(null);
|
|
39
|
+
const wrapperRef = useRef(null);
|
|
40
|
+
const isFixedSize = width !== void 0 && height !== void 0;
|
|
39
41
|
useEffect(() => {
|
|
40
42
|
const el = canvasRef.current;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
43
|
+
const wrapper = wrapperRef.current;
|
|
44
|
+
if (!el || !wrapper) return;
|
|
45
|
+
const initialWidth = isFixedSize ? width : wrapper.clientWidth || 800;
|
|
46
|
+
const initialHeight = isFixedSize ? height : wrapper.clientHeight || 600;
|
|
47
|
+
const fabricCanvas = new FabricCanvas(el, {
|
|
48
|
+
width: initialWidth,
|
|
49
|
+
height: initialHeight
|
|
50
|
+
});
|
|
45
51
|
onReady?.(fabricCanvas);
|
|
46
52
|
const cleanupShortcuts = enableKeyboardShortcuts(fabricCanvas);
|
|
53
|
+
let observer;
|
|
54
|
+
let rafId = 0;
|
|
55
|
+
if (!isFixedSize) {
|
|
56
|
+
let currentWidth = initialWidth;
|
|
57
|
+
let currentHeight = initialHeight;
|
|
58
|
+
observer = new ResizeObserver((entries) => {
|
|
59
|
+
cancelAnimationFrame(rafId);
|
|
60
|
+
rafId = requestAnimationFrame(() => {
|
|
61
|
+
const entry = entries[0];
|
|
62
|
+
if (!entry) return;
|
|
63
|
+
const { width: newWidth, height: newHeight } = entry.contentRect;
|
|
64
|
+
if (newWidth > 0 && newHeight > 0 && (newWidth !== currentWidth || newHeight !== currentHeight)) {
|
|
65
|
+
currentWidth = newWidth;
|
|
66
|
+
currentHeight = newHeight;
|
|
67
|
+
fabricCanvas.setDimensions({ width: newWidth, height: newHeight });
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
observer.observe(wrapper);
|
|
72
|
+
}
|
|
47
73
|
return () => {
|
|
74
|
+
cancelAnimationFrame(rafId);
|
|
75
|
+
observer?.disconnect();
|
|
48
76
|
cleanupShortcuts();
|
|
49
77
|
fabricCanvas.dispose();
|
|
50
78
|
};
|
|
51
79
|
}, []);
|
|
52
|
-
|
|
80
|
+
const wrapperStyle = isFixedSize ? { ...style } : { width: "100%", height: "100%", ...style };
|
|
81
|
+
return /* @__PURE__ */ jsx("div", { ref: wrapperRef, className, style: wrapperStyle, children: /* @__PURE__ */ jsx("canvas", { ref: canvasRef }) });
|
|
53
82
|
}
|
|
54
83
|
|
|
55
84
|
// src/hooks/useEditCanvas.ts
|
|
@@ -57,7 +86,9 @@ import { useCallback, useEffect as useEffect2, useRef as useRef2, useState } fro
|
|
|
57
86
|
import { Polygon as Polygon4 } from "fabric";
|
|
58
87
|
|
|
59
88
|
// src/viewport.ts
|
|
60
|
-
import {
|
|
89
|
+
import {
|
|
90
|
+
Point
|
|
91
|
+
} from "fabric";
|
|
61
92
|
|
|
62
93
|
// src/constants.ts
|
|
63
94
|
var DEFAULT_MIN_ZOOM = 0.2;
|
|
@@ -259,6 +290,54 @@ function enablePanAndZoom(canvas, options) {
|
|
|
259
290
|
z
|
|
260
291
|
);
|
|
261
292
|
},
|
|
293
|
+
panToObject(object, panOpts) {
|
|
294
|
+
const zoom = canvas.getZoom();
|
|
295
|
+
const objectCenter = object.getCenterPoint();
|
|
296
|
+
const canvasCenterX = canvas.getWidth() / 2;
|
|
297
|
+
const canvasCenterY = canvas.getHeight() / 2;
|
|
298
|
+
const targetX = canvasCenterX - objectCenter.x * zoom;
|
|
299
|
+
const targetY = canvasCenterY - objectCenter.y * zoom;
|
|
300
|
+
if (!panOpts?.animate) {
|
|
301
|
+
const vt2 = canvas.viewportTransform;
|
|
302
|
+
if (!vt2) return;
|
|
303
|
+
canvas.setViewportTransform([
|
|
304
|
+
vt2[0],
|
|
305
|
+
vt2[1],
|
|
306
|
+
vt2[2],
|
|
307
|
+
vt2[3],
|
|
308
|
+
targetX,
|
|
309
|
+
targetY
|
|
310
|
+
]);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const duration = panOpts.duration ?? 300;
|
|
314
|
+
const vt = canvas.viewportTransform;
|
|
315
|
+
if (!vt) return;
|
|
316
|
+
const startX = vt[4];
|
|
317
|
+
const startY = vt[5];
|
|
318
|
+
const startTime = performance.now();
|
|
319
|
+
function step(now) {
|
|
320
|
+
const elapsed = now - startTime;
|
|
321
|
+
const t = Math.min(elapsed / duration, 1);
|
|
322
|
+
const eased = 1 - Math.pow(1 - t, 3);
|
|
323
|
+
const currentX = startX + (targetX - startX) * eased;
|
|
324
|
+
const currentY = startY + (targetY - startY) * eased;
|
|
325
|
+
const currentVt = canvas.viewportTransform;
|
|
326
|
+
if (!currentVt) return;
|
|
327
|
+
canvas.setViewportTransform([
|
|
328
|
+
currentVt[0],
|
|
329
|
+
currentVt[1],
|
|
330
|
+
currentVt[2],
|
|
331
|
+
currentVt[3],
|
|
332
|
+
currentX,
|
|
333
|
+
currentY
|
|
334
|
+
]);
|
|
335
|
+
if (t < 1) {
|
|
336
|
+
requestAnimationFrame(step);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
requestAnimationFrame(step);
|
|
340
|
+
},
|
|
262
341
|
cleanup() {
|
|
263
342
|
canvas.off("mouse:wheel", handleWheel);
|
|
264
343
|
canvas.off("mouse:down", panHandlers.handleMouseDown);
|
|
@@ -277,6 +356,11 @@ import { FabricImage, filters } from "fabric";
|
|
|
277
356
|
function getBackgroundImage(canvas) {
|
|
278
357
|
return canvas.backgroundImage;
|
|
279
358
|
}
|
|
359
|
+
function getBackgroundSrc(canvas) {
|
|
360
|
+
const bg = getBackgroundImage(canvas);
|
|
361
|
+
if (!bg) return null;
|
|
362
|
+
return bg.getSrc() || null;
|
|
363
|
+
}
|
|
280
364
|
function fitViewportToBackground(canvas, options) {
|
|
281
365
|
const bg = getBackgroundImage(canvas);
|
|
282
366
|
if (!bg) return;
|
|
@@ -412,7 +496,10 @@ function createViewportActions(canvasRef, viewportRef, setZoom) {
|
|
|
412
496
|
viewportRef.current?.zoomOut(step);
|
|
413
497
|
syncZoom(canvasRef, setZoom);
|
|
414
498
|
};
|
|
415
|
-
|
|
499
|
+
const panToObject = (object, panOpts) => {
|
|
500
|
+
viewportRef.current?.panToObject(object, panOpts);
|
|
501
|
+
};
|
|
502
|
+
return { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject };
|
|
416
503
|
}
|
|
417
504
|
function resolveAlignmentEnabled(enableAlignment, alignmentProp) {
|
|
418
505
|
if (enableAlignment !== void 0) return enableAlignment;
|
|
@@ -1308,21 +1395,39 @@ function enableDragToCreate(canvas, factory, options) {
|
|
|
1308
1395
|
options?.onCreated?.(obj);
|
|
1309
1396
|
previewRect = null;
|
|
1310
1397
|
};
|
|
1398
|
+
const handleKeyDown = (e) => {
|
|
1399
|
+
if (e.key === "Escape") {
|
|
1400
|
+
e.stopImmediatePropagation();
|
|
1401
|
+
e.preventDefault();
|
|
1402
|
+
cleanup("cancel");
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1311
1405
|
canvas.on("mouse:down", handleMouseDown);
|
|
1312
1406
|
canvas.on("mouse:move", handleMouseMove);
|
|
1313
1407
|
canvas.on("mouse:up", handleMouseUp);
|
|
1314
|
-
|
|
1408
|
+
document.addEventListener("keydown", handleKeyDown, true);
|
|
1409
|
+
let exited = false;
|
|
1410
|
+
function cleanup(reason) {
|
|
1411
|
+
if (exited) return;
|
|
1412
|
+
exited = true;
|
|
1315
1413
|
canvas.off("mouse:down", handleMouseDown);
|
|
1316
1414
|
canvas.off("mouse:move", handleMouseMove);
|
|
1317
1415
|
canvas.off("mouse:up", handleMouseUp);
|
|
1416
|
+
document.removeEventListener("keydown", handleKeyDown, true);
|
|
1318
1417
|
shiftTracker.cleanup();
|
|
1319
1418
|
snapping.cleanup();
|
|
1320
1419
|
if (isDrawing && previewRect) {
|
|
1420
|
+
snapping.excludeSet.delete(previewRect);
|
|
1321
1421
|
canvas.remove(previewRect);
|
|
1422
|
+
canvas.selection = previousSelection;
|
|
1322
1423
|
canvas.requestRenderAll();
|
|
1323
1424
|
}
|
|
1324
1425
|
restoreViewport(options?.viewport);
|
|
1325
|
-
|
|
1426
|
+
if (reason === "cancel") {
|
|
1427
|
+
options?.onCancel?.();
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return () => cleanup();
|
|
1326
1431
|
}
|
|
1327
1432
|
|
|
1328
1433
|
// src/interactions/drawToCreate.ts
|
|
@@ -1602,6 +1707,9 @@ function enableDrawToCreate(canvas, options) {
|
|
|
1602
1707
|
removePreviewElements();
|
|
1603
1708
|
snapping.clearSnapResult();
|
|
1604
1709
|
const polygon = createPolygonFromVertices(canvas, points, options?.style);
|
|
1710
|
+
if (options?.data) {
|
|
1711
|
+
polygon.data = options.data;
|
|
1712
|
+
}
|
|
1605
1713
|
canvas.selection = previousSelection;
|
|
1606
1714
|
canvas.requestRenderAll();
|
|
1607
1715
|
restoreViewport(options?.viewport);
|
|
@@ -1996,6 +2104,7 @@ async function loadCanvas(canvas, json, options) {
|
|
|
1996
2104
|
}
|
|
1997
2105
|
});
|
|
1998
2106
|
canvas.requestRenderAll();
|
|
2107
|
+
return canvas.getObjects();
|
|
1999
2108
|
}
|
|
2000
2109
|
|
|
2001
2110
|
// src/hooks/useEditCanvas.ts
|
|
@@ -2141,7 +2250,7 @@ function useEditCanvas(options) {
|
|
|
2141
2250
|
viewportRef.current?.setMode(mode);
|
|
2142
2251
|
setViewportModeState(mode);
|
|
2143
2252
|
}, []);
|
|
2144
|
-
const { resetViewport: resetViewport2, zoomIn, zoomOut } = createViewportActions(
|
|
2253
|
+
const { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject } = createViewportActions(
|
|
2145
2254
|
canvasRef,
|
|
2146
2255
|
viewportRef,
|
|
2147
2256
|
setZoom
|
|
@@ -2181,7 +2290,9 @@ function useEditCanvas(options) {
|
|
|
2181
2290
|
/** Zoom in toward the canvas center. Default step: 0.2. */
|
|
2182
2291
|
zoomIn,
|
|
2183
2292
|
/** Zoom out from the canvas center. Default step: 0.2. */
|
|
2184
|
-
zoomOut
|
|
2293
|
+
zoomOut,
|
|
2294
|
+
/** Pan the viewport to center on a specific object. */
|
|
2295
|
+
panToObject
|
|
2185
2296
|
},
|
|
2186
2297
|
/** Whether vertex edit mode is currently active (reactive). */
|
|
2187
2298
|
isEditingVertices,
|
|
@@ -2271,7 +2382,7 @@ function useViewCanvas(options) {
|
|
|
2271
2382
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2272
2383
|
[]
|
|
2273
2384
|
);
|
|
2274
|
-
const { resetViewport: resetViewport2, zoomIn, zoomOut } = createViewportActions(
|
|
2385
|
+
const { resetViewport: resetViewport2, zoomIn, zoomOut, panToObject } = createViewportActions(
|
|
2275
2386
|
canvasRef,
|
|
2276
2387
|
viewportRef,
|
|
2277
2388
|
setZoom
|
|
@@ -2337,7 +2448,9 @@ function useViewCanvas(options) {
|
|
|
2337
2448
|
/** Zoom in toward the canvas center. Default step: 0.2. */
|
|
2338
2449
|
zoomIn,
|
|
2339
2450
|
/** Zoom out from the canvas center. Default step: 0.2. */
|
|
2340
|
-
zoomOut
|
|
2451
|
+
zoomOut,
|
|
2452
|
+
/** Pan the viewport to center on a specific object. */
|
|
2453
|
+
panToObject
|
|
2341
2454
|
},
|
|
2342
2455
|
/** Update a single object's visual style by its `data.id`. */
|
|
2343
2456
|
setObjectStyle,
|
|
@@ -2488,13 +2601,75 @@ function useCanvasClick(canvasRef, onClick, options) {
|
|
|
2488
2601
|
}, [canvasRef]);
|
|
2489
2602
|
}
|
|
2490
2603
|
|
|
2604
|
+
// src/hooks/useObjectOverlay.ts
|
|
2605
|
+
import { useEffect as useEffect6, useRef as useRef7 } from "react";
|
|
2606
|
+
import { util as util4 } from "fabric";
|
|
2607
|
+
function useObjectOverlay(canvasRef, object, options) {
|
|
2608
|
+
const containerRef = useRef7(null);
|
|
2609
|
+
const optionsRef = useRef7(options);
|
|
2610
|
+
optionsRef.current = options;
|
|
2611
|
+
useEffect6(() => {
|
|
2612
|
+
const canvas = canvasRef.current;
|
|
2613
|
+
if (!canvas || !object) return;
|
|
2614
|
+
function update() {
|
|
2615
|
+
const el = containerRef.current;
|
|
2616
|
+
if (!el || !canvas || !object) return;
|
|
2617
|
+
const zoom = canvas.getZoom();
|
|
2618
|
+
const vt = canvas.viewportTransform;
|
|
2619
|
+
if (!vt) return;
|
|
2620
|
+
const center = object.getCenterPoint();
|
|
2621
|
+
const actualWidth = (object.width ?? 0) * (object.scaleX ?? 1);
|
|
2622
|
+
const actualHeight = (object.height ?? 0) * (object.scaleY ?? 1);
|
|
2623
|
+
const screenCoords = util4.transformPoint(center, vt);
|
|
2624
|
+
const screenWidth = actualWidth * zoom;
|
|
2625
|
+
const screenHeight = actualHeight * zoom;
|
|
2626
|
+
el.style.left = `${screenCoords.x - screenWidth / 2}px`;
|
|
2627
|
+
el.style.top = `${screenCoords.y - screenHeight / 2}px`;
|
|
2628
|
+
el.style.width = `${screenWidth}px`;
|
|
2629
|
+
el.style.height = `${screenHeight}px`;
|
|
2630
|
+
const angle = object.angle ?? 0;
|
|
2631
|
+
el.style.rotate = angle !== 0 ? `${angle}deg` : "";
|
|
2632
|
+
const opts = optionsRef.current;
|
|
2633
|
+
if (opts?.autoScaleContent) {
|
|
2634
|
+
const contentScale = Math.min(screenWidth, screenHeight) / 100;
|
|
2635
|
+
const clampedScale = Math.max(0.1, Math.min(contentScale, 2));
|
|
2636
|
+
el.style.setProperty("--overlay-scale", String(clampedScale));
|
|
2637
|
+
if (opts.textSelector) {
|
|
2638
|
+
const textMinScale = opts.textMinScale ?? 0.5;
|
|
2639
|
+
const textEls = el.querySelectorAll(opts.textSelector);
|
|
2640
|
+
const display = clampedScale < textMinScale ? "none" : "";
|
|
2641
|
+
textEls.forEach((t) => {
|
|
2642
|
+
t.style.display = display;
|
|
2643
|
+
});
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
update();
|
|
2648
|
+
canvas.on("after:render", update);
|
|
2649
|
+
canvas.on("mouse:wheel", update);
|
|
2650
|
+
object.on("moving", update);
|
|
2651
|
+
object.on("scaling", update);
|
|
2652
|
+
object.on("rotating", update);
|
|
2653
|
+
return () => {
|
|
2654
|
+
canvas.off("after:render", update);
|
|
2655
|
+
canvas.off("mouse:wheel", update);
|
|
2656
|
+
object.off("moving", update);
|
|
2657
|
+
object.off("scaling", update);
|
|
2658
|
+
object.off("rotating", update);
|
|
2659
|
+
};
|
|
2660
|
+
}, [canvasRef, object]);
|
|
2661
|
+
return containerRef;
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2491
2664
|
// src/index.ts
|
|
2492
2665
|
import {
|
|
2493
2666
|
Canvas as Canvas2,
|
|
2494
2667
|
FabricObject as FabricObject5,
|
|
2495
2668
|
FabricImage as FabricImage2,
|
|
2496
2669
|
Rect as Rect7,
|
|
2497
|
-
Polygon as Polygon5
|
|
2670
|
+
Polygon as Polygon5,
|
|
2671
|
+
Point as Point9,
|
|
2672
|
+
util as util5
|
|
2498
2673
|
} from "fabric";
|
|
2499
2674
|
export {
|
|
2500
2675
|
Canvas,
|
|
@@ -2507,6 +2682,7 @@ export {
|
|
|
2507
2682
|
Canvas2 as FabricCanvas,
|
|
2508
2683
|
FabricImage2 as FabricImage,
|
|
2509
2684
|
FabricObject5 as FabricObject,
|
|
2685
|
+
Point9 as Point,
|
|
2510
2686
|
Polygon5 as Polygon,
|
|
2511
2687
|
Rect7 as Rect,
|
|
2512
2688
|
createCircle,
|
|
@@ -2533,6 +2709,7 @@ export {
|
|
|
2533
2709
|
fitViewportToBackground,
|
|
2534
2710
|
getBackgroundInverted,
|
|
2535
2711
|
getBackgroundOpacity,
|
|
2712
|
+
getBackgroundSrc,
|
|
2536
2713
|
getBaseStrokeWidth,
|
|
2537
2714
|
getSnapPoints,
|
|
2538
2715
|
loadCanvas,
|
|
@@ -2548,6 +2725,8 @@ export {
|
|
|
2548
2725
|
useCanvasEvents,
|
|
2549
2726
|
useCanvasTooltip,
|
|
2550
2727
|
useEditCanvas,
|
|
2551
|
-
|
|
2728
|
+
useObjectOverlay,
|
|
2729
|
+
useViewCanvas,
|
|
2730
|
+
util5 as util
|
|
2552
2731
|
};
|
|
2553
2732
|
//# sourceMappingURL=index.js.map
|