@mhamz.01/easyflow-whiteboard 1.0.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/components/node/custom-node-overlay-layer.d.ts +44 -0
- package/dist/components/node/custom-node-overlay-layer.d.ts.map +1 -0
- package/dist/components/node/custom-node-overlay-layer.js +353 -0
- package/dist/components/node/custom-node.d.ts +17 -0
- package/dist/components/node/custom-node.d.ts.map +1 -0
- package/dist/components/node/custom-node.js +63 -0
- package/dist/components/node/document-node.d.ts +14 -0
- package/dist/components/node/document-node.d.ts.map +1 -0
- package/dist/components/node/document-node.js +58 -0
- package/dist/components/toolbar/document-dropdown.d.ts +14 -0
- package/dist/components/toolbar/document-dropdown.d.ts.map +1 -0
- package/dist/components/toolbar/document-dropdown.js +66 -0
- package/dist/components/toolbar/options/arrow-options.d.ts +8 -0
- package/dist/components/toolbar/options/arrow-options.d.ts.map +1 -0
- package/dist/components/toolbar/options/arrow-options.js +109 -0
- package/dist/components/toolbar/options/erase-option.d.ts +2 -0
- package/dist/components/toolbar/options/erase-option.d.ts.map +1 -0
- package/dist/components/toolbar/options/erase-option.js +20 -0
- package/dist/components/toolbar/options/image-options.d.ts +2 -0
- package/dist/components/toolbar/options/image-options.d.ts.map +1 -0
- package/dist/components/toolbar/options/image-options.js +10 -0
- package/dist/components/toolbar/options/line-options.d.ts +2 -0
- package/dist/components/toolbar/options/line-options.d.ts.map +1 -0
- package/dist/components/toolbar/options/line-options.js +46 -0
- package/dist/components/toolbar/options/pen-option.d.ts +2 -0
- package/dist/components/toolbar/options/pen-option.d.ts.map +1 -0
- package/dist/components/toolbar/options/pen-option.js +53 -0
- package/dist/components/toolbar/options/shape-option.d.ts +6 -0
- package/dist/components/toolbar/options/shape-option.d.ts.map +1 -0
- package/dist/components/toolbar/options/shape-option.js +58 -0
- package/dist/components/toolbar/options/text-option.d.ts +2 -0
- package/dist/components/toolbar/options/text-option.d.ts.map +1 -0
- package/dist/components/toolbar/options/text-option.js +73 -0
- package/dist/components/toolbar/task-dropdown.d.ts +15 -0
- package/dist/components/toolbar/task-dropdown.d.ts.map +1 -0
- package/dist/components/toolbar/task-dropdown.js +85 -0
- package/dist/components/toolbar/toolbar-button.d.ts +12 -0
- package/dist/components/toolbar/toolbar-button.d.ts.map +1 -0
- package/dist/components/toolbar/toolbar-button.js +8 -0
- package/dist/components/toolbar/toolbar-seperator.d.ts +6 -0
- package/dist/components/toolbar/toolbar-seperator.d.ts.map +1 -0
- package/dist/components/toolbar/toolbar-seperator.js +5 -0
- package/dist/components/toolbar/tooloptions-panel.d.ts +8 -0
- package/dist/components/toolbar/tooloptions-panel.d.ts.map +1 -0
- package/dist/components/toolbar/tooloptions-panel.js +88 -0
- package/dist/components/toolbar/whiteboard-toolbar.d.ts +28 -0
- package/dist/components/toolbar/whiteboard-toolbar.d.ts.map +1 -0
- package/dist/components/toolbar/whiteboard-toolbar.js +160 -0
- package/dist/components/ui/dropdown-menu.d.ts +26 -0
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/components/ui/dropdown-menu.js +51 -0
- package/dist/components/ui/label.d.ts +5 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +8 -0
- package/dist/components/ui/slider.d.ts +5 -0
- package/dist/components/ui/slider.d.ts.map +1 -0
- package/dist/components/ui/slider.js +14 -0
- package/dist/components/whiteboard/whiteboard-test.d.ts +2 -0
- package/dist/components/whiteboard/whiteboard-test.d.ts.map +1 -0
- package/dist/components/whiteboard/whiteboard-test.js +207 -0
- package/dist/components/whiteboard/whiteboard.d.ts +1 -0
- package/dist/components/whiteboard/whiteboard.d.ts.map +1 -0
- package/dist/components/whiteboard/whiteboard.js +911 -0
- package/dist/components/zoomcontrol/zoom-control.d.ts +9 -0
- package/dist/components/zoomcontrol/zoom-control.d.ts.map +1 -0
- package/dist/components/zoomcontrol/zoom-control.js +7 -0
- package/dist/hooks/useCanvasInit.d.ts +15 -0
- package/dist/hooks/useCanvasInit.d.ts.map +1 -0
- package/dist/hooks/useCanvasInit.js +89 -0
- package/dist/hooks/useDrawing.d.ts +23 -0
- package/dist/hooks/useDrawing.d.ts.map +1 -0
- package/dist/hooks/useDrawing.js +142 -0
- package/dist/hooks/useEraser.d.ts +27 -0
- package/dist/hooks/useEraser.d.ts.map +1 -0
- package/dist/hooks/useEraser.js +143 -0
- package/dist/hooks/useLiveUpdate.d.ts +9 -0
- package/dist/hooks/useLiveUpdate.d.ts.map +1 -0
- package/dist/hooks/useLiveUpdate.js +63 -0
- package/dist/hooks/useMouseHandlers.d.ts +25 -0
- package/dist/hooks/useMouseHandlers.d.ts.map +1 -0
- package/dist/hooks/useMouseHandlers.js +44 -0
- package/dist/hooks/usePan.d.ts +17 -0
- package/dist/hooks/usePan.d.ts.map +1 -0
- package/dist/hooks/usePan.js +80 -0
- package/dist/hooks/usePersistance.d.ts +13 -0
- package/dist/hooks/usePersistance.d.ts.map +1 -0
- package/dist/hooks/usePersistance.js +79 -0
- package/dist/hooks/useSelection.d.ts +21 -0
- package/dist/hooks/useSelection.d.ts.map +1 -0
- package/dist/hooks/useSelection.js +142 -0
- package/dist/hooks/useTextStyle.d.ts +9 -0
- package/dist/hooks/useTextStyle.d.ts.map +1 -0
- package/dist/hooks/useTextStyle.js +32 -0
- package/dist/hooks/useToolManager.d.ts +15 -0
- package/dist/hooks/useToolManager.d.ts.map +1 -0
- package/dist/hooks/useToolManager.js +115 -0
- package/dist/hooks/useZoom.d.ts +25 -0
- package/dist/hooks/useZoom.d.ts.map +1 -0
- package/dist/hooks/useZoom.js +133 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/lib/eraser-brush.d.ts +1 -0
- package/dist/lib/eraser-brush.d.ts.map +1 -0
- package/dist/lib/eraser-brush.js +21 -0
- package/dist/lib/fabric-arrow.d.ts +16 -0
- package/dist/lib/fabric-arrow.d.ts.map +1 -0
- package/dist/lib/fabric-arrow.js +50 -0
- package/dist/lib/fabric-bidirectional-arrow.d.ts +20 -0
- package/dist/lib/fabric-bidirectional-arrow.d.ts.map +1 -0
- package/dist/lib/fabric-bidirectional-arrow.js +65 -0
- package/dist/lib/fabric-frame.d.ts +7 -0
- package/dist/lib/fabric-frame.d.ts.map +1 -0
- package/dist/lib/fabric-frame.js +25 -0
- package/dist/lib/fabric-utils.d.ts +30 -0
- package/dist/lib/fabric-utils.d.ts.map +1 -0
- package/dist/lib/fabric-utils.js +273 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +5 -0
- package/dist/store/whiteboard-store.d.ts +99 -0
- package/dist/store/whiteboard-store.d.ts.map +1 -0
- package/dist/store/whiteboard-store.js +137 -0
- package/dist/types/canvas-node.d.ts +24 -0
- package/dist/types/canvas-node.d.ts.map +1 -0
- package/dist/types/canvas-node.js +1 -0
- package/package.json +34 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { useCallback, useEffect } from "react";
|
|
2
|
+
import { Point } from "fabric";
|
|
3
|
+
export const useZoom = ({ fabricCanvas, MIN_ZOOM, MAX_ZOOM, canvasZoom, canvasViewport, setCanvasZoom, setCanvasViewport, }) => {
|
|
4
|
+
const handleZoom = useCallback((newZoom, point) => {
|
|
5
|
+
const canvas = fabricCanvas.current;
|
|
6
|
+
if (!canvas)
|
|
7
|
+
return;
|
|
8
|
+
const clampedZoom = Math.min(Math.max(newZoom, MIN_ZOOM), MAX_ZOOM);
|
|
9
|
+
const pivot = point
|
|
10
|
+
? new Point(point.x, point.y)
|
|
11
|
+
: new Point(canvas.getWidth() / 2, canvas.getHeight() / 2);
|
|
12
|
+
canvas.zoomToPoint(pivot, clampedZoom);
|
|
13
|
+
const vpt = canvas.viewportTransform;
|
|
14
|
+
if (vpt) {
|
|
15
|
+
setCanvasZoom(clampedZoom);
|
|
16
|
+
setCanvasViewport({ x: vpt[4], y: vpt[5] });
|
|
17
|
+
}
|
|
18
|
+
canvas.requestRenderAll();
|
|
19
|
+
}, [MIN_ZOOM, MAX_ZOOM, setCanvasZoom, setCanvasViewport, fabricCanvas]);
|
|
20
|
+
// Wheel handler
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const canvas = fabricCanvas.current;
|
|
23
|
+
if (!canvas)
|
|
24
|
+
return;
|
|
25
|
+
const onWheel = (opt) => {
|
|
26
|
+
const e = opt.e;
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
e.stopPropagation();
|
|
29
|
+
const vpt = canvas.viewportTransform;
|
|
30
|
+
if (!vpt)
|
|
31
|
+
return;
|
|
32
|
+
if (e.ctrlKey || e.metaKey) {
|
|
33
|
+
// Zoom logic
|
|
34
|
+
const rect = canvas.getElement().getBoundingClientRect();
|
|
35
|
+
handleZoom(e.deltaY < 0 ? canvasZoom * 1.1 : canvasZoom / 1.1, { x: e.clientX - rect.left, y: e.clientY - rect.top });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Pan via wheel
|
|
39
|
+
const delta = e.deltaY;
|
|
40
|
+
const shiftDelta = e.deltaX || e.deltaY;
|
|
41
|
+
vpt[5] -= delta;
|
|
42
|
+
if (e.shiftKey)
|
|
43
|
+
vpt[4] -= shiftDelta;
|
|
44
|
+
setCanvasViewport({ x: vpt[4], y: vpt[5] });
|
|
45
|
+
// Sync selection coordinates
|
|
46
|
+
const activeObj = canvas.getActiveObject();
|
|
47
|
+
if (activeObj) {
|
|
48
|
+
activeObj.setCoords();
|
|
49
|
+
if (activeObj.type === "activeSelection") {
|
|
50
|
+
const objects = activeObj.getObjects();
|
|
51
|
+
objects.forEach((obj) => obj.setCoords());
|
|
52
|
+
activeObj.setCoords();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
canvas.calcOffset();
|
|
56
|
+
canvas.requestRenderAll();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
canvas.on("mouse:wheel", onWheel);
|
|
60
|
+
return () => canvas.off("mouse:wheel", onWheel);
|
|
61
|
+
}, [canvasZoom, canvasViewport, handleZoom, setCanvasViewport, fabricCanvas]);
|
|
62
|
+
// Prevent browser zoom
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const prevent = (e) => {
|
|
65
|
+
if (e.ctrlKey || e.metaKey)
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
};
|
|
68
|
+
window.addEventListener("wheel", prevent, { passive: false });
|
|
69
|
+
return () => window.removeEventListener("wheel", prevent);
|
|
70
|
+
}, []);
|
|
71
|
+
// Keyboard shortcuts
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
const onKey = (e) => {
|
|
74
|
+
if (e.target instanceof HTMLInputElement ||
|
|
75
|
+
e.target instanceof HTMLTextAreaElement)
|
|
76
|
+
return;
|
|
77
|
+
if (!(e.ctrlKey || e.metaKey))
|
|
78
|
+
return;
|
|
79
|
+
if (e.key === "=" || e.key === "+") {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
handleZoom(canvasZoom + 0.1);
|
|
82
|
+
}
|
|
83
|
+
else if (e.key === "-" || e.key === "_") {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
handleZoom(canvasZoom - 0.1);
|
|
86
|
+
}
|
|
87
|
+
else if (e.key === "0") {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
const canvas = fabricCanvas.current;
|
|
90
|
+
if (!canvas)
|
|
91
|
+
return;
|
|
92
|
+
canvas.setZoom(1);
|
|
93
|
+
const vpt = canvas.viewportTransform;
|
|
94
|
+
if (vpt) {
|
|
95
|
+
vpt[4] = 0;
|
|
96
|
+
vpt[5] = 0;
|
|
97
|
+
setCanvasViewport({ x: 0, y: 0 });
|
|
98
|
+
}
|
|
99
|
+
setCanvasZoom(1);
|
|
100
|
+
canvas.renderAll();
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
window.addEventListener("keydown", onKey);
|
|
104
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
105
|
+
}, [canvasZoom, handleZoom, setCanvasZoom, setCanvasViewport, fabricCanvas]);
|
|
106
|
+
// Sync viewport state
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
const canvas = fabricCanvas.current;
|
|
109
|
+
if (!canvas)
|
|
110
|
+
return;
|
|
111
|
+
const sync = () => {
|
|
112
|
+
const vpt = canvas.viewportTransform;
|
|
113
|
+
if (!vpt)
|
|
114
|
+
return;
|
|
115
|
+
const z = canvas.getZoom();
|
|
116
|
+
if (canvasViewport.x !== vpt[4] || canvasViewport.y !== vpt[5]) {
|
|
117
|
+
setCanvasViewport({ x: vpt[4], y: vpt[5] });
|
|
118
|
+
}
|
|
119
|
+
if (canvasZoom !== z) {
|
|
120
|
+
setCanvasZoom(z);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
canvas.on("after:render", sync);
|
|
124
|
+
canvas.on("object:moving", sync);
|
|
125
|
+
canvas.on("mouse:up", sync);
|
|
126
|
+
return () => {
|
|
127
|
+
canvas.off("after:render", sync);
|
|
128
|
+
canvas.off("object:moving", sync);
|
|
129
|
+
canvas.off("mouse:up", sync);
|
|
130
|
+
};
|
|
131
|
+
}, [fabricCanvas, setCanvasViewport, setCanvasZoom]);
|
|
132
|
+
return { handleZoom };
|
|
133
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// export {default as EasyflowWhiteboard} from "./components/whiteboard/whiteboard-test";
|
|
2
|
+
// export * from "./hooks/useCanvasInit";
|
|
3
|
+
// export * from "./hooks/useDrawing";
|
|
4
|
+
// export * from "./hooks/useEraser";
|
|
5
|
+
// export * from "./hooks/usePan";
|
|
6
|
+
// export * from "./hooks/useZoom";
|
|
7
|
+
// export * from "./hooks/useSelection";
|
|
8
|
+
// export * from "./hooks/useLiveUpdate";
|
|
9
|
+
// export * from "./hooks/useMouseHandlers";
|
|
10
|
+
// export * from "./hooks/usePersistance";
|
|
11
|
+
// export * from "./hooks/useToolManager";
|
|
12
|
+
// export * from "./hooks/useTextStyle";
|
|
13
|
+
// export * from "./lib/fabric-frame";
|
|
14
|
+
// export * from "./lib/fabric-arrow";
|
|
15
|
+
// export * from "./lib/fabric-bidirectional-arrow";
|
|
16
|
+
// export * from "./lib/fabric-utils";
|
|
17
|
+
// export * from "./lib/utils";
|
|
18
|
+
// export * from "./store/whiteboard-store";
|
|
19
|
+
// export * from "./components/toolbar/whiteboard-toolbar";
|
|
20
|
+
// export * from "./components/toolbar/tooloptions-panel";
|
|
21
|
+
// export * from "./components/node/custom-node-overlay-layer";
|
|
22
|
+
// export * from "./components/zoomcontrol/zoom-control";
|
|
23
|
+
// export * from "./components/whiteboard/whiteboard-test";
|
|
24
|
+
// export * from "./components/node/document-node";
|
|
25
|
+
// export * from "./components/node/custom-node";
|
|
26
|
+
// export * from "./components/toolbar/document-dropdown";
|
|
27
|
+
// export * from "./components/toolbar/task-dropdown";
|
|
28
|
+
// export * from "./components/toolbar/document-dropdown";
|
|
29
|
+
export { default as EasyflowWhiteboard } from "./components/whiteboard/whiteboard-test";
|
|
30
|
+
export { useWhiteboardStore } from './store/whiteboard-store';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=eraser-brush.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eraser-brush.d.ts","sourceRoot":"","sources":["../../src/lib/eraser-brush.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { PencilBrush,Path } from "fabric";
|
|
3
|
+
// export class EraserBrush extends PencilBrush {
|
|
4
|
+
// _finalizeAndAddPath() {
|
|
5
|
+
// const ctx = this.canvas.getContext();
|
|
6
|
+
// ctx.save();
|
|
7
|
+
// ctx.globalCompositeOperation = "destination-out";
|
|
8
|
+
// const pathData = this.convertPointsToSVGPath(this._points);
|
|
9
|
+
// const path = this.createPath(pathData);
|
|
10
|
+
// path.set({
|
|
11
|
+
// globalCompositeOperation: "destination-out",
|
|
12
|
+
// selectable: false,
|
|
13
|
+
// evented: false,
|
|
14
|
+
// });
|
|
15
|
+
// this.canvas.add(path);
|
|
16
|
+
// this.canvas.requestRenderAll();
|
|
17
|
+
// ctx.restore();
|
|
18
|
+
// this._resetShadow();
|
|
19
|
+
// this._points = [];
|
|
20
|
+
// }
|
|
21
|
+
// }
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Line, TClassProperties, FabricObjectProps, SerializedLineProps } from "fabric";
|
|
2
|
+
export declare class Arrow extends Line {
|
|
3
|
+
static type: string;
|
|
4
|
+
constructor(points: [number, number, number, number], options?: any);
|
|
5
|
+
_render(ctx: CanvasRenderingContext2D): void;
|
|
6
|
+
/**
|
|
7
|
+
* Fixes the Type signature mismatch.
|
|
8
|
+
* K extends keyof T = never ensures compatibility with the base class generics.
|
|
9
|
+
*/
|
|
10
|
+
toObject<T extends Omit<Partial<FabricObjectProps> & TClassProperties<this>, keyof SerializedLineProps>, K extends keyof T = never>(propertiesToInclude?: K[]): Pick<T, K> & SerializedLineProps;
|
|
11
|
+
/**
|
|
12
|
+
* Deserialization support
|
|
13
|
+
*/
|
|
14
|
+
static fromObject(object: any): Promise<Arrow>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=fabric-arrow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabric-arrow.d.ts","sourceRoot":"","sources":["../../src/lib/fabric-arrow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAiB,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAEvG,qBAAa,KAAM,SAAQ,IAAI;IAC7B,MAAM,CAAC,IAAI,SAAW;gBAIV,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG;IAInE,OAAO,CAAC,GAAG,EAAE,wBAAwB;IA2BrC;;;OAGG;IACH,QAAQ,CACN,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,mBAAmB,CAAC,EAC9F,CAAC,SAAS,MAAM,CAAC,GAAG,KAAK,EACzB,mBAAmB,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,mBAAmB;IAI9D;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC;CAU/C"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Line, classRegistry } from "fabric";
|
|
2
|
+
export class Arrow extends Line {
|
|
3
|
+
// Use the specific tuple type Fabric expects for Line
|
|
4
|
+
// This solves: "Target requires 4 element(s) but source may have fewer"
|
|
5
|
+
constructor(points, options) {
|
|
6
|
+
super(points, options);
|
|
7
|
+
}
|
|
8
|
+
_render(ctx) {
|
|
9
|
+
super._render(ctx);
|
|
10
|
+
const p = this.calcLinePoints();
|
|
11
|
+
const dx = p.x2 - p.x1;
|
|
12
|
+
const dy = p.y2 - p.y1;
|
|
13
|
+
const angle = Math.atan2(dy, dx);
|
|
14
|
+
const headLength = 15;
|
|
15
|
+
const headWidth = 10;
|
|
16
|
+
ctx.save();
|
|
17
|
+
ctx.translate(p.x2, p.y2);
|
|
18
|
+
ctx.rotate(angle);
|
|
19
|
+
ctx.beginPath();
|
|
20
|
+
ctx.moveTo(0, 0);
|
|
21
|
+
ctx.lineTo(-headLength, headWidth / 2);
|
|
22
|
+
ctx.lineTo(-headLength, -headWidth / 2);
|
|
23
|
+
ctx.closePath();
|
|
24
|
+
ctx.fillStyle = this.stroke || "#000000";
|
|
25
|
+
ctx.fill();
|
|
26
|
+
ctx.restore();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fixes the Type signature mismatch.
|
|
30
|
+
* K extends keyof T = never ensures compatibility with the base class generics.
|
|
31
|
+
*/
|
|
32
|
+
toObject(propertiesToInclude) {
|
|
33
|
+
return super.toObject(propertiesToInclude);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Deserialization support
|
|
37
|
+
*/
|
|
38
|
+
static fromObject(object) {
|
|
39
|
+
// Explicitly cast to the required tuple type [number, number, number, number]
|
|
40
|
+
const points = [
|
|
41
|
+
object.x1,
|
|
42
|
+
object.y1,
|
|
43
|
+
object.x2,
|
|
44
|
+
object.y2,
|
|
45
|
+
];
|
|
46
|
+
return Promise.resolve(new Arrow(points, object));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
Arrow.type = "arrow";
|
|
50
|
+
classRegistry.setClass(Arrow, "arrow");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Line, TClassProperties, FabricObjectProps, SerializedLineProps, ObjectEvents } from "fabric";
|
|
2
|
+
export declare class BidirectionalArrow extends Line<Partial<FabricObjectProps>, SerializedLineProps, ObjectEvents> {
|
|
3
|
+
static type: string;
|
|
4
|
+
headSize: number;
|
|
5
|
+
constructor(points: [number, number, number, number], options?: any);
|
|
6
|
+
static cacheProperties: string[];
|
|
7
|
+
_render(ctx: CanvasRenderingContext2D): void;
|
|
8
|
+
private _drawArrowHead;
|
|
9
|
+
/**
|
|
10
|
+
* Signature must be exact. Casting the return to 'any' allows us to bypass
|
|
11
|
+
* the Pick/Omit complexity of the Fabric v6 base type.
|
|
12
|
+
*/
|
|
13
|
+
toObject<T extends Omit<Partial<FabricObjectProps> & TClassProperties<this>, keyof SerializedLineProps>, K extends keyof T = never>(propertiesToInclude?: K[]): Pick<T, K> & SerializedLineProps;
|
|
14
|
+
/**
|
|
15
|
+
* Static side inheritance requires the return to be compatible with Promise<Line>.
|
|
16
|
+
* Casting the result to Promise<any> satisfies the static extension check.
|
|
17
|
+
*/
|
|
18
|
+
static fromObject(object: any): Promise<any>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=fabric-bidirectional-arrow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabric-bidirectional-arrow.d.ts","sourceRoot":"","sources":["../../src/lib/fabric-bidirectional-arrow.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,IAAI,EAEJ,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACb,MAAM,QAAQ,CAAC;AAGhB,qBAAa,kBAAmB,SAAQ,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,mBAAmB,EAAE,YAAY,CAAC;IACzG,OAAgB,IAAI,SAAyB;IAEtC,QAAQ,EAAE,MAAM,CAAC;gBAEZ,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG;IAKnE,OAAgB,eAAe,WAAyC;IAExE,OAAO,CAAC,GAAG,EAAE,wBAAwB;IA6BrC,OAAO,CAAC,cAAc;IAStB;;;OAGG;IACM,QAAQ,CACf,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,EAAE,MAAM,mBAAmB,CAAC,EAC9F,CAAC,SAAS,MAAM,CAAC,GAAG,KAAK,EACzB,mBAAmB,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,mBAAmB;IAO9D;;;OAGG;WACa,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;CAStD"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Line, classRegistry } from "fabric";
|
|
2
|
+
// We must include the third generic <ObjectEvents> to match the Line class signature perfectly
|
|
3
|
+
export class BidirectionalArrow extends Line {
|
|
4
|
+
constructor(points, options) {
|
|
5
|
+
super(points, options);
|
|
6
|
+
this.headSize = options?.headSize || 12;
|
|
7
|
+
}
|
|
8
|
+
_render(ctx) {
|
|
9
|
+
super._render(ctx);
|
|
10
|
+
const p = this.calcLinePoints();
|
|
11
|
+
const dx = p.x2 - p.x1;
|
|
12
|
+
const dy = p.y2 - p.y1;
|
|
13
|
+
const angle = Math.atan2(dy, dx);
|
|
14
|
+
const head = this.headSize;
|
|
15
|
+
ctx.save();
|
|
16
|
+
ctx.fillStyle = this.stroke || "#000000";
|
|
17
|
+
// End Arrowhead
|
|
18
|
+
ctx.save();
|
|
19
|
+
ctx.translate(p.x2, p.y2);
|
|
20
|
+
ctx.rotate(angle);
|
|
21
|
+
this._drawArrowHead(ctx, head);
|
|
22
|
+
ctx.restore();
|
|
23
|
+
// Start Arrowhead
|
|
24
|
+
ctx.save();
|
|
25
|
+
ctx.translate(p.x1, p.y1);
|
|
26
|
+
ctx.rotate(angle + Math.PI);
|
|
27
|
+
this._drawArrowHead(ctx, head);
|
|
28
|
+
ctx.restore();
|
|
29
|
+
ctx.restore();
|
|
30
|
+
}
|
|
31
|
+
_drawArrowHead(ctx, size) {
|
|
32
|
+
ctx.beginPath();
|
|
33
|
+
ctx.moveTo(0, 0);
|
|
34
|
+
ctx.lineTo(-size, size / 2);
|
|
35
|
+
ctx.lineTo(-size, -size / 2);
|
|
36
|
+
ctx.closePath();
|
|
37
|
+
ctx.fill();
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Signature must be exact. Casting the return to 'any' allows us to bypass
|
|
41
|
+
* the Pick/Omit complexity of the Fabric v6 base type.
|
|
42
|
+
*/
|
|
43
|
+
toObject(propertiesToInclude) {
|
|
44
|
+
return {
|
|
45
|
+
...super.toObject(propertiesToInclude),
|
|
46
|
+
headSize: this.headSize,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Static side inheritance requires the return to be compatible with Promise<Line>.
|
|
51
|
+
* Casting the result to Promise<any> satisfies the static extension check.
|
|
52
|
+
*/
|
|
53
|
+
static fromObject(object) {
|
|
54
|
+
const points = [
|
|
55
|
+
object.x1,
|
|
56
|
+
object.y1,
|
|
57
|
+
object.x2,
|
|
58
|
+
object.y2,
|
|
59
|
+
];
|
|
60
|
+
return Promise.resolve(new BidirectionalArrow(points, object));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
BidirectionalArrow.type = "bidirectional-arrow";
|
|
64
|
+
BidirectionalArrow.cacheProperties = [...Line.cacheProperties, "headSize"];
|
|
65
|
+
classRegistry.setClass(BidirectionalArrow, "bidirectional-arrow");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabric-frame.d.ts","sourceRoot":"","sources":["../../src/lib/fabric-frame.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,qBAAa,KAAM,SAAQ,IAAI;IAC7B,MAAM,CAAC,IAAI,SAAW;gBAEV,OAAO,GAAE,GAAQ;IAkB7B,eAAe,CAAC,GAAG,EAAE,wBAAwB;CAG9C"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// lib/fabric-frame.ts
|
|
2
|
+
import { Rect } from "fabric";
|
|
3
|
+
export class Frame extends Rect {
|
|
4
|
+
constructor(options = {}) {
|
|
5
|
+
super({
|
|
6
|
+
...options,
|
|
7
|
+
rx: 0,
|
|
8
|
+
ry: 0,
|
|
9
|
+
fill: "#FFFFFF",
|
|
10
|
+
stroke: "#E5E7EB", // Light gray border
|
|
11
|
+
strokeWidth: 1,
|
|
12
|
+
shadow: {
|
|
13
|
+
color: "rgba(0,0,0,0.1)",
|
|
14
|
+
blur: 4,
|
|
15
|
+
offsetX: 0,
|
|
16
|
+
offsetY: 2,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
// Override to ensure frames stay behind other objects
|
|
21
|
+
_renderControls(ctx) {
|
|
22
|
+
super._renderControls(ctx);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
Frame.type = "frame";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Canvas, FabricObject, FabricImage } from "fabric";
|
|
2
|
+
export declare const initializeFabricCanvas: (canvas: Canvas) => Canvas;
|
|
3
|
+
export declare const updateDrawingObject: (shape: FabricObject, toolType: string, startPoint: {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
}, currentPoint: {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
}) => void;
|
|
10
|
+
export declare const deleteSelectedObjects: (canvas: Canvas) => void;
|
|
11
|
+
export declare const exportCanvasToJSON: (canvas: Canvas) => void;
|
|
12
|
+
export declare const importCanvasFromJSON: (canvas: Canvas, json: string, callback?: () => void) => void;
|
|
13
|
+
export declare const exportCanvasToImage: (canvas: Canvas, format?: "png" | "jpeg") => string;
|
|
14
|
+
export declare const calculateDashArray: (strokeDashArray: number[] | null, strokeWidth: number) => number[] | undefined;
|
|
15
|
+
export declare const addText: (canvas: Canvas, options: {
|
|
16
|
+
text?: string;
|
|
17
|
+
x?: number;
|
|
18
|
+
y?: number;
|
|
19
|
+
fontSize?: number;
|
|
20
|
+
fontWeight?: string;
|
|
21
|
+
fontFamily?: string;
|
|
22
|
+
color?: string;
|
|
23
|
+
textAlign?: string;
|
|
24
|
+
}) => void;
|
|
25
|
+
export declare const addImageToCanvas: (canvas: Canvas, url: string) => Promise<FabricImage<Partial<import("fabric").ImageProps>, import("fabric").SerializedImageProps, import("fabric").ObjectEvents> | undefined>;
|
|
26
|
+
export declare const clearCanvas: (canvas: Canvas) => void;
|
|
27
|
+
export declare const zoomCanvas: (canvas: Canvas, zoomLevel: number) => void;
|
|
28
|
+
export declare const fitCanvasToObjects: (canvas: Canvas) => void;
|
|
29
|
+
export declare const addWelcomeContent: (canvas: Canvas, logoUrl: string) => Promise<void>;
|
|
30
|
+
//# sourceMappingURL=fabric-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fabric-utils.d.ts","sourceRoot":"","sources":["../../src/lib/fabric-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAmE,WAAW,EAAc,MAAM,QAAQ,CAAC;AAKxI,eAAO,MAAM,sBAAsB,GAAI,QAAQ,MAAM,WAkBpD,CAAC;AAQF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,YAAY,EACnB,UAAU,MAAM,EAChB,YAAY;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACpC,cAAc;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,SAwEvC,CAAC;AAKF,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,SASnD,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,SAEhD,CAAC;AAGF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,WAAW,MAAM,IAAI,SAMtB,CAAC;AAGF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,SAAQ,KAAK,GAAG,MAAc,WAO/B,CAAC;AAUF,eAAO,MAAM,kBAAkB,GAC7B,iBAAiB,MAAM,EAAE,GAAG,IAAI,EAChC,aAAa,MAAM,KAClB,MAAM,EAAE,GAAG,SAKb,CAAC;AAKF,eAAO,MAAM,OAAO,GAClB,QAAQ,MAAM,EACd,SAAS;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,SAmBF,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,EAAE,KAAK,MAAM,iJAuCjE,CAAC;AAGF,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,SAIzC,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,EAAE,WAAW,MAAM,SAG3D,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,SAoBhD,CAAC;AAIF,eAAO,MAAM,iBAAiB,GAAU,QAAQ,MAAM,EAAE,SAAS,MAAM,kBAoFtE,CAAC"}
|