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.
@@ -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, pathLength } = this.textObject;
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 = pathLength * lengthRatio;
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({ fontSize });
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({ fontSize });
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 path = new fabric_1.fabric.Path((0, svg_util_1.getEllipsePath)(width, height), {
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.pop().length;
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
- loadCustomizedImage?: (image: IImageOptions) => Promise<void>;
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: left - this.left,
161
- top: top - this.top,
166
+ left,
167
+ top,
162
168
  width,
163
169
  height,
164
170
  scaleX,
165
171
  scaleY,
166
- angle: angle - this.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
- loadCustomizedImage: async function (image) {
252
+ loadCustomImage: async function (image) {
246
253
  if (image) {
247
- const { url, filteredUrl, data, clipPath } = image;
254
+ const { url, filteredUrl, data } = image;
248
255
  const imageUrl = filteredUrl ?? url;
249
- if (imageUrl && data && clipPath) {
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 { top, left, scaleX, width, angle, flipX, flipY, settings = {}, } = data;
260
+ const { relativeLeftRatio, relativeTopRatio, relativeScaleX, relativeScaleY, relativeAngle, width, height, flipX, flipY, settings = {}, } = data;
254
261
  const { color, type } = settings;
255
- const ratioWidth = (width * scaleX) / (clipPath.width * clipPath.scaleX);
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
- top: this.top + ratioPosition * top,
260
- left: this.left + ratioPosition * left,
261
- angle: this.angle + angle,
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.renderAll();
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;
@@ -7,6 +7,5 @@ export declare const OBJECT_TYPES: {
7
7
  layoutGroup: string;
8
8
  calendar: string;
9
9
  qrCode: string;
10
- advancedText: string;
11
10
  };
12
11
  export declare const MAX_TEXTURE_SIZE = 20000;
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 { fabric, TextInput, Clipart, ImagePlaceholder, LayoutGroup, CurvedText, Calendar, QRCode, AdvancedText, lockObject, lockAllObjects, loadImageFromFile, loadImageFromUrl, getObject, asyncGetObject, OBJECT_TYPES, IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES, IMAGE_FILTER_TYPES, };
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
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.asyncGetObject = exports.getObject = exports.loadImageFromUrl = exports.loadImageFromFile = exports.lockAllObjects = exports.lockObject = exports.AdvancedText = exports.QRCode = exports.Calendar = exports.CurvedText = exports.LayoutGroup = exports.ImagePlaceholder = exports.Clipart = exports.TextInput = exports.fabric = void 0;
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
+ };
@@ -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;
@@ -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 default fabric;
27
+ export { fabric };
28
+ export * from "./common.util";
@@ -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?.loadCustomizedImage?.(object?.image);
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
- exports.default = fabric_1.fabric;
279
+ __exportStar(require("./common.util"), exports);
@@ -1,7 +1,4 @@
1
1
  import { fabric } from "fabric";
2
- export type PathType = "parabola" | "ellipse" | "half-ellipse";
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 getParabolaPath: (width: number, height: number) => string;
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;
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPath = exports.getHalfEllipsePath = exports.getParabolaPath = exports.getPathLength = exports.getEllipsePath = void 0;
3
+ exports.getEllipseCircumference = exports.getPathLength = exports.getEllipsePath = void 0;
4
4
  const fabric_1 = require("fabric");
5
- const getEllipsePath = (width, height) => {
6
- const start = `${0} ${height / 2}`;
7
- const rxy = `${width / 2} ${height / 2}`;
8
- const end = `${0} ${-height / 2}`;
9
- return `M ${start} A ${rxy} 0 0 1 ${end} A ${rxy} 0 0 1 ${start}`;
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 getParabolaPath = (width, height) => {
19
- const start = `-${width / 2} -${height}`;
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.getParabolaPath = getParabolaPath;
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.9",
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,11 +0,0 @@
1
- export declare const ADVANCED_TEXT_OBJECT_ATTRIBUTES: {
2
- name: string;
3
- type: string;
4
- maxFontSize: number;
5
- stroke: {
6
- stroke: string;
7
- strokeDashArray: number[];
8
- strokeWidth: number;
9
- };
10
- };
11
- export declare const PARENT_ATTRIBUTES: string[];
@@ -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,5 +0,0 @@
1
- import { fabric } from "fabric";
2
- import { IAdvancedTextOptions } from "./interfaces";
3
- export default class AdvancedText extends fabric.Group {
4
- constructor(options?: IAdvancedTextOptions);
5
- }
@@ -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
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });