customized-fabric 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/lib/ClipartObject/constants.js +12 -0
  2. package/lib/ClipartObject/index.js +145 -0
  3. package/lib/ClipartObject/interfaces.js +2 -0
  4. package/lib/ImagePlaceholderObject/constants.js +12 -0
  5. package/lib/ImagePlaceholderObject/index.js +140 -0
  6. package/lib/ImagePlaceholderObject/interfaces.js +2 -0
  7. package/lib/TextInputObject/constants.js +13 -0
  8. package/lib/TextInputObject/index.js +188 -0
  9. package/lib/TextInputObject/interfaces.js +2 -0
  10. package/lib/constants.js +12 -0
  11. package/lib/index.js +52 -0
  12. package/lib/interfaces.js +19 -0
  13. package/lib/objectId/bson_value.js +12 -0
  14. package/lib/objectId/constants.js +107 -0
  15. package/lib/objectId/error.js +79 -0
  16. package/lib/objectId/index.js +281 -0
  17. package/lib/objectId/parser/utils.js +31 -0
  18. package/lib/objectId/utils/byte_utils.js +28 -0
  19. package/lib/objectId/utils/node_byte_utils.js +98 -0
  20. package/lib/objectId/utils/web_byte_utils.js +124 -0
  21. package/lib/utils.js +90 -0
  22. package/package.json +21 -0
  23. package/src/ClipartObject/constants.ts +9 -0
  24. package/src/ClipartObject/index.ts +156 -0
  25. package/src/ClipartObject/interfaces.ts +29 -0
  26. package/src/ImagePlaceholderObject/constants.ts +9 -0
  27. package/src/ImagePlaceholderObject/index.ts +155 -0
  28. package/src/ImagePlaceholderObject/interfaces.ts +21 -0
  29. package/src/TextInputObject/constants.ts +11 -0
  30. package/src/TextInputObject/index.ts +205 -0
  31. package/src/TextInputObject/interfaces.ts +40 -0
  32. package/src/constants.ts +10 -0
  33. package/src/index.ts +62 -0
  34. package/src/interfaces.ts +3 -0
  35. package/src/objectId/bson_value.ts +18 -0
  36. package/src/objectId/constants.ts +141 -0
  37. package/src/objectId/error.ts +85 -0
  38. package/src/objectId/index.ts +354 -0
  39. package/src/objectId/parser/utils.ts +29 -0
  40. package/src/objectId/utils/byte_utils.ts +72 -0
  41. package/src/objectId/utils/node_byte_utils.ts +173 -0
  42. package/src/objectId/utils/web_byte_utils.ts +212 -0
  43. package/src/utils.ts +93 -0
  44. package/tsconfig.json +110 -0
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webByteUtils = exports.webMathRandomBytes = void 0;
4
+ const error_1 = require("../error");
5
+ function isReactNative() {
6
+ const { navigator } = globalThis;
7
+ return typeof navigator === "object" && navigator.product === "ReactNative";
8
+ }
9
+ /** @internal */
10
+ function webMathRandomBytes(byteLength) {
11
+ if (byteLength < 0) {
12
+ throw new RangeError(`The argument 'byteLength' is invalid. Received ${byteLength}`);
13
+ }
14
+ return exports.webByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
15
+ }
16
+ exports.webMathRandomBytes = webMathRandomBytes;
17
+ /** @internal */
18
+ const webRandomBytes = (() => {
19
+ const { crypto } = globalThis;
20
+ if (crypto != null && typeof crypto.getRandomValues === "function") {
21
+ return (byteLength) => {
22
+ // @ts-expect-error: crypto.getRandomValues cannot actually be null here
23
+ // You cannot separate getRandomValues from crypto (need to have this === crypto)
24
+ return crypto.getRandomValues(exports.webByteUtils.allocate(byteLength));
25
+ };
26
+ }
27
+ else {
28
+ if (isReactNative()) {
29
+ const { console } = globalThis;
30
+ console?.warn?.("BSON: For React Native please polyfill crypto.getRandomValues, e.g. using: https://www.npmjs.com/package/react-native-get-random-values.");
31
+ }
32
+ return webMathRandomBytes;
33
+ }
34
+ })();
35
+ const HEX_DIGIT = /(\d|[a-f])/i;
36
+ /** @internal */
37
+ exports.webByteUtils = {
38
+ toLocalBufferType(potentialUint8array) {
39
+ const stringTag = potentialUint8array?.[Symbol.toStringTag] ??
40
+ Object.prototype.toString.call(potentialUint8array);
41
+ if (stringTag === "Uint8Array") {
42
+ return potentialUint8array;
43
+ }
44
+ if (ArrayBuffer.isView(potentialUint8array)) {
45
+ return new Uint8Array(potentialUint8array.buffer.slice(potentialUint8array.byteOffset, potentialUint8array.byteOffset + potentialUint8array.byteLength));
46
+ }
47
+ if (stringTag === "ArrayBuffer" ||
48
+ stringTag === "SharedArrayBuffer" ||
49
+ stringTag === "[object ArrayBuffer]" ||
50
+ stringTag === "[object SharedArrayBuffer]") {
51
+ return new Uint8Array(potentialUint8array);
52
+ }
53
+ throw new error_1.BSONError(`Cannot make a Uint8Array from ${String(potentialUint8array)}`);
54
+ },
55
+ allocate(size) {
56
+ if (typeof size !== "number") {
57
+ throw new TypeError(`The "size" argument must be of type number. Received ${String(size)}`);
58
+ }
59
+ return new Uint8Array(size);
60
+ },
61
+ equals(a, b) {
62
+ if (a.byteLength !== b.byteLength) {
63
+ return false;
64
+ }
65
+ for (let i = 0; i < a.byteLength; i++) {
66
+ if (a[i] !== b[i]) {
67
+ return false;
68
+ }
69
+ }
70
+ return true;
71
+ },
72
+ fromNumberArray(array) {
73
+ return Uint8Array.from(array);
74
+ },
75
+ fromBase64(base64) {
76
+ return Uint8Array.from(atob(base64), (c) => c.charCodeAt(0));
77
+ },
78
+ toBase64(uint8array) {
79
+ return btoa(exports.webByteUtils.toISO88591(uint8array));
80
+ },
81
+ /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
82
+ fromISO88591(codePoints) {
83
+ return Uint8Array.from(codePoints, (c) => c.charCodeAt(0) & 0xff);
84
+ },
85
+ /** **Legacy** binary strings are an outdated method of data transfer. Do not add public API support for interpreting this format */
86
+ toISO88591(uint8array) {
87
+ return Array.from(Uint16Array.from(uint8array), (b) => String.fromCharCode(b)).join("");
88
+ },
89
+ fromHex(hex) {
90
+ const evenLengthHex = hex.length % 2 === 0 ? hex : hex.slice(0, hex.length - 1);
91
+ const buffer = [];
92
+ for (let i = 0; i < evenLengthHex.length; i += 2) {
93
+ const firstDigit = evenLengthHex[i];
94
+ const secondDigit = evenLengthHex[i + 1];
95
+ if (!HEX_DIGIT.test(firstDigit)) {
96
+ break;
97
+ }
98
+ if (!HEX_DIGIT.test(secondDigit)) {
99
+ break;
100
+ }
101
+ const hexDigit = Number.parseInt(`${firstDigit}${secondDigit}`, 16);
102
+ buffer.push(hexDigit);
103
+ }
104
+ return Uint8Array.from(buffer);
105
+ },
106
+ toHex(uint8array) {
107
+ return Array.from(uint8array, (byte) => byte.toString(16).padStart(2, "0")).join("");
108
+ },
109
+ fromUTF8(text) {
110
+ return new TextEncoder().encode(text);
111
+ },
112
+ toUTF8(uint8array, start, end) {
113
+ return new TextDecoder("utf8", { fatal: false }).decode(uint8array.slice(start, end));
114
+ },
115
+ utf8ByteLength(input) {
116
+ return exports.webByteUtils.fromUTF8(input).byteLength;
117
+ },
118
+ encodeUTF8Into(buffer, source, byteOffset) {
119
+ const bytes = exports.webByteUtils.fromUTF8(source);
120
+ buffer.set(bytes, byteOffset);
121
+ return bytes.byteLength;
122
+ },
123
+ randomBytes: webRandomBytes,
124
+ };
package/lib/utils.js ADDED
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getObject = exports.lockAllObjects = exports.lockObject = exports.loadImageFromFile = exports.isFontLoaded = exports.loadFontFromUrl = void 0;
4
+ const fabric_1 = require("fabric");
5
+ const constants_1 = require("./constants");
6
+ const _1 = require(".");
7
+ const ImagePlaceholderObject_1 = require("./ImagePlaceholderObject");
8
+ const loadFontFromUrl = async (name, url) => {
9
+ if (!name || !url)
10
+ return;
11
+ const font = new FontFace(name, `url(${url})`);
12
+ await font.load();
13
+ document.fonts.add(font);
14
+ };
15
+ exports.loadFontFromUrl = loadFontFromUrl;
16
+ const isFontLoaded = (name) => {
17
+ let isLoaded = false;
18
+ document.fonts.forEach((font) => {
19
+ if (name == font.family) {
20
+ isLoaded = true;
21
+ }
22
+ });
23
+ return isLoaded;
24
+ };
25
+ exports.isFontLoaded = isFontLoaded;
26
+ const loadImageFromFile = (image) => {
27
+ return new Promise((resolve) => {
28
+ const reader = new FileReader();
29
+ reader.onload = function (event) {
30
+ const image = new Image();
31
+ image.src = event?.target?.result;
32
+ image.onload = function () {
33
+ resolve(new fabric_1.fabric.Image(image));
34
+ };
35
+ };
36
+ reader.readAsDataURL(image);
37
+ });
38
+ };
39
+ exports.loadImageFromFile = loadImageFromFile;
40
+ const lockObject = (object, locked, selectable) => {
41
+ object.set({
42
+ hasControls: !locked,
43
+ lockMovementX: locked,
44
+ lockMovementY: locked,
45
+ lockRotation: locked,
46
+ lockScalingX: locked,
47
+ lockScalingY: locked,
48
+ lockUniScaling: locked,
49
+ lockSkewingX: locked,
50
+ lockSkewingY: locked,
51
+ lockScalingFlip: locked,
52
+ locked: locked,
53
+ selectable: selectable ?? !locked,
54
+ });
55
+ };
56
+ exports.lockObject = lockObject;
57
+ const lockAllObjects = (canvas, locked) => {
58
+ canvas._objects.map((object) => {
59
+ (0, exports.lockObject)(object, locked);
60
+ });
61
+ };
62
+ exports.lockAllObjects = lockAllObjects;
63
+ const getObject = (object, options) => {
64
+ switch (object.type) {
65
+ case constants_1.OBJECT_TYPES.textInput: {
66
+ const textInputObject = new _1.TextInput({
67
+ ...object,
68
+ hideStroke: options?.isOriginal,
69
+ });
70
+ return textInputObject;
71
+ }
72
+ case constants_1.OBJECT_TYPES.clipart: {
73
+ const clipartObject = new _1.Clipart({
74
+ ...object,
75
+ hideStroke: options?.isOriginal,
76
+ });
77
+ return clipartObject;
78
+ }
79
+ case constants_1.OBJECT_TYPES.imagePlaceHolder: {
80
+ const imagePlaceHolderObject = new ImagePlaceholderObject_1.ImagePlaceholder({
81
+ ...object,
82
+ hideStroke: options?.isOriginal,
83
+ });
84
+ return imagePlaceHolderObject;
85
+ }
86
+ default:
87
+ return;
88
+ }
89
+ };
90
+ exports.getObject = getObject;
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "customized-fabric",
3
+ "version": "1.0.0",
4
+ "description": "Customized fabric",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1",
9
+ "build": "tsc",
10
+ "prepare" : "npm run build"
11
+ },
12
+ "author": "",
13
+ "license": "ISC",
14
+ "dependencies": {
15
+ "fabric": "^5.3.0"
16
+ },
17
+ "devDependencies": {
18
+ "@types/fabric": "^5.3.3",
19
+ "typescript": "^5.2.2"
20
+ }
21
+ }
@@ -0,0 +1,9 @@
1
+ export const CLIPART_OBJECT_ATTRIBUTES = {
2
+ name: "Clipart",
3
+ type: "CLIP_ART",
4
+ stroke: {
5
+ stroke: "#000000",
6
+ strokeDashArray: [5, 5],
7
+ strokeWidth: 2,
8
+ },
9
+ };
@@ -0,0 +1,156 @@
1
+ import { fabric } from "fabric";
2
+ import { CLIPART_OBJECT_ATTRIBUTES } from "./constants";
3
+ import { loadImageFromFile } from "../utils";
4
+ import { ClipartObject, IClipartOptions } from "./interfaces";
5
+ import { ObjectId } from "../objectId";
6
+
7
+ const ClipartClass = fabric.util.createClass(fabric.Group, {
8
+ initialize: function (options?: IClipartOptions) {
9
+ this.rectObject = new fabric.Rect({
10
+ width: options?.width,
11
+ height: options?.height,
12
+ fill: undefined,
13
+ originX: "center",
14
+ originY: "center",
15
+ objectCaching: false,
16
+ ...CLIPART_OBJECT_ATTRIBUTES.stroke,
17
+ });
18
+
19
+ const imageObject = new fabric.Image("");
20
+ imageObject.set({
21
+ width: options?.width,
22
+ height: options?.height,
23
+ });
24
+ this.imageObject = imageObject;
25
+
26
+ const group = new fabric.Group([this.rectObject, this.imageObject]);
27
+ group.setControlsVisibility({
28
+ mt: false,
29
+ mr: false,
30
+ mb: false,
31
+ ml: false,
32
+ });
33
+ this.set(group);
34
+ this.on("scaling", () => {
35
+ let width = this.width * this.scaleX;
36
+ let height = this.height * this.scaleY;
37
+ const imageScaleX = width / this.imageObject.width;
38
+ const imageScaleY = height / this.imageObject.height;
39
+ this.imageObject.set({ scaleX: imageScaleX, scaleY: imageScaleY });
40
+ this.fitImage(this.imageObject);
41
+ this.canvas?.renderAll?.();
42
+ });
43
+ this.set({
44
+ _id: new ObjectId().toString(),
45
+ name: CLIPART_OBJECT_ATTRIBUTES.name,
46
+ type: CLIPART_OBJECT_ATTRIBUTES.type,
47
+ ...options,
48
+ layerId: options?.personalizeId ?? options?.layerId,
49
+ objectCaching: false,
50
+ });
51
+
52
+ if (options?.clipartUrl) {
53
+ this.loadImageFromUrl(options.clipartUrl);
54
+ }
55
+ if (options?.clipartFile) {
56
+ this.loadImageFromFile(options.clipartFile);
57
+ }
58
+ if (options?.hideStroke) {
59
+ this.rectObject.set({ strokeWidth: 0 });
60
+ }
61
+ },
62
+
63
+ loadImageFromUrl: async function (url: string) {
64
+ fabric.Image.fromURL(
65
+ url,
66
+ (loadedImage) => {
67
+ this.loadImage(loadedImage);
68
+ },
69
+ {
70
+ crossOrigin: "anonymous",
71
+ }
72
+ );
73
+ },
74
+
75
+ loadImageFromFile: async function (imageFile: File) {
76
+ const loadedImage = await loadImageFromFile(imageFile);
77
+ this.loadImage(loadedImage);
78
+ },
79
+
80
+ loadImage: function (image: fabric.Image) {
81
+ if (image.width && image.height) {
82
+ image.set({
83
+ originX: "center",
84
+ originY: "center",
85
+ });
86
+ image.scaleToWidth(this.width);
87
+ this.remove(this.imageObject);
88
+ this.imageObject = image;
89
+ this.add(this.imageObject);
90
+ this.fitImage(this.imageObject);
91
+ } else {
92
+ this.remove(this.imageObject);
93
+ const imageObject = new fabric.Image("");
94
+ imageObject.set({
95
+ width: this.width,
96
+ height: this.height,
97
+ });
98
+ this.imageObject = imageObject;
99
+ this.add(this.imageObject);
100
+ this.fitImage(this.imageObject);
101
+ }
102
+ this.canvas?.renderAll();
103
+ },
104
+
105
+ getSettings: function (attribute: string) {
106
+ return this.get(attribute);
107
+ },
108
+
109
+ setSizes: function (options: { width?: number; height?: number }) {
110
+ const { width, height } = options;
111
+ if (width) {
112
+ const scaleX = width / (this?.imageObject?.width ?? this.width);
113
+ this.imageObject.set({ scaleX, scaleY: scaleX });
114
+ }
115
+ if (height) {
116
+ const scaleY = height / (this?.imageObject?.height ?? this.height);
117
+ this.imageObject.set({ scaleX: scaleY, scaleY });
118
+ }
119
+ this.fitImage(this.imageObject);
120
+ this.canvas?.renderAll?.();
121
+ },
122
+
123
+ fitImage: function (image: fabric.Image) {
124
+ const attributes = {
125
+ scaleX: 1,
126
+ scaleY: 1,
127
+ width: (image.width ?? 0) * (image.scaleX ?? 1),
128
+ height: (image.height ?? 0) * (image.scaleY ?? 1),
129
+ };
130
+ this.set(attributes);
131
+ this.rectObject.set(attributes);
132
+ },
133
+ });
134
+
135
+ export const toClipartObject = (clipartObject: ClipartObject) => {
136
+ return {
137
+ id: clipartObject._id,
138
+ personalizeId: clipartObject.layerId,
139
+ layerId: clipartObject.layerId,
140
+ name: clipartObject.name,
141
+ locked: clipartObject.locked,
142
+ isAdditional: clipartObject?.isAdditional,
143
+ clipartUrl: clipartObject?.clipartUrl,
144
+ clipartFile: clipartObject?.clipartFile,
145
+ clipartRootCategoryId: clipartObject?.clipartRootCategoryId,
146
+ clipartCategoryId: clipartObject?.clipartCategoryId,
147
+ clipartOptionId: clipartObject?.clipartOptionId,
148
+ };
149
+ };
150
+
151
+ export class Clipart extends fabric.Group {
152
+ constructor(options?: IClipartOptions) {
153
+ super();
154
+ return new ClipartClass(options);
155
+ }
156
+ }
@@ -0,0 +1,29 @@
1
+ import { ObjectId } from "../objectId";
2
+
3
+ export interface ClipartObject extends fabric.Group {
4
+ _id: ObjectId;
5
+ layerId?: number;
6
+ locked?: boolean;
7
+ isAdditional?: boolean;
8
+ clipartFile?: File;
9
+ clipartRootCategoryId?: string;
10
+ clipartRootCategoryName?: string;
11
+ clipartCategoryId?: string;
12
+ clipartCategoryName?: string;
13
+ clipartOptionId?: number;
14
+ imageObject?: fabric.Image;
15
+ clipartUrl?: string;
16
+ loadImageFromFile: (imageFile: File) => void;
17
+ loadImageFromUrl: (imageUrl: string) => void;
18
+ getSettings: (attribute: string) => any;
19
+ setSizes: (options: { width?: number; height?: number }) => void;
20
+ }
21
+
22
+ export interface IClipartOptions extends fabric.IGroupOptions {
23
+ _id?: string;
24
+ personalizeId?: number;
25
+ layerId: number;
26
+ clipartUrl?: string;
27
+ clipartFile?: File;
28
+ hideStroke?: boolean;
29
+ }
@@ -0,0 +1,9 @@
1
+ export const IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES = {
2
+ name: "Image placeholder",
3
+ type: "IMAGE_PLACEHOLDER",
4
+ stroke: {
5
+ stroke: "#000000",
6
+ strokeDashArray: [5, 5],
7
+ strokeWidth: 2,
8
+ },
9
+ };
@@ -0,0 +1,155 @@
1
+ import { fabric } from "fabric";
2
+ import { IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES } from "./constants";
3
+ import { IImagePlaceholderOptions, ImagePlaceholderObject } from "./interfaces";
4
+ import { loadImageFromFile } from "../utils";
5
+ import { ObjectId } from "../objectId";
6
+
7
+ const ImagePlaceholderClass = fabric.util.createClass(fabric.Group, {
8
+ initialize: function (options?: IImagePlaceholderOptions) {
9
+ this.rectObject = new fabric.Rect({
10
+ width: options?.width,
11
+ height: options?.height,
12
+ fill: undefined,
13
+ originX: "center",
14
+ originY: "center",
15
+ objectCaching: false,
16
+ ...IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES.stroke,
17
+ });
18
+
19
+ this.imageObject = new fabric.Image("");
20
+
21
+ const group = new fabric.Group([this.rectObject, this.imageObject]);
22
+ this.set(group);
23
+ this.on("scaling", () => {
24
+ let width = this.width * this.scaleX;
25
+ let height = this.height * this.scaleY;
26
+ this.setSizes({ width, height });
27
+ this.canvas?.renderAll();
28
+ });
29
+ this.set({
30
+ _id: new ObjectId().toString(),
31
+ name: IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES.name,
32
+ type: IMAGE_PLACEHOLDER_OBJECT_ATTRIBUTES.type,
33
+ ...options,
34
+ layerId: options?.personalizeId ?? options?.layerId,
35
+ objectCaching: false,
36
+ });
37
+
38
+ if (options?.imageFile) {
39
+ this.loadImageFromFile(options?.imageFile);
40
+ }
41
+ if (options?.hideStroke) {
42
+ this.rectObject.set({ strokeWidth: 0 });
43
+ }
44
+ },
45
+
46
+ loadImageFromUrl: async function (url: string) {
47
+ fabric.Image.fromURL(
48
+ url,
49
+ (loadedImage) => {
50
+ this.loadImage(loadedImage);
51
+ },
52
+ {
53
+ crossOrigin: "anonymous",
54
+ }
55
+ );
56
+ },
57
+
58
+ loadImageFromFile: async function (imageFile: File) {
59
+ const loadedImage = await loadImageFromFile(imageFile);
60
+ this.loadImage(loadedImage);
61
+ },
62
+
63
+ loadImage: function (image: fabric.Image) {
64
+ if (image.width && image.height) {
65
+ image.set({
66
+ originX: "center",
67
+ originY: "center",
68
+ });
69
+ this.remove(this.imageObject);
70
+ this.imageObject = image;
71
+ this.add(this.imageObject);
72
+ this.fitImage(this.imageObject);
73
+ } else {
74
+ this.remove(this.imageObject);
75
+ this.imageObject = new fabric.Image("");
76
+ this.add(this.imageObject);
77
+ this.fitImage(this.imageObject);
78
+ }
79
+ this.canvas?.renderAll();
80
+ },
81
+
82
+ setSizes: function (options: { width?: number; height?: number }) {
83
+ const { width, height } = options;
84
+ const attributes: any = {
85
+ scaleX: 1,
86
+ scaleY: 1,
87
+ };
88
+ if (width) {
89
+ attributes.width = width;
90
+ }
91
+ if (height) {
92
+ attributes.height = height;
93
+ }
94
+ this.set(attributes);
95
+ this.rectObject.set(attributes);
96
+ this.fitImage(this.imageObject);
97
+ this.canvas?.renderAll?.();
98
+ },
99
+
100
+ fitImage: function (image: fabric.Image) {
101
+ const imageScaleX = this.width / (image?.width ?? 1);
102
+ const imageScaleY = this.height / (image?.height ?? 1);
103
+ imageScaleX > imageScaleY
104
+ ? image.set({ scaleX: imageScaleY, scaleY: imageScaleY })
105
+ : image.set({ scaleX: imageScaleX, scaleY: imageScaleX });
106
+ },
107
+
108
+ getSettings: function (attribute: string) {
109
+ return this.get(attribute);
110
+ },
111
+
112
+ loadUploadedImage: function (imageFile: File) {
113
+ loadImageFromFile(imageFile).then((loadedImage) => {
114
+ const clipPath = new fabric.Rect({
115
+ width: this.width,
116
+ height: this.height,
117
+ top: this.top,
118
+ left: this.left,
119
+ absolutePositioned: true,
120
+ });
121
+ loadedImage.set({ top: this.top, left: this.left, clipPath: clipPath });
122
+ this.fitImage(loadedImage);
123
+ this.uploadedImage = loadedImage;
124
+ const canvas = this?.canvas;
125
+ canvas?.add(this.uploadedImage);
126
+ canvas?.renderAll();
127
+ });
128
+ },
129
+
130
+ removeUploadedImage: function () {
131
+ const canvas = this?.canvas;
132
+ canvas?.remove(this.uploadedImage);
133
+ canvas?.renderAll();
134
+ },
135
+ });
136
+
137
+ export const toImagePlaceholderObject = (
138
+ imagePlaceholderObject: ImagePlaceholderObject
139
+ ) => {
140
+ return {
141
+ id: imagePlaceholderObject._id,
142
+ personalizeId: imagePlaceholderObject.layerId,
143
+ layerId: imagePlaceholderObject.layerId,
144
+ name: imagePlaceholderObject.name,
145
+ locked: imagePlaceholderObject.locked,
146
+ isAdditional: imagePlaceholderObject?.isAdditional,
147
+ };
148
+ };
149
+
150
+ export class ImagePlaceholder extends fabric.Group {
151
+ constructor(options?: IImagePlaceholderOptions) {
152
+ super();
153
+ return new ImagePlaceholderClass(options);
154
+ }
155
+ }
@@ -0,0 +1,21 @@
1
+ import { ObjectId } from "../objectId";
2
+
3
+ export interface ImagePlaceholderObject extends fabric.Group {
4
+ _id: ObjectId;
5
+ layerId: number;
6
+ locked: boolean;
7
+ imageFile?: File;
8
+ isAdditional: boolean;
9
+ loadImageFromFile: (imageFile: File) => void;
10
+ loadImageFromUrl: (imageUrl: string) => void;
11
+ getSettings: (attribute: string) => any;
12
+ setSizes: (options: { width?: number; height?: number }) => void;
13
+ }
14
+
15
+ export interface IImagePlaceholderOptions extends fabric.IGroupOptions {
16
+ _id?: string;
17
+ personalizeId?: number;
18
+ layerId: number;
19
+ imageFile?: File;
20
+ hideStroke?: boolean;
21
+ }
@@ -0,0 +1,11 @@
1
+ export const TEXT_INPUT_OBJECT_ATTRIBUTES = {
2
+ name: "Text input",
3
+ type: "TEXT_INPUT",
4
+ stroke: {
5
+ stroke: "#000000",
6
+ strokeDashArray: [5, 5],
7
+ strokeWidth: 2,
8
+ },
9
+ };
10
+
11
+ export const PARENT_ATTRIBUTES = ["top", "left", "width", "height", "angle"];