customized-fabric 2.0.21 → 2.0.22
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.
@@ -5,8 +5,8 @@ const fabric_1 = require("fabric");
|
|
5
5
|
const constants_1 = require("./constants");
|
6
6
|
const utils_1 = require("../utils");
|
7
7
|
const objectId_1 = require("../utils/objectId");
|
8
|
-
const svg_util_1 = require("../utils/svg.util");
|
9
8
|
const common_util_1 = require("../utils/common.util");
|
9
|
+
const utils_2 = require("./utils");
|
10
10
|
const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group, {
|
11
11
|
initialize: function (options) {
|
12
12
|
let { text, ...rest } = options ?? {};
|
@@ -33,10 +33,21 @@ const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group,
|
|
33
33
|
positionAngle: 0,
|
34
34
|
maxFontSize: 200,
|
35
35
|
strokeLineJoin: "round",
|
36
|
+
startAngle: 45,
|
37
|
+
endAngle: 135,
|
36
38
|
...text,
|
37
39
|
text: isAllCapital ? fullText.toUpperCase() : fullText,
|
38
40
|
});
|
39
|
-
|
41
|
+
this.ellipseObject = new fabric_1.fabric.Ellipse({
|
42
|
+
stroke: "black",
|
43
|
+
strokeDashArray: [10, 10],
|
44
|
+
fill: "transparent",
|
45
|
+
});
|
46
|
+
const group = new fabric_1.fabric.Group([
|
47
|
+
this.rectObject,
|
48
|
+
this.ellipseObject,
|
49
|
+
this.textObject,
|
50
|
+
]);
|
40
51
|
this.set({
|
41
52
|
...group,
|
42
53
|
_id: new objectId_1.ObjectId().toString(),
|
@@ -71,44 +82,47 @@ const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group,
|
|
71
82
|
}
|
72
83
|
this.set(attributes);
|
73
84
|
this.rectObject.set(attributes);
|
74
|
-
this.calculateTextPath(
|
85
|
+
this.calculateTextPath();
|
75
86
|
this.autoChangeFontSize(0.1);
|
87
|
+
this.updateEllipsePath();
|
76
88
|
this.canvas?.renderAll?.();
|
77
89
|
});
|
78
90
|
if (options?.isOriginal) {
|
79
|
-
this.rectObject?.set({
|
91
|
+
this.rectObject?.set({ visible: false });
|
92
|
+
this.ellipseObject.set({ visible: false });
|
80
93
|
}
|
81
94
|
else {
|
82
95
|
if (options?.hideStroke) {
|
83
|
-
this.rectObject?.set({
|
96
|
+
this.rectObject?.set({ visible: false });
|
97
|
+
this.ellipseObject.set({ visible: false });
|
84
98
|
}
|
85
99
|
this.setFontFamily(text?.fontFamily ?? "", options?.fontUrl);
|
86
100
|
}
|
87
101
|
this.fire("scaling");
|
88
102
|
},
|
89
|
-
autoChangeFontSize: function (
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
let
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
this.
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
}
|
109
|
-
this.canvas?.renderAll?.();
|
110
|
-
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
103
|
+
autoChangeFontSize: function (deltaFontSize = 0.1) {
|
104
|
+
const textPath = this.textObject.path;
|
105
|
+
if (!textPath)
|
106
|
+
return;
|
107
|
+
const pathLength = textPath.segmentsInfo?.at(-1)?.length || 0;
|
108
|
+
let low = 0;
|
109
|
+
let high = this.textObject.maxFontSize;
|
110
|
+
let bestFit = this.textObject.fontSize;
|
111
|
+
while (high - low > deltaFontSize) {
|
112
|
+
const mid = (low + high) / 2;
|
113
|
+
this.textObject.set({ fontSize: mid });
|
114
|
+
this.canvas?.renderAll();
|
115
|
+
const textWidth = Math.max(...this.textObject.__lineWidths);
|
116
|
+
if (textWidth <= pathLength) {
|
117
|
+
bestFit = mid;
|
118
|
+
low = mid;
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
high = mid;
|
122
|
+
}
|
111
123
|
}
|
124
|
+
this.textObject.set({ fontSize: bestFit });
|
125
|
+
this.canvas?.renderAll();
|
112
126
|
},
|
113
127
|
setText: function (text) {
|
114
128
|
this.textObject.set({
|
@@ -176,30 +190,34 @@ const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group,
|
|
176
190
|
}
|
177
191
|
return this.textObject.get(attribute);
|
178
192
|
},
|
179
|
-
calculateTextPath: function (
|
180
|
-
|
181
|
-
|
182
|
-
const
|
183
|
-
const
|
184
|
-
const
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
193
|
+
calculateTextPath: function () {
|
194
|
+
const { width: layerWidth, height: layerHeight } = this;
|
195
|
+
const rx = layerWidth / 2;
|
196
|
+
const ry = layerHeight / 2;
|
197
|
+
const { startAngle, endAngle, pathSide } = this.textObject;
|
198
|
+
const pathString = (0, utils_2.ellipseArcPath)(rx, ry, startAngle, endAngle, pathSide === "left" ? false : true);
|
199
|
+
this.textObject.set({
|
200
|
+
path: new fabric_1.fabric.Path(pathString, {
|
201
|
+
stroke: "red",
|
202
|
+
strokeWidth: 4,
|
203
|
+
fill: "transparent",
|
204
|
+
visible: this.pathVisible,
|
205
|
+
}),
|
192
206
|
});
|
193
|
-
this.
|
194
|
-
|
195
|
-
|
196
|
-
const
|
207
|
+
this.canvas?.renderAll();
|
208
|
+
},
|
209
|
+
updateEllipsePath() {
|
210
|
+
const { width: layerWidth, height: layerHeight } = this;
|
211
|
+
const rx = layerWidth / 2;
|
212
|
+
const ry = layerHeight / 2;
|
213
|
+
const { startAngle, endAngle, pathSide } = this.textObject;
|
214
|
+
const { x, y } = (0, utils_2.getEllipseArcCenterPoint)(rx, ry, startAngle, endAngle);
|
197
215
|
this.textObject.set({
|
198
|
-
|
199
|
-
|
200
|
-
pathStartOffset,
|
216
|
+
left: pathSide === "left" ? x : -x,
|
217
|
+
top: pathSide === "left" ? y : -y,
|
201
218
|
});
|
202
|
-
this
|
219
|
+
this.ellipseObject.set({ rx, ry, top: -ry, left: -rx });
|
220
|
+
this.canvas?.requestRenderAll();
|
203
221
|
},
|
204
222
|
});
|
205
223
|
const toCurvedTextObject = (object) => {
|
@@ -236,6 +254,8 @@ const toCurvedTextObject = (object) => {
|
|
236
254
|
pathSide: textObject?.pathSide,
|
237
255
|
positionAngle: textObject?.positionAngle,
|
238
256
|
isAllCapital: textObject?.isAllCapital,
|
257
|
+
startAngle: textObject?.startAngle,
|
258
|
+
endAngle: textObject?.endAngle,
|
239
259
|
},
|
240
260
|
};
|
241
261
|
};
|
@@ -0,0 +1,54 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getEllipseArcCenterPoint = exports.ellipseArcPath = void 0;
|
4
|
+
const degreeToRad = (deg) => (deg * Math.PI) / 180;
|
5
|
+
const ellipseArcPath = (rx, ry, startAngle, endAngle, flip = false) => {
|
6
|
+
if (flip) {
|
7
|
+
startAngle = (startAngle + 180) % 360;
|
8
|
+
endAngle = (endAngle + 180) % 360;
|
9
|
+
}
|
10
|
+
const x1 = -rx * Math.cos(degreeToRad(startAngle));
|
11
|
+
const y1 = ry * Math.sin(degreeToRad(startAngle));
|
12
|
+
const x2 = -rx * Math.cos(degreeToRad(endAngle));
|
13
|
+
const y2 = ry * Math.sin(degreeToRad(endAngle));
|
14
|
+
const angleDiff = (endAngle - startAngle + 360) % 360;
|
15
|
+
const largeArcFlag = angleDiff > 180 ? 1 : 0;
|
16
|
+
const sweepFlag = 1;
|
17
|
+
return `M ${x1} ${y1} A ${rx} ${ry} 0 ${largeArcFlag} ${sweepFlag} ${x2} ${y2}`;
|
18
|
+
};
|
19
|
+
exports.ellipseArcPath = ellipseArcPath;
|
20
|
+
const twoPi = 2 * Math.PI;
|
21
|
+
const normalize = (angle) => ((angle % twoPi) + twoPi) % twoPi;
|
22
|
+
function isAngleInArc(theta, a, b) {
|
23
|
+
theta = normalize(theta);
|
24
|
+
a = normalize(a);
|
25
|
+
b = normalize(b);
|
26
|
+
if (a < b)
|
27
|
+
return a <= theta && theta <= b;
|
28
|
+
return a <= theta || theta <= b;
|
29
|
+
}
|
30
|
+
const getEllipseArcCenterPoint = (rx, ry, a, b) => {
|
31
|
+
a = degreeToRad(a);
|
32
|
+
b = degreeToRad(b);
|
33
|
+
const criticalAngles = [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2];
|
34
|
+
const points = [
|
35
|
+
[rx * Math.cos(a), -ry * Math.sin(a)],
|
36
|
+
[rx * Math.cos(b), -ry * Math.sin(b)],
|
37
|
+
];
|
38
|
+
for (const theta of criticalAngles) {
|
39
|
+
if (isAngleInArc(theta, a, b)) {
|
40
|
+
points.push([rx * Math.cos(theta), -ry * Math.sin(theta)]);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
const xs = points.map((p) => p[0]);
|
44
|
+
const ys = points.map((p) => p[1]);
|
45
|
+
const minX = Math.min(...xs);
|
46
|
+
const maxX = Math.max(...xs);
|
47
|
+
const minY = Math.min(...ys);
|
48
|
+
const maxY = Math.max(...ys);
|
49
|
+
return {
|
50
|
+
x: (minX + maxX) / 2,
|
51
|
+
y: (minY + maxY) / 2,
|
52
|
+
};
|
53
|
+
};
|
54
|
+
exports.getEllipseArcCenterPoint = getEllipseArcCenterPoint;
|