customized-fabric 2.0.9 → 2.0.11
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/lib/CurvedTextObject/index.js +13 -12
- package/lib/ImagePlaceholderObject/index.d.ts +1 -1
- package/lib/ImagePlaceholderObject/index.js +22 -15
- package/lib/ImagePlaceholderObject/interfaces.d.ts +5 -1
- package/lib/constants.d.ts +0 -1
- package/lib/constants.js +0 -2
- package/lib/index.d.ts +2 -3
- package/lib/index.js +4 -22
- package/lib/utils/common.util.d.ts +9 -0
- package/lib/utils/common.util.js +28 -1
- package/lib/utils/index.d.ts +2 -1
- package/lib/utils/index.js +7 -3
- package/lib/utils/svg.util.d.ts +2 -5
- package/lib/utils/svg.util.js +11 -32
- package/package.json +2 -2
- package/lib/AdvancedText/constants.d.ts +0 -11
- package/lib/AdvancedText/constants.js +0 -14
- package/lib/AdvancedText/index.d.ts +0 -5
- package/lib/AdvancedText/index.js +0 -198
- package/lib/AdvancedText/interfaces.d.ts +0 -29
- package/lib/AdvancedText/interfaces.js +0 -2
@@ -73,26 +73,25 @@ const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group,
|
|
73
73
|
this.fire("scaling");
|
74
74
|
},
|
75
75
|
autoChangeFontSize: function (changeSpeed = 0.1) {
|
76
|
-
let { fontSize, lengthRatio, maxFontSize
|
76
|
+
let { fontSize, lengthRatio, maxFontSize } = this.textObject;
|
77
77
|
fontSize = Number(fontSize || 0);
|
78
78
|
lengthRatio = Number(lengthRatio || 0.4);
|
79
79
|
maxFontSize = Number(maxFontSize || 200);
|
80
|
-
const length =
|
80
|
+
const length = (0, svg_util_1.getEllipseCircumference)(this.width / 2, this.height / 2) * lengthRatio;
|
81
81
|
let maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
82
|
-
const ratio = length / maxLineWidth;
|
83
|
-
fontSize = Math.min(maxFontSize, fontSize * ratio);
|
84
|
-
this.textObject.set({ fontSize });
|
85
|
-
this.canvas?.renderAll?.();
|
86
|
-
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
87
82
|
while (length <= maxLineWidth) {
|
88
83
|
fontSize -= changeSpeed;
|
89
|
-
this.textObject.set({
|
84
|
+
this.textObject.set({
|
85
|
+
fontSize,
|
86
|
+
});
|
90
87
|
this.canvas?.renderAll?.();
|
91
88
|
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
92
89
|
}
|
93
90
|
while (maxFontSize > fontSize.toFixed(1) && length > maxLineWidth) {
|
94
91
|
fontSize += changeSpeed;
|
95
|
-
this.textObject.set({
|
92
|
+
this.textObject.set({
|
93
|
+
fontSize,
|
94
|
+
});
|
96
95
|
this.canvas?.renderAll?.();
|
97
96
|
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
98
97
|
}
|
@@ -166,7 +165,10 @@ const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group,
|
|
166
165
|
calculateTextPath: function (width, height) {
|
167
166
|
let { pathSide, positionAngle } = this.textObject;
|
168
167
|
positionAngle = Number(positionAngle || 0);
|
169
|
-
const
|
168
|
+
const textHeight = 0;
|
169
|
+
const rx = (width - textHeight) / 2;
|
170
|
+
const ry = (height - textHeight) / 2;
|
171
|
+
const path = new fabric_1.fabric.Path((0, svg_util_1.getEllipsePath)(rx, ry, pathSide), {
|
170
172
|
fill: undefined,
|
171
173
|
stroke: "black",
|
172
174
|
objectCaching: false,
|
@@ -176,13 +178,12 @@ const CurvedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group,
|
|
176
178
|
});
|
177
179
|
this.pathObject = path;
|
178
180
|
const pathInfo = fabric_1.fabric.util?.getPathSegmentsInfo?.(path.path);
|
179
|
-
const pathLength = pathInfo
|
181
|
+
const pathLength = pathInfo?.[(pathInfo?.length ?? 0) - 1]?.length;
|
180
182
|
const pathStartOffset = ((positionAngle % 360) * pathLength) / 360;
|
181
183
|
this.textObject.set({
|
182
184
|
path,
|
183
185
|
pathLength,
|
184
186
|
pathStartOffset,
|
185
|
-
angle: (pathSide == "left" ? 0 : 1) * 180,
|
186
187
|
});
|
187
188
|
this?.canvas?.renderAll();
|
188
189
|
},
|
@@ -50,7 +50,7 @@ export default class ImagePlaceholder extends fabric.Group {
|
|
50
50
|
removeUploadedImage?: () => void;
|
51
51
|
loadMask?: (maskInput: File | string) => void;
|
52
52
|
removeMask?: () => void;
|
53
|
-
|
53
|
+
loadCustomImage?: (image: IImageOptions) => Promise<void>;
|
54
54
|
setImageType?: (type: ImageFilterType) => void;
|
55
55
|
setImageColor?: (color: string) => void;
|
56
56
|
applyImageFilters?: (image: fabric.Image | undefined) => void;
|
@@ -153,17 +153,23 @@ const ImagePlaceholderClass = fabric_1.fabric.util.createClass(fabric_1.fabric.G
|
|
153
153
|
},
|
154
154
|
toImageObject: function () {
|
155
155
|
if (this.uploadedImage) {
|
156
|
-
const { originX, originY, left = 0, top = 0, width, height, scaleX, scaleY, angle = 0, flipX, flipY, skewX, skewY, opacity, } = this.uploadedImage;
|
156
|
+
const { originX, originY, left = 0, top = 0, width = 0, height = 0, scaleX = 0, scaleY = 0, angle = 0, flipX, flipY, skewX, skewY, opacity, } = this.uploadedImage;
|
157
|
+
const { relativeLeft, relativeTop } = (0, utils_1.getRelativePosition)(this.uploadedImage, this);
|
157
158
|
return {
|
159
|
+
relativeLeftRatio: relativeLeft / this.width,
|
160
|
+
relativeTopRatio: relativeTop / this.height,
|
161
|
+
relativeScaleX: (width * scaleX) / this.width,
|
162
|
+
relativeScaleY: (height * scaleY) / this.height,
|
163
|
+
relativeAngle: angle - this.angle,
|
158
164
|
originX,
|
159
165
|
originY,
|
160
|
-
left
|
161
|
-
top
|
166
|
+
left,
|
167
|
+
top,
|
162
168
|
width,
|
163
169
|
height,
|
164
170
|
scaleX,
|
165
171
|
scaleY,
|
166
|
-
angle
|
172
|
+
angle,
|
167
173
|
flipX,
|
168
174
|
flipY,
|
169
175
|
skewX,
|
@@ -174,6 +180,7 @@ const ImagePlaceholderClass = fabric_1.fabric.util.createClass(fabric_1.fabric.G
|
|
174
180
|
color: this?.imageColor,
|
175
181
|
removeBackground: this?.removeBackground,
|
176
182
|
faceCutout: this?.faceCutout,
|
183
|
+
advancedFilter: this?.advancedFilter,
|
177
184
|
},
|
178
185
|
};
|
179
186
|
}
|
@@ -242,23 +249,23 @@ const ImagePlaceholderClass = fabric_1.fabric.util.createClass(fabric_1.fabric.G
|
|
242
249
|
return mask;
|
243
250
|
}
|
244
251
|
},
|
245
|
-
|
252
|
+
loadCustomImage: async function (image) {
|
246
253
|
if (image) {
|
247
|
-
const { url, filteredUrl, data
|
254
|
+
const { url, filteredUrl, data } = image;
|
248
255
|
const imageUrl = filteredUrl ?? url;
|
249
|
-
if (imageUrl && data
|
256
|
+
if (imageUrl && data) {
|
250
257
|
const loadedImage = await (0, utils_1.loadImageFromUrl)(imageUrl);
|
251
258
|
if (loadedImage) {
|
252
259
|
const mask = await this.getMask();
|
253
|
-
const {
|
260
|
+
const { relativeLeftRatio, relativeTopRatio, relativeScaleX, relativeScaleY, relativeAngle, width, height, flipX, flipY, settings = {}, } = data;
|
254
261
|
const { color, type } = settings;
|
255
|
-
const
|
256
|
-
const ratioPosition = this.width / clipPath.width;
|
257
|
-
loadedImage.scaleToWidth(ratioWidth * this.width);
|
262
|
+
const { absoluteLeft, absoluteRight } = (0, utils_1.getAbsolutePosition)(relativeLeftRatio, relativeTopRatio, this);
|
258
263
|
loadedImage.set({
|
259
|
-
|
260
|
-
|
261
|
-
|
264
|
+
left: absoluteLeft,
|
265
|
+
top: absoluteRight,
|
266
|
+
scaleX: (relativeScaleX * this.width) / width,
|
267
|
+
scaleY: (relativeScaleY * this.height) / height,
|
268
|
+
angle: this.angle + relativeAngle,
|
262
269
|
originX: "center",
|
263
270
|
originY: "center",
|
264
271
|
flipX,
|
@@ -287,7 +294,7 @@ const ImagePlaceholderClass = fabric_1.fabric.util.createClass(fabric_1.fabric.G
|
|
287
294
|
const imageFilters = this.imageFilters ?? [];
|
288
295
|
image.filters = imageFilters;
|
289
296
|
image.applyFilters();
|
290
|
-
this.canvas
|
297
|
+
this.canvas?.renderAll();
|
291
298
|
}
|
292
299
|
},
|
293
300
|
});
|
@@ -22,6 +22,11 @@ export interface IImageOptions {
|
|
22
22
|
data: {
|
23
23
|
originX: string;
|
24
24
|
originY: string;
|
25
|
+
relativeLeftRatio: number;
|
26
|
+
relativeTopRatio: number;
|
27
|
+
relativeScaleX: number;
|
28
|
+
relativeScaleY: number;
|
29
|
+
relativeAngle: number;
|
25
30
|
left: number;
|
26
31
|
top: number;
|
27
32
|
width: number;
|
@@ -39,7 +44,6 @@ export interface IImageOptions {
|
|
39
44
|
type?: ImageFilterType;
|
40
45
|
};
|
41
46
|
};
|
42
|
-
clipPath: IClipPathOptions;
|
43
47
|
}
|
44
48
|
export interface IImagePlaceholderOptions extends fabric.IGroupOptions {
|
45
49
|
_id?: ObjectId;
|
package/lib/constants.d.ts
CHANGED
package/lib/constants.js
CHANGED
@@ -8,7 +8,6 @@ const constants_4 = require("./ImagePlaceholderObject/constants");
|
|
8
8
|
const constants_5 = require("./LayoutGroupObject/constants");
|
9
9
|
const constants_6 = require("./QRCodeObject/constants");
|
10
10
|
const constants_7 = require("./TextInputObject/constants");
|
11
|
-
const constants_8 = require("./AdvancedText/constants");
|
12
11
|
exports.OBJECT_TYPES = {
|
13
12
|
textInput: constants_7.TEXT_INPUT_OBJECT_ATTRIBUTES.type,
|
14
13
|
curvedText: constants_3.CURVED_TEXT_OBJECT_ATTRIBUTES.type,
|
@@ -18,6 +17,5 @@ exports.OBJECT_TYPES = {
|
|
18
17
|
layoutGroup: constants_5.LAYOUT_GROUP_OBJECT_ATTRIBUTES.type,
|
19
18
|
calendar: constants_1.CALENDAR_OBJECT_ATTRIBUTES.type,
|
20
19
|
qrCode: constants_6.QR_CODE_OBJECT_ATTRIBUTES.type,
|
21
|
-
advancedText: constants_8.ADVANCED_TEXT_OBJECT_ATTRIBUTES.type,
|
22
20
|
};
|
23
21
|
exports.MAX_TEXTURE_SIZE = 20000;
|
package/lib/index.d.ts
CHANGED
@@ -5,9 +5,8 @@ import ImagePlaceholder from "./ImagePlaceholderObject";
|
|
5
5
|
import LayoutGroup from "./LayoutGroupObject";
|
6
6
|
import Calendar from "./CalendarObject";
|
7
7
|
import QRCode from "./QRCodeObject";
|
8
|
-
import AdvancedText from "./AdvancedText";
|
9
|
-
import fabric, { lockObject, lockAllObjects, loadImageFromFile, loadImageFromUrl, getObject, asyncGetObject } from "./utils";
|
10
8
|
import { OBJECT_TYPES } from "./constants";
|
11
9
|
import { IMAGE_FILTER_TYPES } from "./ImagePlaceholderObject/constants";
|
12
10
|
import { IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES } from "./ImagePlaceholderObject/constants";
|
13
|
-
export
|
11
|
+
export * from "./utils";
|
12
|
+
export { TextInput, Clipart, ImagePlaceholder, LayoutGroup, CurvedText, Calendar, QRCode, OBJECT_TYPES, IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES, IMAGE_FILTER_TYPES, };
|
package/lib/index.js
CHANGED
@@ -10,23 +10,14 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
10
10
|
if (k2 === undefined) k2 = k;
|
11
11
|
o[k2] = m[k];
|
12
12
|
}));
|
13
|
-
var
|
14
|
-
|
15
|
-
}) : function(o, v) {
|
16
|
-
o["default"] = v;
|
17
|
-
});
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
-
if (mod && mod.__esModule) return mod;
|
20
|
-
var result = {};
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
-
__setModuleDefault(result, mod);
|
23
|
-
return result;
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
24
15
|
};
|
25
16
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
26
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
18
|
};
|
28
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
-
exports.IMAGE_FILTER_TYPES = exports.IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES = exports.OBJECT_TYPES = exports.
|
20
|
+
exports.IMAGE_FILTER_TYPES = exports.IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES = exports.OBJECT_TYPES = exports.QRCode = exports.Calendar = exports.CurvedText = exports.LayoutGroup = exports.ImagePlaceholder = exports.Clipart = exports.TextInput = void 0;
|
30
21
|
const TextInputObject_1 = __importDefault(require("./TextInputObject"));
|
31
22
|
exports.TextInput = TextInputObject_1.default;
|
32
23
|
const CurvedTextObject_1 = __importDefault(require("./CurvedTextObject"));
|
@@ -41,19 +32,10 @@ const CalendarObject_1 = __importDefault(require("./CalendarObject"));
|
|
41
32
|
exports.Calendar = CalendarObject_1.default;
|
42
33
|
const QRCodeObject_1 = __importDefault(require("./QRCodeObject"));
|
43
34
|
exports.QRCode = QRCodeObject_1.default;
|
44
|
-
const AdvancedText_1 = __importDefault(require("./AdvancedText"));
|
45
|
-
exports.AdvancedText = AdvancedText_1.default;
|
46
|
-
const utils_1 = __importStar(require("./utils"));
|
47
|
-
exports.fabric = utils_1.default;
|
48
|
-
Object.defineProperty(exports, "lockObject", { enumerable: true, get: function () { return utils_1.lockObject; } });
|
49
|
-
Object.defineProperty(exports, "lockAllObjects", { enumerable: true, get: function () { return utils_1.lockAllObjects; } });
|
50
|
-
Object.defineProperty(exports, "loadImageFromFile", { enumerable: true, get: function () { return utils_1.loadImageFromFile; } });
|
51
|
-
Object.defineProperty(exports, "loadImageFromUrl", { enumerable: true, get: function () { return utils_1.loadImageFromUrl; } });
|
52
|
-
Object.defineProperty(exports, "getObject", { enumerable: true, get: function () { return utils_1.getObject; } });
|
53
|
-
Object.defineProperty(exports, "asyncGetObject", { enumerable: true, get: function () { return utils_1.asyncGetObject; } });
|
54
35
|
const constants_1 = require("./constants");
|
55
36
|
Object.defineProperty(exports, "OBJECT_TYPES", { enumerable: true, get: function () { return constants_1.OBJECT_TYPES; } });
|
56
37
|
const constants_2 = require("./ImagePlaceholderObject/constants");
|
57
38
|
Object.defineProperty(exports, "IMAGE_FILTER_TYPES", { enumerable: true, get: function () { return constants_2.IMAGE_FILTER_TYPES; } });
|
58
39
|
const constants_3 = require("./ImagePlaceholderObject/constants");
|
59
40
|
Object.defineProperty(exports, "IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES", { enumerable: true, get: function () { return constants_3.IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES; } });
|
41
|
+
__exportStar(require("./utils"), exports);
|
@@ -1 +1,10 @@
|
|
1
|
+
import { fabric } from "fabric";
|
1
2
|
export declare const removeValueKeys: (object: any, value?: any) => any;
|
3
|
+
export declare const getRelativePosition: (relativeObject: fabric.Object, objectToRelate: fabric.Object) => {
|
4
|
+
relativeLeft: number;
|
5
|
+
relativeTop: number;
|
6
|
+
};
|
7
|
+
export declare const getAbsolutePosition: (relativeLeftRatio: number, relativeTopRatio: number, objectToApply: any) => {
|
8
|
+
absoluteLeft: number;
|
9
|
+
absoluteRight: any;
|
10
|
+
};
|
package/lib/utils/common.util.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.removeValueKeys = void 0;
|
3
|
+
exports.getAbsolutePosition = exports.getRelativePosition = exports.removeValueKeys = void 0;
|
4
|
+
const fabric_1 = require("fabric");
|
4
5
|
const removeValueKeys = (object, value = null) => {
|
5
6
|
const newObject = {};
|
6
7
|
for (const key in object) {
|
@@ -11,3 +12,29 @@ const removeValueKeys = (object, value = null) => {
|
|
11
12
|
return newObject;
|
12
13
|
};
|
13
14
|
exports.removeValueKeys = removeValueKeys;
|
15
|
+
const getRelativePosition = (relativeObject, objectToRelate) => {
|
16
|
+
const rLeft = relativeObject.left || 0;
|
17
|
+
const rTop = relativeObject.top || 0;
|
18
|
+
const oLeft = objectToRelate.left || 0;
|
19
|
+
const oTop = objectToRelate.top || 0;
|
20
|
+
const oAngle = fabric_1.fabric.util.degreesToRadians(objectToRelate.angle || 0);
|
21
|
+
const relativeLeft = Math.cos(-oAngle) * (rLeft - oLeft) - Math.sin(-oAngle) * (rTop - oTop);
|
22
|
+
const relativeTop = Math.sin(-oAngle) * (rLeft - oLeft) + Math.cos(-oAngle) * (rTop - oTop);
|
23
|
+
return { relativeLeft, relativeTop };
|
24
|
+
};
|
25
|
+
exports.getRelativePosition = getRelativePosition;
|
26
|
+
const getAbsolutePosition = (relativeLeftRatio, relativeTopRatio, objectToApply) => {
|
27
|
+
const targetX = objectToApply.left;
|
28
|
+
const targetY = objectToApply.top;
|
29
|
+
const targetAngle = fabric_1.fabric.util.degreesToRadians(objectToApply.angle);
|
30
|
+
const targetWidth = objectToApply.width;
|
31
|
+
const targetHeight = objectToApply.height;
|
32
|
+
const absoluteLeft = targetX +
|
33
|
+
Math.cos(targetAngle) * (relativeLeftRatio * targetWidth) -
|
34
|
+
Math.sin(targetAngle) * (relativeTopRatio * targetHeight);
|
35
|
+
const absoluteRight = targetY +
|
36
|
+
Math.sin(targetAngle) * (relativeLeftRatio * targetWidth) +
|
37
|
+
Math.cos(targetAngle) * (relativeTopRatio * targetHeight);
|
38
|
+
return { absoluteLeft, absoluteRight };
|
39
|
+
};
|
40
|
+
exports.getAbsolutePosition = getAbsolutePosition;
|
package/lib/utils/index.d.ts
CHANGED
@@ -24,4 +24,5 @@ export declare const getObject: (object: any, options?: {
|
|
24
24
|
export declare const asyncGetObject: (object: any, options?: {
|
25
25
|
isOriginal?: boolean;
|
26
26
|
}) => Promise<Clipart | ImagePlaceholder | CurvedText | Calendar | QRCode | TextInput | undefined>;
|
27
|
-
export
|
27
|
+
export { fabric };
|
28
|
+
export * from "./common.util";
|
package/lib/utils/index.js
CHANGED
@@ -22,9 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
22
|
__setModuleDefault(result, mod);
|
23
23
|
return result;
|
24
24
|
};
|
25
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
26
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
27
|
+
};
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
26
|
-
exports.asyncGetObject = exports.getObject = exports.lockAllObjects = exports.lockObject = exports.getImageFilters = exports.loadImage = exports.loadImageFromUrl = exports.loadImageFromFile = exports.isFontLoaded = exports.loadFontFromUrl = void 0;
|
29
|
+
exports.fabric = exports.asyncGetObject = exports.getObject = exports.lockAllObjects = exports.lockObject = exports.getImageFilters = exports.loadImage = exports.loadImageFromUrl = exports.loadImageFromFile = exports.isFontLoaded = exports.loadFontFromUrl = void 0;
|
27
30
|
const fabric_1 = require("fabric");
|
31
|
+
Object.defineProperty(exports, "fabric", { enumerable: true, get: function () { return fabric_1.fabric; } });
|
28
32
|
const constants_1 = require("../constants");
|
29
33
|
const ClipartObject_1 = __importStar(require("../ClipartObject"));
|
30
34
|
const ImagePlaceholderObject_1 = __importStar(require("../ImagePlaceholderObject"));
|
@@ -204,7 +208,7 @@ const asyncGetObject = async (object, options) => {
|
|
204
208
|
isOriginal: options?.isOriginal,
|
205
209
|
});
|
206
210
|
if (object?.image) {
|
207
|
-
const image = await imagePlaceHolderObject?.
|
211
|
+
const image = await imagePlaceHolderObject?.loadCustomImage?.(object?.image);
|
208
212
|
if (image) {
|
209
213
|
return image;
|
210
214
|
}
|
@@ -272,4 +276,4 @@ fabric_1.fabric.Object.prototype.toObject = (function (toObject) {
|
|
272
276
|
}
|
273
277
|
};
|
274
278
|
})(fabric_1.fabric.Object.prototype.toObject);
|
275
|
-
|
279
|
+
__exportStar(require("./common.util"), exports);
|
package/lib/utils/svg.util.d.ts
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
import { fabric } from "fabric";
|
2
|
-
export
|
3
|
-
export declare const getEllipsePath: (width: number, height: number) => string;
|
2
|
+
export declare const getEllipsePath: (rx: number, ry: number, side?: "left" | "right") => string;
|
4
3
|
export declare const getPathLength: (path: fabric.Path) => any;
|
5
|
-
export declare const
|
6
|
-
export declare const getHalfEllipsePath: (width: number, height: number) => string;
|
7
|
-
export declare const getPath: (width: number, height: number, type: PathType) => string;
|
4
|
+
export declare const getEllipseCircumference: (a: number, b: number) => number;
|
package/lib/utils/svg.util.js
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.getEllipseCircumference = exports.getPathLength = exports.getEllipsePath = void 0;
|
4
4
|
const fabric_1 = require("fabric");
|
5
|
-
const getEllipsePath = (
|
6
|
-
const
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
const getEllipsePath = (rx, ry, side = "left") => {
|
6
|
+
const sideFactor = side == "left" ? -1 : 1;
|
7
|
+
let output = `M 0,0`;
|
8
|
+
output += `a ${rx},${ry} 0 0,1 0,${ry * 2 * sideFactor}`;
|
9
|
+
output += " ";
|
10
|
+
output += `a ${rx},${ry} 0 0,1 0,${ry * -2 * sideFactor}`;
|
11
|
+
return output;
|
10
12
|
};
|
11
13
|
exports.getEllipsePath = getEllipsePath;
|
12
14
|
const getPathLength = (path) => {
|
@@ -15,30 +17,7 @@ const getPathLength = (path) => {
|
|
15
17
|
return pathLength;
|
16
18
|
};
|
17
19
|
exports.getPathLength = getPathLength;
|
18
|
-
const
|
19
|
-
|
20
|
-
const peak = `${0} -${height * 3}`;
|
21
|
-
const end = `${width / 2} -${height}`;
|
22
|
-
return `M ${start} Q ${peak} ${end}`;
|
20
|
+
const getEllipseCircumference = (a, b) => {
|
21
|
+
return Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));
|
23
22
|
};
|
24
|
-
exports.
|
25
|
-
const getHalfEllipsePath = (width, height) => {
|
26
|
-
const start = `-${width / 2} ${0}`;
|
27
|
-
const rxy = `${width / 2} ${height}`;
|
28
|
-
const end = `${width / 2} ${0}`;
|
29
|
-
return `M ${start} A ${rxy} 0 0 1 ${end}`;
|
30
|
-
};
|
31
|
-
exports.getHalfEllipsePath = getHalfEllipsePath;
|
32
|
-
const getPath = (width, height, type) => {
|
33
|
-
switch (type) {
|
34
|
-
case "ellipse":
|
35
|
-
return (0, exports.getEllipsePath)(width, height);
|
36
|
-
case "half-ellipse":
|
37
|
-
return (0, exports.getHalfEllipsePath)(width, height);
|
38
|
-
case "parabola":
|
39
|
-
return (0, exports.getParabolaPath)(width, height);
|
40
|
-
default:
|
41
|
-
return "";
|
42
|
-
}
|
43
|
-
};
|
44
|
-
exports.getPath = getPath;
|
23
|
+
exports.getEllipseCircumference = getEllipseCircumference;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "customized-fabric",
|
3
|
-
"version": "2.0.
|
3
|
+
"version": "2.0.11",
|
4
4
|
"description": "Customized fabric",
|
5
5
|
"main": "lib/index.js",
|
6
6
|
"types": "lib/index.d.ts",
|
@@ -22,4 +22,4 @@
|
|
22
22
|
"@types/fabric": "^5.3.3",
|
23
23
|
"typescript": "^5.2.2"
|
24
24
|
}
|
25
|
-
}
|
25
|
+
}
|
@@ -1,14 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.PARENT_ATTRIBUTES = exports.ADVANCED_TEXT_OBJECT_ATTRIBUTES = void 0;
|
4
|
-
exports.ADVANCED_TEXT_OBJECT_ATTRIBUTES = {
|
5
|
-
name: "Advanced text",
|
6
|
-
type: "ADVANCED_TEXT",
|
7
|
-
maxFontSize: 200,
|
8
|
-
stroke: {
|
9
|
-
stroke: "#333",
|
10
|
-
strokeDashArray: [5, 5],
|
11
|
-
strokeWidth: 1,
|
12
|
-
},
|
13
|
-
};
|
14
|
-
exports.PARENT_ATTRIBUTES = ["top", "left", "width", "height", "angle"];
|
@@ -1,198 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
const fabric_1 = require("fabric");
|
4
|
-
const constants_1 = require("./constants");
|
5
|
-
const utils_1 = require("../utils");
|
6
|
-
const objectId_1 = require("../utils/objectId");
|
7
|
-
const svg_util_1 = require("../utils/svg.util");
|
8
|
-
const common_util_1 = require("../utils/common.util");
|
9
|
-
const AdvancedTextClass = fabric_1.fabric.util.createClass(fabric_1.fabric.Group, {
|
10
|
-
initialize: function (options) {
|
11
|
-
let { text, ...rest } = options ?? {};
|
12
|
-
this.rectObject = new fabric_1.fabric.Rect({
|
13
|
-
width: options?.width,
|
14
|
-
height: options?.height,
|
15
|
-
fill: undefined,
|
16
|
-
originX: "center",
|
17
|
-
originY: "center",
|
18
|
-
objectCaching: false,
|
19
|
-
...constants_1.ADVANCED_TEXT_OBJECT_ATTRIBUTES.stroke,
|
20
|
-
});
|
21
|
-
text = (0, common_util_1.removeValueKeys)(text);
|
22
|
-
const { prefix = "", infix = "", suffix = "", isAllCapital } = text ?? {};
|
23
|
-
const fullText = prefix + infix + suffix;
|
24
|
-
this.textObject = new fabric_1.fabric.IText("", {
|
25
|
-
originX: "center",
|
26
|
-
originY: "center",
|
27
|
-
textAlign: "center",
|
28
|
-
objectCaching: false,
|
29
|
-
fontFamily: "",
|
30
|
-
paintFirst: "stroke",
|
31
|
-
lengthRatio: 0.4,
|
32
|
-
positionAngle: 0,
|
33
|
-
maxFontSize: 200,
|
34
|
-
pathType: "parabola",
|
35
|
-
...text,
|
36
|
-
text: isAllCapital ? fullText.toUpperCase() : fullText,
|
37
|
-
});
|
38
|
-
const group = new fabric_1.fabric.Group([this.rectObject, this.textObject]);
|
39
|
-
this.set({
|
40
|
-
...group,
|
41
|
-
_id: new objectId_1.ObjectId().toString(),
|
42
|
-
name: constants_1.ADVANCED_TEXT_OBJECT_ATTRIBUTES.name,
|
43
|
-
type: constants_1.ADVANCED_TEXT_OBJECT_ATTRIBUTES.type,
|
44
|
-
...rest,
|
45
|
-
layerId: options?.personalizeId ?? options?.layerId,
|
46
|
-
objectCaching: false,
|
47
|
-
pathVisible: !(options?.isOriginal || options?.hideStroke),
|
48
|
-
});
|
49
|
-
this.on("scaling", () => {
|
50
|
-
let width = this.width * this.scaleX;
|
51
|
-
let height = this.height * this.scaleY;
|
52
|
-
const attributes = {
|
53
|
-
scaleX: 1,
|
54
|
-
scaleY: 1,
|
55
|
-
width,
|
56
|
-
height,
|
57
|
-
};
|
58
|
-
this.set(attributes);
|
59
|
-
this.rectObject.set(attributes);
|
60
|
-
this.calculateTextPath(width, height);
|
61
|
-
this.autoChangeFontSize();
|
62
|
-
this.canvas?.renderAll?.();
|
63
|
-
});
|
64
|
-
if (options?.isOriginal) {
|
65
|
-
this.rectObject?.set({ strokeWidth: 0 });
|
66
|
-
}
|
67
|
-
else {
|
68
|
-
if (options?.hideStroke) {
|
69
|
-
this.rectObject?.set({ strokeWidth: 0 });
|
70
|
-
}
|
71
|
-
this.setFontFamily(text?.fontFamily ?? "", options?.fontUrl);
|
72
|
-
}
|
73
|
-
this.fire("scaling");
|
74
|
-
},
|
75
|
-
autoChangeFontSize: function (changeSpeed = 0.1) {
|
76
|
-
let { fontSize, maxFontSize, pathLength } = this.textObject;
|
77
|
-
fontSize = Number(fontSize || 0);
|
78
|
-
maxFontSize = Number(maxFontSize || 200);
|
79
|
-
const length = pathLength - 10;
|
80
|
-
let maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
81
|
-
const ratio = length / maxLineWidth;
|
82
|
-
fontSize = Math.min(maxFontSize, fontSize * ratio);
|
83
|
-
this.textObject.set({ fontSize });
|
84
|
-
this.canvas?.renderAll?.();
|
85
|
-
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
86
|
-
while (length <= maxLineWidth) {
|
87
|
-
fontSize -= changeSpeed;
|
88
|
-
this.textObject.set({ fontSize });
|
89
|
-
this.canvas?.renderAll?.();
|
90
|
-
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
91
|
-
}
|
92
|
-
while (maxFontSize > fontSize.toFixed(1) && length > maxLineWidth) {
|
93
|
-
fontSize += changeSpeed;
|
94
|
-
this.textObject.set({ fontSize });
|
95
|
-
this.canvas?.renderAll?.();
|
96
|
-
maxLineWidth = Math.max(...this.textObject.__lineWidths);
|
97
|
-
}
|
98
|
-
},
|
99
|
-
setText: function (text) {
|
100
|
-
this.textObject.set({
|
101
|
-
text,
|
102
|
-
});
|
103
|
-
this.fire("scaling");
|
104
|
-
},
|
105
|
-
setPrefix: function (text) {
|
106
|
-
this.textObject.set({
|
107
|
-
prefix: text,
|
108
|
-
});
|
109
|
-
this.getText();
|
110
|
-
},
|
111
|
-
setInfix: function (text) {
|
112
|
-
this.textObject.set({
|
113
|
-
infix: text,
|
114
|
-
});
|
115
|
-
this.getText();
|
116
|
-
},
|
117
|
-
setSuffix: function (text) {
|
118
|
-
this.textObject.set({
|
119
|
-
suffix: text,
|
120
|
-
});
|
121
|
-
this.getText();
|
122
|
-
},
|
123
|
-
getText: function () {
|
124
|
-
const { prefix = "", infix = "", suffix = "", isAllCapital, } = this.textObject;
|
125
|
-
const text = prefix + infix + suffix;
|
126
|
-
this.setText(infix?.length > 0 ? (isAllCapital ? text.toUpperCase() : text) : "");
|
127
|
-
},
|
128
|
-
setMaxFontSize: function (fontSize) {
|
129
|
-
this.textObject.set({
|
130
|
-
fontSize,
|
131
|
-
maxFontSize: fontSize,
|
132
|
-
});
|
133
|
-
this.fire("scaling");
|
134
|
-
},
|
135
|
-
setFontFamily: async function (fontName, fontUrl) {
|
136
|
-
if (!(0, utils_1.isFontLoaded)(fontName)) {
|
137
|
-
await (0, utils_1.loadFontFromUrl)(fontUrl ?? "", fontName);
|
138
|
-
}
|
139
|
-
this.textObject.set({ fontFamily: fontName });
|
140
|
-
this.fire("scaling");
|
141
|
-
},
|
142
|
-
setSizes: function (options) {
|
143
|
-
const { width, height } = options;
|
144
|
-
if (width) {
|
145
|
-
this.set({ width });
|
146
|
-
}
|
147
|
-
if (height) {
|
148
|
-
this.set({ height });
|
149
|
-
}
|
150
|
-
this.fire("scaling");
|
151
|
-
},
|
152
|
-
setTextAttributes: function (options) {
|
153
|
-
this.textObject.set(options);
|
154
|
-
this.fire("scaling");
|
155
|
-
},
|
156
|
-
getTextAttribute: function (attribute) {
|
157
|
-
return this.textObject.get(attribute);
|
158
|
-
},
|
159
|
-
getSettings: function (attribute) {
|
160
|
-
if (constants_1.PARENT_ATTRIBUTES.includes(attribute)) {
|
161
|
-
return this.get(attribute);
|
162
|
-
}
|
163
|
-
return this.textObject.get(attribute);
|
164
|
-
},
|
165
|
-
calculateTextPath: function (width, height) {
|
166
|
-
const { pathSide, pathType = "parabola" } = this.textObject;
|
167
|
-
const pathSvg = (0, svg_util_1.getPath)(width, height, pathType);
|
168
|
-
const sideFactor = pathSide == "left" ? -1 : 1;
|
169
|
-
const pathProperties = {
|
170
|
-
top: pathType == "parabola" ? (sideFactor * height) / 4 : 0,
|
171
|
-
angle: (pathSide == "left" ? 0 : 1) * 180,
|
172
|
-
};
|
173
|
-
const path = new fabric_1.fabric.Path(pathSvg, {
|
174
|
-
fill: undefined,
|
175
|
-
stroke: "black",
|
176
|
-
objectCaching: false,
|
177
|
-
originX: "center",
|
178
|
-
originY: "center",
|
179
|
-
visible: this.pathVisible,
|
180
|
-
});
|
181
|
-
this.pathObject = path;
|
182
|
-
const pathInfo = fabric_1.fabric.util?.getPathSegmentsInfo?.(path.path);
|
183
|
-
const pathLength = pathInfo.pop().length;
|
184
|
-
this.textObject.set({
|
185
|
-
...pathProperties,
|
186
|
-
path,
|
187
|
-
pathLength,
|
188
|
-
});
|
189
|
-
this?.canvas?.renderAll();
|
190
|
-
},
|
191
|
-
});
|
192
|
-
class AdvancedText extends fabric_1.fabric.Group {
|
193
|
-
constructor(options) {
|
194
|
-
super();
|
195
|
-
return new AdvancedTextClass(options);
|
196
|
-
}
|
197
|
-
}
|
198
|
-
exports.default = AdvancedText;
|
@@ -1,29 +0,0 @@
|
|
1
|
-
import { ObjectId } from "../utils/objectId";
|
2
|
-
export interface IAdvancedTextOptions extends fabric.IObjectOptions {
|
3
|
-
_id?: ObjectId;
|
4
|
-
personalizeId?: string;
|
5
|
-
layerId: number;
|
6
|
-
text: {
|
7
|
-
fontSize?: number;
|
8
|
-
fill?: string;
|
9
|
-
width?: number;
|
10
|
-
height?: number;
|
11
|
-
textAlign?: string;
|
12
|
-
fontWeight?: string;
|
13
|
-
text?: string;
|
14
|
-
fontFamily?: string;
|
15
|
-
maxFontSize: number;
|
16
|
-
stroke?: string;
|
17
|
-
strokeWidth?: number;
|
18
|
-
prefix?: string;
|
19
|
-
infix?: string;
|
20
|
-
suffix?: string;
|
21
|
-
lengthRatio?: number;
|
22
|
-
positionAngle?: number;
|
23
|
-
isAllCapital?: boolean;
|
24
|
-
};
|
25
|
-
fontUrl?: string;
|
26
|
-
isOriginal?: boolean;
|
27
|
-
isAdditional?: boolean;
|
28
|
-
hideStroke?: boolean;
|
29
|
-
}
|