@visns-studio/visns-components 4.10.47 → 5.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/package.json +28 -30
- package/src/components/cms/Field.jsx +39 -63
- package/src/components/crm/Breadcrumb.jsx +2 -18
- package/src/components/crm/DataGrid.jsx +23 -379
- package/src/components/crm/Field.jsx +16 -215
- package/src/components/crm/Form.jsx +81 -79
- package/src/components/crm/MultiSelect.jsx +25 -71
- package/src/components/crm/Navigation.jsx +7 -11
- package/src/components/crm/QrCode.jsx +8 -12
- package/src/components/crm/QuickAction.jsx +1 -0
- package/src/components/crm/generic/GenericAuth.jsx +2 -6
- package/src/components/crm/generic/GenericDashboard.jsx +30 -340
- package/src/components/crm/generic/GenericDetail.jsx +37 -80
- package/src/components/crm/generic/GenericDynamic.jsx +76 -94
- package/src/components/crm/generic/GenericFormBuilder.jsx +19 -79
- package/src/components/crm/generic/GenericIndex.jsx +1 -2
- package/src/components/crm/generic/styles/GenericDetail.module.scss +0 -51
- package/src/components/crm/generic/styles/GenericFormBuilder.module.scss +0 -5
- package/src/components/crm/styles/DataGrid.module.scss +25 -0
- package/src/components/crm/styles/Field.module.scss +0 -210
- package/src/components/crm/styles/Form.module.scss +0 -78
- package/src/components/crm/styles/Navigation.module.scss +4 -10
- package/src/components/crm/styles/QrCode.module.scss +0 -18
- package/src/index.js +0 -8
- package/src/components/crm/generic/styles/GenericDashboard.module.scss +0 -325
- package/src/components/crm/sketch/SketchField.jsx +0 -395
- package/src/components/crm/sketch/arrow.jsx +0 -108
- package/src/components/crm/sketch/circle.jsx +0 -75
- package/src/components/crm/sketch/default-tool.jsx +0 -16
- package/src/components/crm/sketch/fabrictool.jsx +0 -22
- package/src/components/crm/sketch/history.jsx +0 -144
- package/src/components/crm/sketch/json/config.json +0 -14
- package/src/components/crm/sketch/line.jsx +0 -64
- package/src/components/crm/sketch/pan.jsx +0 -48
- package/src/components/crm/sketch/pencil.jsx +0 -36
- package/src/components/crm/sketch/rectangle-label-object.jsx +0 -69
- package/src/components/crm/sketch/rectangle-label.jsx +0 -93
- package/src/components/crm/sketch/rectangle.jsx +0 -76
- package/src/components/crm/sketch/select.jsx +0 -16
- package/src/components/crm/sketch/tools.jsx +0 -11
- package/src/components/crm/sketch/utils.jsx +0 -67
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import FabricCanvasTool from './fabrictool';
|
|
2
|
-
import {
|
|
3
|
-
Line as FabricLine,
|
|
4
|
-
Triangle as FabricTriangle,
|
|
5
|
-
Group as FabricGroup,
|
|
6
|
-
} from 'fabric'; // Import specific classes
|
|
7
|
-
|
|
8
|
-
class Arrow extends FabricCanvasTool {
|
|
9
|
-
configureCanvas(props) {
|
|
10
|
-
const canvas = this._canvas;
|
|
11
|
-
|
|
12
|
-
// Disable selection and set up drawing mode
|
|
13
|
-
canvas.isDrawingMode = false;
|
|
14
|
-
canvas.selection = false;
|
|
15
|
-
canvas.forEachObject((o) => {
|
|
16
|
-
o.selectable = false;
|
|
17
|
-
o.evented = false;
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// Set arrow line properties
|
|
21
|
-
this._width = props.lineWidth || 1;
|
|
22
|
-
this._color = props.lineColor || 'black';
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
doMouseDown(o) {
|
|
26
|
-
this.isDown = true;
|
|
27
|
-
const canvas = this._canvas;
|
|
28
|
-
|
|
29
|
-
// Get initial mouse pointer position
|
|
30
|
-
const pointer = canvas.getPointer(o.e);
|
|
31
|
-
const points = [pointer.x, pointer.y, pointer.x, pointer.y];
|
|
32
|
-
|
|
33
|
-
// Create the main line of the arrow
|
|
34
|
-
this.line = new FabricLine(points, {
|
|
35
|
-
strokeWidth: this._width,
|
|
36
|
-
fill: this._color,
|
|
37
|
-
stroke: this._color,
|
|
38
|
-
originX: 'center',
|
|
39
|
-
originY: 'center',
|
|
40
|
-
selectable: false,
|
|
41
|
-
evented: false,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Create the arrowhead as a triangle
|
|
45
|
-
this.head = new FabricTriangle({
|
|
46
|
-
fill: this._color,
|
|
47
|
-
left: pointer.x,
|
|
48
|
-
top: pointer.y,
|
|
49
|
-
originX: 'center',
|
|
50
|
-
originY: 'center',
|
|
51
|
-
height: 3 * this._width,
|
|
52
|
-
width: 3 * this._width,
|
|
53
|
-
selectable: false,
|
|
54
|
-
evented: false,
|
|
55
|
-
angle: 90,
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Add both line and head to the canvas
|
|
59
|
-
canvas.add(this.line);
|
|
60
|
-
canvas.add(this.head);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
doMouseMove(o) {
|
|
64
|
-
if (!this.isDown) return;
|
|
65
|
-
const canvas = this._canvas;
|
|
66
|
-
const pointer = canvas.getPointer(o.e);
|
|
67
|
-
|
|
68
|
-
// Update the line endpoint as mouse moves
|
|
69
|
-
this.line.set({ x2: pointer.x, y2: pointer.y });
|
|
70
|
-
this.line.setCoords();
|
|
71
|
-
|
|
72
|
-
// Calculate angle for the arrowhead to point along the line
|
|
73
|
-
const xDelta = pointer.x - this.line.x1;
|
|
74
|
-
const yDelta = pointer.y - this.line.y1;
|
|
75
|
-
this.head.set({
|
|
76
|
-
left: pointer.x,
|
|
77
|
-
top: pointer.y,
|
|
78
|
-
angle: 90 + (Math.atan2(yDelta, xDelta) * 180) / Math.PI,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
// Render changes
|
|
82
|
-
canvas.requestRenderAll();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
doMouseUp() {
|
|
86
|
-
this.isDown = false;
|
|
87
|
-
const canvas = this._canvas;
|
|
88
|
-
|
|
89
|
-
// Remove separate line and head and group them into an arrow
|
|
90
|
-
canvas.remove(this.line);
|
|
91
|
-
canvas.remove(this.head);
|
|
92
|
-
|
|
93
|
-
const arrow = new FabricGroup([this.line, this.head], {
|
|
94
|
-
selectable: true,
|
|
95
|
-
evented: true,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Add the grouped arrow back to the canvas
|
|
99
|
-
canvas.add(arrow);
|
|
100
|
-
canvas.requestRenderAll();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
doMouseOut() {
|
|
104
|
-
this.isDown = false;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export default Arrow;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import FabricCanvasTool from './fabrictool';
|
|
2
|
-
import { Circle as FabricCircle } from 'fabric';
|
|
3
|
-
|
|
4
|
-
class Circle extends FabricCanvasTool {
|
|
5
|
-
constructor(canvas) {
|
|
6
|
-
super(canvas);
|
|
7
|
-
// Define event handlers as arrow functions for consistent references
|
|
8
|
-
this.doMouseDown = (o) => this._doMouseDown(o);
|
|
9
|
-
this.doMouseMove = (o) => this._doMouseMove(o);
|
|
10
|
-
this.doMouseUp = () => this._doMouseUp();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
configureCanvas(props) {
|
|
14
|
-
const canvas = this._canvas;
|
|
15
|
-
canvas.isDrawingMode = false; // Disable drawing mode for custom drawing
|
|
16
|
-
canvas.selection = false;
|
|
17
|
-
this._width = props.lineWidth || 2;
|
|
18
|
-
this._color = props.lineColor || 'black';
|
|
19
|
-
this._fill = props.fillColor || 'transparent';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
attachListeners() {
|
|
23
|
-
this._canvas.on('mouse:down', this.doMouseDown);
|
|
24
|
-
this._canvas.on('mouse:move', this.doMouseMove);
|
|
25
|
-
this._canvas.on('mouse:up', this.doMouseUp);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
detachListeners() {
|
|
29
|
-
this._canvas.off('mouse:down', this.doMouseDown);
|
|
30
|
-
this._canvas.off('mouse:move', this.doMouseMove);
|
|
31
|
-
this._canvas.off('mouse:up', this.doMouseUp);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
_doMouseDown(o) {
|
|
35
|
-
const canvas = this._canvas;
|
|
36
|
-
this.isDown = true;
|
|
37
|
-
const pointer = canvas.getPointer(o.e);
|
|
38
|
-
this.startX = pointer.x;
|
|
39
|
-
this.startY = pointer.y;
|
|
40
|
-
|
|
41
|
-
this.circle = new FabricCircle({
|
|
42
|
-
left: this.startX,
|
|
43
|
-
top: this.startY,
|
|
44
|
-
originX: 'center',
|
|
45
|
-
originY: 'center',
|
|
46
|
-
strokeWidth: this._width,
|
|
47
|
-
stroke: this._color,
|
|
48
|
-
fill: this._fill,
|
|
49
|
-
radius: 1, // Start with a minimal radius, updated on `doMouseMove`
|
|
50
|
-
selectable: false,
|
|
51
|
-
evented: false,
|
|
52
|
-
});
|
|
53
|
-
canvas.add(this.circle);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
_doMouseMove(o) {
|
|
57
|
-
if (!this.isDown) return;
|
|
58
|
-
const canvas = this._canvas;
|
|
59
|
-
const pointer = canvas.getPointer(o.e);
|
|
60
|
-
const radius = Math.sqrt(
|
|
61
|
-
Math.pow(pointer.x - this.startX, 2) +
|
|
62
|
-
Math.pow(pointer.y - this.startY, 2)
|
|
63
|
-
);
|
|
64
|
-
|
|
65
|
-
this.circle.set({ radius });
|
|
66
|
-
this.circle.setCoords();
|
|
67
|
-
canvas.renderAll();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
_doMouseUp() {
|
|
71
|
-
this.isDown = false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export default Circle;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/*eslint no-unused-vars: 0*/
|
|
2
|
-
|
|
3
|
-
import FabricCanvasTool from './fabrictool';
|
|
4
|
-
|
|
5
|
-
class DefaultTool extends FabricCanvasTool {
|
|
6
|
-
configureCanvas(props) {
|
|
7
|
-
let canvas = this._canvas;
|
|
8
|
-
canvas.isDrawingMode = canvas.selection = false;
|
|
9
|
-
canvas.forEachObject((o) => (o.selectable = o.evented = false));
|
|
10
|
-
canvas.discardActiveObject();
|
|
11
|
-
canvas.defaultCursor = 'pointer';
|
|
12
|
-
canvas.renderAll();
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export default DefaultTool;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/* eslint no-unused-vars: 0 */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* "Abstract" like base class for a Canvas tool
|
|
5
|
-
*/
|
|
6
|
-
class FabricCanvasTool {
|
|
7
|
-
constructor(canvas) {
|
|
8
|
-
this._canvas = canvas;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
configureCanvas(props) {}
|
|
12
|
-
|
|
13
|
-
doMouseUp(event) {}
|
|
14
|
-
|
|
15
|
-
doMouseDown(event) {}
|
|
16
|
-
|
|
17
|
-
doMouseMove(event) {}
|
|
18
|
-
|
|
19
|
-
doMouseOut(event) {}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default FabricCanvasTool;
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Maintains the history of an object
|
|
3
|
-
*/
|
|
4
|
-
class History {
|
|
5
|
-
constructor(undoLimit = 10, debug = false) {
|
|
6
|
-
this.undoLimit = undoLimit;
|
|
7
|
-
this.undoList = [];
|
|
8
|
-
this.redoList = [];
|
|
9
|
-
this.current = null;
|
|
10
|
-
this.debug = debug;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Get the limit of undo/redo actions
|
|
15
|
-
*
|
|
16
|
-
* @returns {number|*} the undo limit, as it is configured when constructing the history instance
|
|
17
|
-
*/
|
|
18
|
-
getUndoLimit() {
|
|
19
|
-
return this.undoLimit;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Get Current state
|
|
24
|
-
*
|
|
25
|
-
* @returns {null|*}
|
|
26
|
-
*/
|
|
27
|
-
getCurrent() {
|
|
28
|
-
return this.current;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Keep an object to history
|
|
33
|
-
*
|
|
34
|
-
* This method will set the object as current value and will push the previous "current" object to the undo history
|
|
35
|
-
*
|
|
36
|
-
* @param obj
|
|
37
|
-
*/
|
|
38
|
-
keep(obj) {
|
|
39
|
-
try {
|
|
40
|
-
if (
|
|
41
|
-
this.current &&
|
|
42
|
-
JSON.stringify(this.current) === JSON.stringify(obj)
|
|
43
|
-
) {
|
|
44
|
-
return; // Skip if no meaningful change
|
|
45
|
-
}
|
|
46
|
-
this.redoList = []; // Clear redo list on new action
|
|
47
|
-
if (this.current) {
|
|
48
|
-
this.undoList.push(this.current); // Store previous state in undo list
|
|
49
|
-
}
|
|
50
|
-
if (this.undoList.length > this.undoLimit) {
|
|
51
|
-
this.undoList.shift(); // Maintain limit on history size
|
|
52
|
-
}
|
|
53
|
-
this.current = obj; // Update current state
|
|
54
|
-
} finally {
|
|
55
|
-
this.print();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Undo the last object, this operation will set the current object to one step back in time
|
|
61
|
-
*
|
|
62
|
-
* @returns the new current value after the undo operation, else null if no undo operation was possible
|
|
63
|
-
*/
|
|
64
|
-
undo() {
|
|
65
|
-
try {
|
|
66
|
-
if (this.current) {
|
|
67
|
-
this.redoList.push(this.current);
|
|
68
|
-
if (this.redoList.length > this.undoLimit) {
|
|
69
|
-
this.redoList.shift();
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (this.undoList.length > 0) {
|
|
74
|
-
this.current = this.undoList.pop();
|
|
75
|
-
return this.current;
|
|
76
|
-
} else {
|
|
77
|
-
// If no more states left in undoList, set current to null (clear canvas)
|
|
78
|
-
this.current = null;
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
} finally {
|
|
82
|
-
this.print();
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Redo the last object, redo happens only if no keep operations have been performed
|
|
88
|
-
*
|
|
89
|
-
* @returns the new current value after the redo operation, or null if no redo operation was possible
|
|
90
|
-
*/
|
|
91
|
-
redo() {
|
|
92
|
-
try {
|
|
93
|
-
if (this.redoList.length > 0) {
|
|
94
|
-
if (this.current) this.undoList.push(this.current);
|
|
95
|
-
this.current = this.redoList.pop();
|
|
96
|
-
return this.current;
|
|
97
|
-
}
|
|
98
|
-
return null;
|
|
99
|
-
} finally {
|
|
100
|
-
this.print();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Checks whether we can perform a redo operation
|
|
106
|
-
*
|
|
107
|
-
* @returns {boolean}
|
|
108
|
-
*/
|
|
109
|
-
canRedo() {
|
|
110
|
-
return this.redoList.length > 0;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Checks whether we can perform an undo operation
|
|
115
|
-
*
|
|
116
|
-
* @returns {boolean}
|
|
117
|
-
*/
|
|
118
|
-
canUndo() {
|
|
119
|
-
return this.undoList.length > 0 || this.current !== null;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Clears the history maintained, can be undone
|
|
124
|
-
*/
|
|
125
|
-
clear() {
|
|
126
|
-
this.undoList = [];
|
|
127
|
-
this.redoList = [];
|
|
128
|
-
this.current = null;
|
|
129
|
-
this.print();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
print() {
|
|
133
|
-
if (this.debug) {
|
|
134
|
-
/* eslint-disable no-console */
|
|
135
|
-
console.log(
|
|
136
|
-
this.undoList,
|
|
137
|
-
' -> ' + this.current + ' <- ',
|
|
138
|
-
this.redoList.slice(0).reverse()
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export default History;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"canvasTypes": [
|
|
3
|
-
{
|
|
4
|
-
"id": "humanBody",
|
|
5
|
-
"label": "Human Body",
|
|
6
|
-
"url": "https://d16lktya8ojp5z.cloudfront.net/adelphi/images/body-diagram.png"
|
|
7
|
-
},
|
|
8
|
-
{
|
|
9
|
-
"id": "car",
|
|
10
|
-
"label": "Car",
|
|
11
|
-
"url": "https://d16lktya8ojp5z.cloudfront.net/adelphi/images/car-diagram.png"
|
|
12
|
-
}
|
|
13
|
-
]
|
|
14
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import FabricCanvasTool from './fabrictool';
|
|
2
|
-
import { Line as FabricLine } from 'fabric';
|
|
3
|
-
|
|
4
|
-
class Line extends FabricCanvasTool {
|
|
5
|
-
constructor(canvas) {
|
|
6
|
-
super(canvas);
|
|
7
|
-
// Define event handlers as arrow functions for consistent references
|
|
8
|
-
this.doMouseDown = (o) => this._doMouseDown(o);
|
|
9
|
-
this.doMouseMove = (o) => this._doMouseMove(o);
|
|
10
|
-
this.doMouseUp = () => this._doMouseUp();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
configureCanvas(props) {
|
|
14
|
-
const canvas = this._canvas;
|
|
15
|
-
canvas.isDrawingMode = false; // Disable drawing mode for custom drawing
|
|
16
|
-
canvas.selection = false;
|
|
17
|
-
this._width = props.lineWidth || 2;
|
|
18
|
-
this._color = props.lineColor || 'black';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
attachListeners() {
|
|
22
|
-
this._canvas.on('mouse:down', this.doMouseDown);
|
|
23
|
-
this._canvas.on('mouse:move', this.doMouseMove);
|
|
24
|
-
this._canvas.on('mouse:up', this.doMouseUp);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
detachListeners() {
|
|
28
|
-
this._canvas.off('mouse:down', this.doMouseDown);
|
|
29
|
-
this._canvas.off('mouse:move', this.doMouseMove);
|
|
30
|
-
this._canvas.off('mouse:up', this.doMouseUp);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
_doMouseDown(o) {
|
|
34
|
-
this.isDown = true;
|
|
35
|
-
const canvas = this._canvas;
|
|
36
|
-
const pointer = canvas.getPointer(o.e);
|
|
37
|
-
const points = [pointer.x, pointer.y, pointer.x, pointer.y];
|
|
38
|
-
|
|
39
|
-
this.line = new FabricLine(points, {
|
|
40
|
-
strokeWidth: this._width,
|
|
41
|
-
stroke: this._color,
|
|
42
|
-
originX: 'center',
|
|
43
|
-
originY: 'center',
|
|
44
|
-
selectable: false,
|
|
45
|
-
evented: false,
|
|
46
|
-
});
|
|
47
|
-
canvas.add(this.line);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
_doMouseMove(o) {
|
|
51
|
-
if (!this.isDown) return;
|
|
52
|
-
const canvas = this._canvas;
|
|
53
|
-
const pointer = canvas.getPointer(o.e);
|
|
54
|
-
this.line.set({ x2: pointer.x, y2: pointer.y });
|
|
55
|
-
this.line.setCoords();
|
|
56
|
-
canvas.renderAll();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
_doMouseUp() {
|
|
60
|
-
this.isDown = false;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export default Line;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import FabricCanvasTool from './fabrictool';
|
|
2
|
-
import * as fabric from 'fabric'; // v6
|
|
3
|
-
|
|
4
|
-
class Pan extends FabricCanvasTool {
|
|
5
|
-
configureCanvas(props) {
|
|
6
|
-
const canvas = this._canvas;
|
|
7
|
-
canvas.isDrawingMode = false;
|
|
8
|
-
canvas.selection = false;
|
|
9
|
-
canvas.forEachObject((o) => {
|
|
10
|
-
o.selectable = false;
|
|
11
|
-
o.evented = false;
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
// Change cursor to move
|
|
15
|
-
canvas.defaultCursor = 'move';
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
doMouseDown(o) {
|
|
19
|
-
const canvas = this._canvas;
|
|
20
|
-
this.isDown = true;
|
|
21
|
-
const pointer = canvas.getPointer(o.e);
|
|
22
|
-
this.startX = pointer.x;
|
|
23
|
-
this.startY = pointer.y;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
doMouseMove(o) {
|
|
27
|
-
if (!this.isDown) return;
|
|
28
|
-
const canvas = this._canvas;
|
|
29
|
-
const pointer = canvas.getPointer(o.e);
|
|
30
|
-
|
|
31
|
-
// Pan the canvas based on pointer movement
|
|
32
|
-
canvas.relativePan({
|
|
33
|
-
x: pointer.x - this.startX,
|
|
34
|
-
y: pointer.y - this.startY,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
// Update the initial positions for consistent panning
|
|
38
|
-
this.startX = pointer.x;
|
|
39
|
-
this.startY = pointer.y;
|
|
40
|
-
canvas.requestRenderAll();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
doMouseUp() {
|
|
44
|
-
this.isDown = false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default Pan;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import FabricCanvasTool from './fabrictool';
|
|
2
|
-
import * as fabric from 'fabric'; // v6
|
|
3
|
-
|
|
4
|
-
class Pencil extends FabricCanvasTool {
|
|
5
|
-
configureCanvas(props) {
|
|
6
|
-
const canvas = this._canvas;
|
|
7
|
-
|
|
8
|
-
// Enable drawing mode for the pencil tool
|
|
9
|
-
canvas.isDrawingMode = true;
|
|
10
|
-
|
|
11
|
-
// Initialize the freeDrawingBrush if not already set
|
|
12
|
-
if (!canvas.freeDrawingBrush) {
|
|
13
|
-
canvas.freeDrawingBrush = new fabric.PencilBrush(canvas);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Set brush properties
|
|
17
|
-
canvas.freeDrawingBrush.width = props.lineWidth || 1;
|
|
18
|
-
canvas.freeDrawingBrush.color = props.lineColor || 'black';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
attachListeners() {
|
|
22
|
-
const canvas = this._canvas;
|
|
23
|
-
|
|
24
|
-
// Set the canvas to drawing mode whenever Pencil is active
|
|
25
|
-
canvas.isDrawingMode = true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
detachListeners() {
|
|
29
|
-
const canvas = this._canvas;
|
|
30
|
-
|
|
31
|
-
// Disable drawing mode when switching away from the Pencil tool
|
|
32
|
-
canvas.isDrawingMode = false;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export default Pencil;
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { Rect, Textbox } from 'fabric';
|
|
2
|
-
|
|
3
|
-
class RectangleLabelObject {
|
|
4
|
-
constructor(canvas, text = 'Label', rectProps = {}, textProps = {}) {
|
|
5
|
-
this._canvas = canvas;
|
|
6
|
-
this._text = text;
|
|
7
|
-
|
|
8
|
-
// Ensure all essential properties are set for Rect and Textbox objects
|
|
9
|
-
const defaultRectProps = {
|
|
10
|
-
left: 10,
|
|
11
|
-
top: 10,
|
|
12
|
-
fill: 'transparent',
|
|
13
|
-
strokeWidth: 1,
|
|
14
|
-
width: 100,
|
|
15
|
-
height: 50,
|
|
16
|
-
selectable: false,
|
|
17
|
-
evented: false,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const defaultTextProps = {
|
|
21
|
-
left: 10,
|
|
22
|
-
top: 0,
|
|
23
|
-
fontSize: 16,
|
|
24
|
-
fill: 'black',
|
|
25
|
-
width: 100,
|
|
26
|
-
height: 30,
|
|
27
|
-
selectable: false,
|
|
28
|
-
evented: false,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Merge default properties with passed properties
|
|
32
|
-
this._rectObj = new Rect({ ...defaultRectProps, ...rectProps });
|
|
33
|
-
this._textObj = new Textbox(text, {
|
|
34
|
-
...defaultTextProps,
|
|
35
|
-
...textProps,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// Trigger dimension calculations for the Textbox object
|
|
39
|
-
this._textObj.initDimensions();
|
|
40
|
-
|
|
41
|
-
// Attach event listeners for updating the label position
|
|
42
|
-
canvas.on('object:scaling', this.update);
|
|
43
|
-
canvas.on('object:moving', this.update);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
update = (e) => {
|
|
47
|
-
if (!this._textObj || !this._rectObj) return;
|
|
48
|
-
|
|
49
|
-
// Ensure text stays positioned above or inside the rectangle during scaling/moving
|
|
50
|
-
if (e.target === this._rectObj) {
|
|
51
|
-
this._textObj.set({
|
|
52
|
-
left: this._rectObj.left,
|
|
53
|
-
top: this._rectObj.top - this._textObj.getScaledHeight(),
|
|
54
|
-
width: this._rectObj.getScaledWidth(),
|
|
55
|
-
scaleX: 1,
|
|
56
|
-
scaleY: 1,
|
|
57
|
-
});
|
|
58
|
-
this._textObj.initDimensions(); // Force re-calculation if needed
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
setText(text) {
|
|
63
|
-
this._text = text;
|
|
64
|
-
this._textObj.set({ text });
|
|
65
|
-
this._textObj.initDimensions(); // Recalculate dimensions for new text
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export default RectangleLabelObject;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import FabricCanvasTool from './fabrictool';
|
|
2
|
-
import RectangleLabelObject from './rectangle-label-object';
|
|
3
|
-
|
|
4
|
-
class RectangleLabel extends FabricCanvasTool {
|
|
5
|
-
configureCanvas(props) {
|
|
6
|
-
const canvas = this._canvas;
|
|
7
|
-
canvas.isDrawingMode = false;
|
|
8
|
-
canvas.selection = false;
|
|
9
|
-
canvas.forEachObject((o) => {
|
|
10
|
-
o.selectable = false;
|
|
11
|
-
o.evented = false;
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
// Tool properties
|
|
15
|
-
this._width = props.lineWidth || 1;
|
|
16
|
-
this._color = props.lineColor || 'black';
|
|
17
|
-
this._fill = props.fillColor || 'transparent';
|
|
18
|
-
this._textString = props.text || '';
|
|
19
|
-
this._maxFontSize = 12;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
doMouseDown(o) {
|
|
23
|
-
const canvas = this._canvas;
|
|
24
|
-
this.isDown = true;
|
|
25
|
-
const pointer = canvas.getPointer(o.e);
|
|
26
|
-
this.startX = pointer.x;
|
|
27
|
-
this.startY = pointer.y;
|
|
28
|
-
|
|
29
|
-
// Create a labeled rectangle
|
|
30
|
-
this.rectangleLabel = new RectangleLabelObject(
|
|
31
|
-
canvas,
|
|
32
|
-
'New drawing',
|
|
33
|
-
{
|
|
34
|
-
left: this.startX,
|
|
35
|
-
top: this.startY,
|
|
36
|
-
originX: 'left',
|
|
37
|
-
originY: 'top',
|
|
38
|
-
stroke: this._color,
|
|
39
|
-
strokeWidth: this._width,
|
|
40
|
-
fill: this._fill,
|
|
41
|
-
selectable: false,
|
|
42
|
-
evented: false,
|
|
43
|
-
strokeUniform: true,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
left: this.startX,
|
|
47
|
-
top: this.startY - 12,
|
|
48
|
-
fontSize: this._maxFontSize,
|
|
49
|
-
backgroundColor: this._color,
|
|
50
|
-
selectable: false,
|
|
51
|
-
evented: false,
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
this._objects = this._objects
|
|
56
|
-
? [...this._objects, this.rectangleLabel]
|
|
57
|
-
: [this.rectangleLabel];
|
|
58
|
-
|
|
59
|
-
canvas.add(this.rectangleLabel._rectObj);
|
|
60
|
-
canvas.add(this.rectangleLabel._textObj);
|
|
61
|
-
canvas.renderAll();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
doMouseMove(o) {
|
|
65
|
-
if (!this.isDown) return;
|
|
66
|
-
const canvas = this._canvas;
|
|
67
|
-
const pointer = canvas.getPointer(o.e);
|
|
68
|
-
|
|
69
|
-
// Update rectangle and text positions
|
|
70
|
-
this.rectangleLabel._rectObj.set({
|
|
71
|
-
left: Math.min(this.startX, pointer.x),
|
|
72
|
-
top: Math.min(this.startY, pointer.y),
|
|
73
|
-
width: Math.abs(this.startX - pointer.x),
|
|
74
|
-
height: Math.abs(this.startY - pointer.y),
|
|
75
|
-
});
|
|
76
|
-
this.rectangleLabel._textObj.set({
|
|
77
|
-
left: this.rectangleLabel._rectObj.left,
|
|
78
|
-
top: this.rectangleLabel._rectObj.top - this._maxFontSize,
|
|
79
|
-
width: this.rectangleLabel._rectObj.getScaledWidth(),
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
this.rectangleLabel._rectObj.setCoords();
|
|
83
|
-
this.rectangleLabel._textObj.setCoords();
|
|
84
|
-
canvas.renderAll();
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
doMouseUp() {
|
|
88
|
-
this.isDown = false;
|
|
89
|
-
this._canvas.renderAll();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export default RectangleLabel;
|