@bwp-web/canvas 0.4.0 → 0.4.2
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/background.d.ts +10 -3
- package/dist/background.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useCanvasClick.d.ts +27 -0
- package/dist/hooks/useCanvasClick.d.ts.map +1 -0
- package/dist/hooks/useCanvasEvents.d.ts +35 -0
- package/dist/hooks/useCanvasEvents.d.ts.map +1 -0
- package/dist/hooks/useCanvasTooltip.d.ts +45 -0
- package/dist/hooks/useCanvasTooltip.d.ts.map +1 -0
- package/dist/hooks/useEditCanvas.d.ts +16 -1
- package/dist/hooks/useEditCanvas.d.ts.map +1 -1
- package/dist/index.cjs +277 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +204 -16
- package/dist/index.js.map +1 -1
- package/dist/serialization.d.ts +12 -1
- package/dist/serialization.d.ts.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -5
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,12 @@ export { useEditCanvas } from './hooks';
|
|
|
5
5
|
export type { UseEditCanvasOptions } from './hooks';
|
|
6
6
|
export { useViewCanvas } from './hooks';
|
|
7
7
|
export type { UseViewCanvasOptions, ViewObjectStyle } from './hooks';
|
|
8
|
+
export { useCanvasEvents } from './hooks';
|
|
9
|
+
export type { CanvasEventHandlers } from './hooks';
|
|
10
|
+
export { useCanvasTooltip } from './hooks';
|
|
11
|
+
export type { UseCanvasTooltipOptions, CanvasTooltipState } from './hooks';
|
|
12
|
+
export { useCanvasClick } from './hooks';
|
|
13
|
+
export type { UseCanvasClickOptions } from './hooks';
|
|
8
14
|
export type { Point2D, ShapeStyleOptions, SnappingOptions, InteractionModeOptions, SnappableInteractionOptions, DragBounds, ModeSetup, } from './types';
|
|
9
15
|
export { createRectangle, createRectangleAtPoint, editRectangle, } from './shapes';
|
|
10
16
|
export type { RectangleOptions, RectangleAtPointOptions } from './shapes';
|
|
@@ -31,8 +37,9 @@ export { snapCursorPoint } from './alignment';
|
|
|
31
37
|
export type { CursorSnapResult, CursorSnapOptions, GuidelineStyle, } from './alignment';
|
|
32
38
|
export { deleteObjects, enableKeyboardShortcuts } from './keyboard';
|
|
33
39
|
export { enableScaledStrokes, serializeCanvas, loadCanvas, getBaseStrokeWidth, } from './serialization';
|
|
34
|
-
export type { SerializeOptions } from './serialization';
|
|
40
|
+
export type { SerializeOptions, LoadCanvasOptions } from './serialization';
|
|
35
41
|
export { fitViewportToBackground, setBackgroundOpacity, getBackgroundOpacity, setBackgroundInverted, getBackgroundInverted, resizeImageUrl, setBackgroundImage, } from './background';
|
|
36
|
-
export type { FitViewportOptions, ResizeResult, ResizeImageOptions, } from './background';
|
|
42
|
+
export type { FitViewportOptions, ResizeResult, ResizeImageOptions, SetBackgroundImageOptions, } from './background';
|
|
37
43
|
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';
|
|
38
45
|
//# 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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/fabricAugmentation.ts
|
|
2
|
+
import "fabric";
|
|
3
|
+
|
|
1
4
|
// src/Canvas/Canvas.tsx
|
|
2
5
|
import { Canvas as FabricCanvas } from "fabric";
|
|
3
6
|
import { useEffect, useRef } from "react";
|
|
@@ -369,14 +372,18 @@ function resizeImageUrl(url, options) {
|
|
|
369
372
|
img.src = url;
|
|
370
373
|
});
|
|
371
374
|
}
|
|
372
|
-
async function setBackgroundImage(canvas, url,
|
|
375
|
+
async function setBackgroundImage(canvas, url, options) {
|
|
376
|
+
const prevOpacity = options?.preserveOpacity ? getBackgroundOpacity(canvas) : void 0;
|
|
373
377
|
let imageUrl = url;
|
|
374
|
-
if (
|
|
375
|
-
const result = await resizeImageUrl(url,
|
|
378
|
+
if (options !== void 0) {
|
|
379
|
+
const result = await resizeImageUrl(url, options);
|
|
376
380
|
imageUrl = result.url;
|
|
377
381
|
}
|
|
378
382
|
const img = await FabricImage.fromURL(imageUrl, { crossOrigin: "anonymous" });
|
|
379
383
|
canvas.backgroundImage = img;
|
|
384
|
+
if (prevOpacity !== void 0 && prevOpacity !== 1) {
|
|
385
|
+
img.set("opacity", prevOpacity);
|
|
386
|
+
}
|
|
380
387
|
canvas.requestRenderAll();
|
|
381
388
|
return img;
|
|
382
389
|
}
|
|
@@ -1973,8 +1980,15 @@ function serializeCanvas(canvas, options) {
|
|
|
1973
1980
|
});
|
|
1974
1981
|
return json;
|
|
1975
1982
|
}
|
|
1976
|
-
async function loadCanvas(canvas, json) {
|
|
1983
|
+
async function loadCanvas(canvas, json, options) {
|
|
1977
1984
|
await canvas.loadFromJSON(json);
|
|
1985
|
+
if (options?.filter) {
|
|
1986
|
+
const toRemove = [];
|
|
1987
|
+
canvas.forEachObject((obj) => {
|
|
1988
|
+
if (!options.filter(obj)) toRemove.push(obj);
|
|
1989
|
+
});
|
|
1990
|
+
for (const obj of toRemove) canvas.remove(obj);
|
|
1991
|
+
}
|
|
1978
1992
|
canvas.forEachObject((obj) => {
|
|
1979
1993
|
obj.set(DEFAULT_CONTROL_STYLE);
|
|
1980
1994
|
if (obj.shapeType === "circle" && obj instanceof Rect5) {
|
|
@@ -1997,6 +2011,7 @@ function useEditCanvas(options) {
|
|
|
1997
2011
|
const [selected, setSelected] = useState([]);
|
|
1998
2012
|
const [viewportMode, setViewportModeState] = useState("select");
|
|
1999
2013
|
const [isEditingVertices, setIsEditingVertices] = useState(false);
|
|
2014
|
+
const [isDirty, setIsDirty] = useState(false);
|
|
2000
2015
|
const setMode = useCallback((setup) => {
|
|
2001
2016
|
vertexEditCleanupRef.current?.();
|
|
2002
2017
|
vertexEditCleanupRef.current = null;
|
|
@@ -2067,6 +2082,11 @@ function useEditCanvas(options) {
|
|
|
2067
2082
|
canvas.on("selection:cleared", () => {
|
|
2068
2083
|
setSelected([]);
|
|
2069
2084
|
});
|
|
2085
|
+
if (options?.trackChanges) {
|
|
2086
|
+
canvas.on("object:added", () => setIsDirty(true));
|
|
2087
|
+
canvas.on("object:removed", () => setIsDirty(true));
|
|
2088
|
+
canvas.on("object:modified", () => setIsDirty(true));
|
|
2089
|
+
}
|
|
2070
2090
|
if (options?.vertexEdit !== false) {
|
|
2071
2091
|
const vertexOpts = typeof options?.vertexEdit === "object" ? options.vertexEdit : void 0;
|
|
2072
2092
|
canvas.on("mouse:dblclick", (e) => {
|
|
@@ -2126,17 +2146,21 @@ function useEditCanvas(options) {
|
|
|
2126
2146
|
viewportRef,
|
|
2127
2147
|
setZoom
|
|
2128
2148
|
);
|
|
2129
|
-
const setBackground = useCallback(
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2149
|
+
const setBackground = useCallback(
|
|
2150
|
+
async (url, bgOpts) => {
|
|
2151
|
+
const canvas = canvasRef.current;
|
|
2152
|
+
if (!canvas) throw new Error("Canvas not ready");
|
|
2153
|
+
const resizeOpts = options?.backgroundResize !== false ? typeof options?.backgroundResize === "object" ? { ...options.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveOpacity ? { preserveOpacity: true } : void 0;
|
|
2154
|
+
const img = await setBackgroundImage(canvas, url, resizeOpts);
|
|
2155
|
+
if (options?.autoFitToBackground !== false) {
|
|
2156
|
+
fitViewportToBackground(canvas);
|
|
2157
|
+
syncZoom(canvasRef, setZoom);
|
|
2158
|
+
}
|
|
2159
|
+
return img;
|
|
2160
|
+
},
|
|
2161
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2162
|
+
[]
|
|
2163
|
+
);
|
|
2140
2164
|
return {
|
|
2141
2165
|
/** Pass this to `<Canvas onReady={...} />` */
|
|
2142
2166
|
onReady,
|
|
@@ -2181,8 +2205,15 @@ function useEditCanvas(options) {
|
|
|
2181
2205
|
* Set a background image from a URL. Automatically resizes if the image
|
|
2182
2206
|
* exceeds the configured limits (opt out via `backgroundResize: false`),
|
|
2183
2207
|
* and fits the viewport after setting if `autoFitToBackground` is enabled.
|
|
2208
|
+
*
|
|
2209
|
+
* Pass `{ preserveOpacity: true }` to keep the current background opacity
|
|
2210
|
+
* when replacing the image.
|
|
2184
2211
|
*/
|
|
2185
|
-
setBackground
|
|
2212
|
+
setBackground,
|
|
2213
|
+
/** Whether the canvas has been modified since the last `resetDirty()` call. Requires `trackChanges: true`. */
|
|
2214
|
+
isDirty,
|
|
2215
|
+
/** Reset the dirty flag (e.g., after a successful save). */
|
|
2216
|
+
resetDirty: useCallback(() => setIsDirty(false), [])
|
|
2186
2217
|
};
|
|
2187
2218
|
}
|
|
2188
2219
|
|
|
@@ -2316,6 +2347,155 @@ function useViewCanvas(options) {
|
|
|
2316
2347
|
setObjectStyleByType
|
|
2317
2348
|
};
|
|
2318
2349
|
}
|
|
2350
|
+
|
|
2351
|
+
// src/hooks/useCanvasEvents.ts
|
|
2352
|
+
import { useEffect as useEffect3, useRef as useRef4 } from "react";
|
|
2353
|
+
function useCanvasEvents(canvasRef, events) {
|
|
2354
|
+
const eventsRef = useRef4(events);
|
|
2355
|
+
eventsRef.current = events;
|
|
2356
|
+
useEffect3(() => {
|
|
2357
|
+
const canvas = canvasRef.current;
|
|
2358
|
+
if (!canvas) return;
|
|
2359
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
2360
|
+
for (const key of Object.keys(eventsRef.current)) {
|
|
2361
|
+
if (!eventsRef.current[key]) continue;
|
|
2362
|
+
const wrapped = (options) => {
|
|
2363
|
+
eventsRef.current[key]?.(options);
|
|
2364
|
+
};
|
|
2365
|
+
canvas.on(key, wrapped);
|
|
2366
|
+
wrappers.set(key, wrapped);
|
|
2367
|
+
}
|
|
2368
|
+
return () => {
|
|
2369
|
+
wrappers.forEach((handler, name) => {
|
|
2370
|
+
canvas.off(name, handler);
|
|
2371
|
+
});
|
|
2372
|
+
};
|
|
2373
|
+
}, [canvasRef]);
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
// src/hooks/useCanvasTooltip.ts
|
|
2377
|
+
import { useEffect as useEffect4, useRef as useRef5, useState as useState3 } from "react";
|
|
2378
|
+
function useCanvasTooltip(canvasRef, options) {
|
|
2379
|
+
const [state, setState] = useState3({
|
|
2380
|
+
visible: false,
|
|
2381
|
+
content: null,
|
|
2382
|
+
position: { x: 0, y: 0 }
|
|
2383
|
+
});
|
|
2384
|
+
const hoveredObjectRef = useRef5(null);
|
|
2385
|
+
const optionsRef = useRef5(options);
|
|
2386
|
+
optionsRef.current = options;
|
|
2387
|
+
useEffect4(() => {
|
|
2388
|
+
const canvas = canvasRef.current;
|
|
2389
|
+
if (!canvas) return;
|
|
2390
|
+
function calculatePosition(target) {
|
|
2391
|
+
const bounds = target.getBoundingRect();
|
|
2392
|
+
const zoom = canvas.getZoom();
|
|
2393
|
+
const vt = canvas.viewportTransform;
|
|
2394
|
+
if (!vt) return null;
|
|
2395
|
+
return {
|
|
2396
|
+
x: (bounds.left + bounds.width / 2) * zoom + vt[4],
|
|
2397
|
+
y: bounds.top * zoom + vt[5] - 10
|
|
2398
|
+
};
|
|
2399
|
+
}
|
|
2400
|
+
const handleMouseOver = (e) => {
|
|
2401
|
+
const target = e.target;
|
|
2402
|
+
if (!target) return;
|
|
2403
|
+
const content = optionsRef.current.getContent(target);
|
|
2404
|
+
if (content === null) return;
|
|
2405
|
+
if (hoveredObjectRef.current !== target) {
|
|
2406
|
+
hoveredObjectRef.current = target;
|
|
2407
|
+
const position = calculatePosition(target);
|
|
2408
|
+
if (position) {
|
|
2409
|
+
setState({ visible: true, content, position });
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
};
|
|
2413
|
+
const handleMouseOut = (e) => {
|
|
2414
|
+
if (e.target && hoveredObjectRef.current === e.target) {
|
|
2415
|
+
setState((prev) => ({ ...prev, visible: false }));
|
|
2416
|
+
hoveredObjectRef.current = null;
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
const updatePosition = () => {
|
|
2420
|
+
if (!hoveredObjectRef.current) return;
|
|
2421
|
+
const position = calculatePosition(hoveredObjectRef.current);
|
|
2422
|
+
if (position) {
|
|
2423
|
+
setState((prev) => prev.visible ? { ...prev, position } : prev);
|
|
2424
|
+
}
|
|
2425
|
+
};
|
|
2426
|
+
canvas.on("mouse:over", handleMouseOver);
|
|
2427
|
+
canvas.on("mouse:out", handleMouseOut);
|
|
2428
|
+
canvas.on("after:render", updatePosition);
|
|
2429
|
+
canvas.on("mouse:wheel", updatePosition);
|
|
2430
|
+
return () => {
|
|
2431
|
+
canvas.off("mouse:over", handleMouseOver);
|
|
2432
|
+
canvas.off("mouse:out", handleMouseOut);
|
|
2433
|
+
canvas.off("after:render", updatePosition);
|
|
2434
|
+
canvas.off("mouse:wheel", updatePosition);
|
|
2435
|
+
};
|
|
2436
|
+
}, [canvasRef]);
|
|
2437
|
+
return state;
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
// src/hooks/useCanvasClick.ts
|
|
2441
|
+
import { useEffect as useEffect5, useRef as useRef6 } from "react";
|
|
2442
|
+
function useCanvasClick(canvasRef, onClick, options) {
|
|
2443
|
+
const onClickRef = useRef6(onClick);
|
|
2444
|
+
onClickRef.current = onClick;
|
|
2445
|
+
const optionsRef = useRef6(options);
|
|
2446
|
+
optionsRef.current = options;
|
|
2447
|
+
useEffect5(() => {
|
|
2448
|
+
const canvas = canvasRef.current;
|
|
2449
|
+
if (!canvas) return;
|
|
2450
|
+
let mouseDown = null;
|
|
2451
|
+
let isPanning = false;
|
|
2452
|
+
const handleMouseDown = (e) => {
|
|
2453
|
+
const native = e.e instanceof TouchEvent ? e.e.touches[0] : e.e;
|
|
2454
|
+
if (native) {
|
|
2455
|
+
mouseDown = { x: native.clientX, y: native.clientY, time: Date.now() };
|
|
2456
|
+
isPanning = false;
|
|
2457
|
+
}
|
|
2458
|
+
};
|
|
2459
|
+
const handleMouseMove = (e) => {
|
|
2460
|
+
if (!mouseDown) return;
|
|
2461
|
+
const native = e.e instanceof TouchEvent ? e.e.touches[0] : e.e;
|
|
2462
|
+
if (!native) return;
|
|
2463
|
+
const threshold = optionsRef.current?.threshold ?? 5;
|
|
2464
|
+
const deltaX = Math.abs(native.clientX - mouseDown.x);
|
|
2465
|
+
const deltaY = Math.abs(native.clientY - mouseDown.y);
|
|
2466
|
+
if (deltaX > threshold || deltaY > threshold) {
|
|
2467
|
+
isPanning = true;
|
|
2468
|
+
}
|
|
2469
|
+
};
|
|
2470
|
+
const handleMouseUp = (e) => {
|
|
2471
|
+
if (!mouseDown) return;
|
|
2472
|
+
const maxDuration = optionsRef.current?.maxDuration ?? 300;
|
|
2473
|
+
const elapsed = Date.now() - mouseDown.time;
|
|
2474
|
+
if (!isPanning && elapsed < maxDuration) {
|
|
2475
|
+
onClickRef.current(e.target);
|
|
2476
|
+
}
|
|
2477
|
+
mouseDown = null;
|
|
2478
|
+
isPanning = false;
|
|
2479
|
+
};
|
|
2480
|
+
canvas.on("mouse:down", handleMouseDown);
|
|
2481
|
+
canvas.on("mouse:move", handleMouseMove);
|
|
2482
|
+
canvas.on("mouse:up", handleMouseUp);
|
|
2483
|
+
return () => {
|
|
2484
|
+
canvas.off("mouse:down", handleMouseDown);
|
|
2485
|
+
canvas.off("mouse:move", handleMouseMove);
|
|
2486
|
+
canvas.off("mouse:up", handleMouseUp);
|
|
2487
|
+
};
|
|
2488
|
+
}, [canvasRef]);
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
// src/index.ts
|
|
2492
|
+
import {
|
|
2493
|
+
Canvas as Canvas2,
|
|
2494
|
+
FabricObject as FabricObject5,
|
|
2495
|
+
FabricImage as FabricImage2,
|
|
2496
|
+
Rect as Rect7,
|
|
2497
|
+
Polygon as Polygon5
|
|
2498
|
+
} from "fabric";
|
|
2319
2499
|
export {
|
|
2320
2500
|
Canvas,
|
|
2321
2501
|
DEFAULT_ALIGNMENT_STYLE,
|
|
@@ -2324,6 +2504,11 @@ export {
|
|
|
2324
2504
|
DEFAULT_DRAG_SHAPE_STYLE,
|
|
2325
2505
|
DEFAULT_GUIDELINE_SHAPE_STYLE,
|
|
2326
2506
|
DEFAULT_SHAPE_STYLE,
|
|
2507
|
+
Canvas2 as FabricCanvas,
|
|
2508
|
+
FabricImage2 as FabricImage,
|
|
2509
|
+
FabricObject5 as FabricObject,
|
|
2510
|
+
Polygon5 as Polygon,
|
|
2511
|
+
Rect7 as Rect,
|
|
2327
2512
|
createCircle,
|
|
2328
2513
|
createCircleAtPoint,
|
|
2329
2514
|
createPolygon,
|
|
@@ -2359,6 +2544,9 @@ export {
|
|
|
2359
2544
|
setBackgroundInverted,
|
|
2360
2545
|
setBackgroundOpacity,
|
|
2361
2546
|
snapCursorPoint,
|
|
2547
|
+
useCanvasClick,
|
|
2548
|
+
useCanvasEvents,
|
|
2549
|
+
useCanvasTooltip,
|
|
2362
2550
|
useEditCanvas,
|
|
2363
2551
|
useViewCanvas
|
|
2364
2552
|
};
|