@hprint/plugins 0.0.9-alpha.1 → 0.0.10

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.
@@ -1,9 +1,14 @@
1
- import { fabric, IEditor, IPluginTempl } from '@hprint/core';
1
+ import { fabric, IEditor, IPluginOption, IPluginTempl } from '@hprint/core';
2
+ interface ControlsPluginOptions extends IPluginOption {
3
+ /** 是否禁用多选对象的整体缩放,默认保留 Fabric 的缩放能力。 */
4
+ disableActiveSelectionScaling?: boolean;
5
+ }
2
6
  declare class ControlsPlugin implements IPluginTempl {
3
7
  canvas: fabric.Canvas;
4
8
  editor: IEditor;
9
+ private options;
5
10
  static pluginName: string;
6
- constructor(canvas: fabric.Canvas, editor: IEditor);
11
+ constructor(canvas: fabric.Canvas, editor: IEditor, options?: ControlsPluginOptions);
7
12
  init(): void;
8
13
  /**
9
14
  * 为画布上所有对象应用统一的控制点样式
@@ -1 +1 @@
1
- {"version":3,"file":"ControlsPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/ControlsPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAMtC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA4N1D,cAAM,cAAe,YAAW,YAAY;IAG7B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,OAAO;IAH1B,MAAM,CAAC,UAAU,SAAoB;gBAE1B,MAAM,EAAE,MAAM,CAAC,MAAM,EACrB,MAAM,EAAE,OAAO;IAI1B,IAAI;IAwBJ;;OAEG;IACH,kBAAkB;IAYlB;;OAEG;IACH,wBAAwB;IAmIxB,OAAO;CAGV;AAED,eAAe,cAAc,CAAC"}
1
+ {"version":3,"file":"ControlsPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/ControlsPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAMtC,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEzE,UAAU,qBAAsB,SAAQ,aAAa;IACjD,uCAAuC;IACvC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CAC3C;AA4ND,cAAM,cAAe,YAAW,YAAY;IAG7B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,OAAO;IACtB,OAAO,CAAC,OAAO;IAJnB,MAAM,CAAC,UAAU,SAAoB;gBAE1B,MAAM,EAAE,MAAM,CAAC,MAAM,EACrB,MAAM,EAAE,OAAO,EACd,OAAO,GAAE,qBAA0B;IAI/C,IAAI;IAwBJ;;OAEG;IACH,kBAAkB;IAYlB;;OAEG;IACH,wBAAwB;IA+KxB,OAAO;CAGV;AAED,eAAe,cAAc,CAAC"}
@@ -10,6 +10,8 @@ declare class GroupAlignPlugin implements IPluginTempl {
10
10
  static pluginName: string;
11
11
  static apis: string[];
12
12
  constructor(canvas: fabric.Canvas, editor: IEditor);
13
+ _refreshObjectCoordinates(objects: fabric.Object[]): void;
14
+ _notifySelectionModified(selection: fabric.ActiveSelection): void;
13
15
  left(): void;
14
16
  right(): void;
15
17
  xcenter(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"GroupAlignPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/GroupAlignPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE1D,KAAK,OAAO,GAAG,IAAI,CACf,gBAAgB,EACd,MAAM,GACN,OAAO,GACP,SAAS,GACT,SAAS,GACT,KAAK,GACL,QAAQ,GACR,WAAW,GACX,WAAW,CAChB,CAAC;AAEF,OAAO,QAAQ,cAAc,CAAC;IAE1B,UAAU,OAAQ,SAAQ,OAAO;KAAI;CACxC;AAED,cAAM,gBAAiB,YAAW,YAAY;IAc/B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,OAAO;IAd1B,MAAM,CAAC,UAAU,SAAsB;IACvC,MAAM,CAAC,IAAI,WAST;gBAGS,MAAM,EAAE,MAAM,CAAC,MAAM,EACrB,MAAM,EAAE,OAAO;IAG1B,IAAI;IAuBJ,KAAK;IA0BL,OAAO;IA0BP,OAAO;IA0BP,GAAG;IAsBH,MAAM;IA0BN,SAAS;IAwFT,SAAS;IAoFT,OAAO;CAGV;AAED,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"GroupAlignPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/GroupAlignPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE1D,KAAK,OAAO,GAAG,IAAI,CACf,gBAAgB,EACd,MAAM,GACN,OAAO,GACP,SAAS,GACT,SAAS,GACT,KAAK,GACL,QAAQ,GACR,WAAW,GACX,WAAW,CAChB,CAAC;AAEF,OAAO,QAAQ,cAAc,CAAC;IAE1B,UAAU,OAAQ,SAAQ,OAAO;KAAI;CACxC;AAED,cAAM,gBAAiB,YAAW,YAAY;IAc/B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,OAAO;IAd1B,MAAM,CAAC,UAAU,SAAsB;IACvC,MAAM,CAAC,IAAI,WAST;gBAGS,MAAM,EAAE,MAAM,CAAC,MAAM,EACrB,MAAM,EAAE,OAAO;IAG1B,yBAAyB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;IAOlD,wBAAwB,CAAC,SAAS,EAAE,MAAM,CAAC,eAAe;IAK1D,IAAI;IAwBJ,KAAK;IA2BL,OAAO;IA2BP,OAAO;IA2BP,GAAG;IAuBH,MAAM;IA2BN,SAAS;IA0FT,SAAS;IAsFT,OAAO;CAGV;AAED,eAAe,gBAAgB,CAAC"}
@@ -78,6 +78,7 @@ declare class UnitPlugin implements IPluginTempl {
78
78
  _syncOriginSize(width?: number, height?: number): void;
79
79
  syncOriginSizeByUnit(width?: number, height?: number): void;
80
80
  _bindEvents(): void;
81
+ _syncTargetOriginSize(target: fabric.Object): void;
81
82
  destroy(): void;
82
83
  }
83
84
  export default UnitPlugin;
@@ -1 +1 @@
1
- {"version":3,"file":"UnitPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/UnitPlugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"UnitPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/UnitPlugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hprint/plugins",
3
- "version": "0.0.9-alpha.1",
3
+ "version": "0.0.10",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -22,8 +22,8 @@
22
22
  "qs": "~6.12.3",
23
23
  "socket.io-client": "^4.8.1",
24
24
  "uuid": "~8.3.2",
25
- "@hprint/core": "0.0.9-alpha.1",
26
- "@hprint/shared": "0.0.9-alpha.1"
25
+ "@hprint/shared": "0.0.10",
26
+ "@hprint/core": "0.0.10"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/bwip-js": "^3.2.3",
@@ -12,12 +12,12 @@ declare module '@hprint/core' {
12
12
  interface IEditor extends IPlugin {}
13
13
  }
14
14
 
15
- type LayoutEntry = {
16
- object: fabric.Object;
17
- index: number;
18
- originalTop: number;
19
- originalBottom: number;
20
- };
15
+ type LayoutEntry = {
16
+ object: fabric.Object;
17
+ index: number;
18
+ originalTop: number;
19
+ originalBottom: number;
20
+ };
21
21
 
22
22
  class ActualContentLayoutPlugin implements IPluginTempl {
23
23
  static pluginName = 'ActualContentLayoutPlugin';
@@ -51,32 +51,32 @@ class ActualContentLayoutPlugin implements IPluginTempl {
51
51
  });
52
52
  }
53
53
 
54
- applyActualContentLayout(templateContent: any, templateHeight: number) {
55
- const settings = (templateContent?.templateSettings ||
56
- {}) as ActualContentLayoutSettings;
57
- if (!settings.actualContentLayout) return templateHeight;
58
-
59
- const fabricObjects = this.canvas
60
- .getObjects()
61
- .filter(this.isPrintableObject);
62
- const mmPerPx = Number(this.editor.getSizeByUnit?.(1, 'mm')) || 1;
63
- const sourceObjects = this.getTemplateSourceObjects(templateContent);
64
-
65
- fabricObjects.forEach((object) => this.preparePrintLayoutObject(object));
66
-
67
- const entries = fabricObjects.map((object, index) => {
68
- const origin = this.layoutOrigins.get(object);
69
- const source = this.getSourceObject(object, sourceObjects);
70
- const originalTop =
71
- origin?.top ??
72
- this.getOriginalTop(source, object, mmPerPx);
73
- const originalHeight =
74
- origin?.height ??
75
- this.getOriginalHeight(source, object, mmPerPx);
76
- return {
77
- object,
78
- index,
79
- originalTop,
54
+ applyActualContentLayout(templateContent: any, templateHeight: number) {
55
+ const settings = (templateContent?.templateSettings ||
56
+ {}) as ActualContentLayoutSettings;
57
+ if (!settings.actualContentLayout) return templateHeight;
58
+
59
+ const fabricObjects = this.canvas
60
+ .getObjects()
61
+ .filter(this.isPrintableObject);
62
+ const mmPerPx = Number(this.editor.getSizeByUnit?.(1, 'mm')) || 1;
63
+ const sourceObjects = this.getTemplateSourceObjects(templateContent);
64
+
65
+ fabricObjects.forEach((object) => this.preparePrintLayoutObject(object));
66
+
67
+ const entries = fabricObjects.map((object, index) => {
68
+ const origin = this.layoutOrigins.get(object);
69
+ const source = this.getSourceObject(object, sourceObjects);
70
+ const originalTop =
71
+ origin?.top ??
72
+ this.getOriginalTop(source, object, mmPerPx);
73
+ const originalHeight =
74
+ origin?.height ??
75
+ this.getOriginalHeight(source, object, mmPerPx);
76
+ return {
77
+ object,
78
+ index,
79
+ originalTop,
80
80
  originalBottom: originalTop + originalHeight,
81
81
  };
82
82
  }) as LayoutEntry[];
@@ -159,22 +159,22 @@ class ActualContentLayoutPlugin implements IPluginTempl {
159
159
  );
160
160
  }
161
161
 
162
- private getOriginalTop(
163
- source: any,
164
- object: fabric.Object,
165
- mmPerPx: number
166
- ) {
162
+ private getOriginalTop(
163
+ source: any,
164
+ object: fabric.Object,
165
+ mmPerPx: number
166
+ ) {
167
167
  const top = Number(source?.top);
168
168
  if (Number.isFinite(top)) return top * mmPerPx;
169
169
  return this.getOriginMmValue(
170
170
  source,
171
171
  'top',
172
172
  Number(object.top || 0) * mmPerPx
173
- );
174
- }
175
-
176
- private getOriginalHeight(
177
- source: any,
173
+ );
174
+ }
175
+
176
+ private getOriginalHeight(
177
+ source: any,
178
178
  object: fabric.Object,
179
179
  mmPerPx: number
180
180
  ) {
@@ -188,31 +188,31 @@ class ActualContentLayoutPlugin implements IPluginTempl {
188
188
  'height',
189
189
  Number(object.getScaledHeight?.() || object.height || 0) *
190
190
  mmPerPx
191
- );
192
- }
193
-
194
- private getTemplateSourceObjects(templateContent: any) {
195
- const sourceObjects = new Map<string, any>();
196
- if (!Array.isArray(templateContent?.objects)) return sourceObjects;
197
- templateContent.objects.forEach((source: any, index: number) => {
198
- if (source?.id) sourceObjects.set(`id:${source.id}`, source);
199
- sourceObjects.set(`index:${index}`, source);
200
- });
201
- return sourceObjects;
202
- }
203
-
204
- private getSourceObject(
205
- object: any,
206
- sourceObjects: Map<string, any>
207
- ) {
208
- if (object?.id) {
209
- const source = sourceObjects.get(`id:${object.id}`);
210
- if (source) return source;
211
- }
212
- const objects = this.canvas.getObjects().filter(this.isPrintableObject);
213
- const index = objects.indexOf(object);
214
- return sourceObjects.get(`index:${index}`);
215
- }
191
+ );
192
+ }
193
+
194
+ private getTemplateSourceObjects(templateContent: any) {
195
+ const sourceObjects = new Map<string, any>();
196
+ if (!Array.isArray(templateContent?.objects)) return sourceObjects;
197
+ templateContent.objects.forEach((source: any, index: number) => {
198
+ if (source?.id) sourceObjects.set(`id:${source.id}`, source);
199
+ sourceObjects.set(`index:${index}`, source);
200
+ });
201
+ return sourceObjects;
202
+ }
203
+
204
+ private getSourceObject(
205
+ object: any,
206
+ sourceObjects: Map<string, any>
207
+ ) {
208
+ if (object?.id) {
209
+ const source = sourceObjects.get(`id:${object.id}`);
210
+ if (source) return source;
211
+ }
212
+ const objects = this.canvas.getObjects().filter(this.isPrintableObject);
213
+ const index = objects.indexOf(object);
214
+ return sourceObjects.get(`index:${index}`);
215
+ }
216
216
 
217
217
  private getOriginMmValue(
218
218
  source: any,
@@ -252,36 +252,36 @@ class ActualContentLayoutPlugin implements IPluginTempl {
252
252
  );
253
253
  }
254
254
 
255
- private isEmptyLayoutObject(object: any) {
256
- if (object?.visible === false) return true;
257
- const field = object?.extension?._field_;
258
- if (!field) return false;
259
- if (object.type === 'textbox') {
260
- return String(object.text ?? '') === '';
261
- }
262
- if (['barcode', 'qrcode'].includes(object.extensionType)) {
263
- return (
264
- String(object.extension?.value ?? '') === '' &&
265
- !this.hasVisibleImageSource(object)
266
- );
267
- }
268
- if (object.extensionType === 'imageTextList') {
269
- return (
270
- !Array.isArray(object.extension?.items) ||
255
+ private isEmptyLayoutObject(object: any) {
256
+ if (object?.visible === false) return true;
257
+ const field = object?.extension?._field_;
258
+ if (!field) return false;
259
+ if (object.type === 'textbox') {
260
+ return String(object.text ?? '') === '';
261
+ }
262
+ if (['barcode', 'qrcode'].includes(object.extensionType)) {
263
+ return (
264
+ String(object.extension?.value ?? '') === '' &&
265
+ !this.hasVisibleImageSource(object)
266
+ );
267
+ }
268
+ if (object.extensionType === 'imageTextList') {
269
+ return (
270
+ !Array.isArray(object.extension?.items) ||
271
271
  object.extension.items.length === 0
272
272
  );
273
- }
274
- return false;
275
- }
276
-
277
- private hasVisibleImageSource(object: any) {
278
- const src = String(object?.getSrc?.() ?? object?.src ?? '');
279
- return src !== '' && /^data:image\//i.test(src);
280
- }
281
-
282
- private getActualLayoutHeight(object: any) {
283
- if (object?.extensionType !== 'imageTextList') {
284
- return Number(
273
+ }
274
+ return false;
275
+ }
276
+
277
+ private hasVisibleImageSource(object: any) {
278
+ const src = String(object?.getSrc?.() ?? object?.src ?? '');
279
+ return src !== '' && /^data:image\//i.test(src);
280
+ }
281
+
282
+ private getActualLayoutHeight(object: any) {
283
+ if (object?.extensionType !== 'imageTextList') {
284
+ return Number(
285
285
  object.getScaledHeight?.() || object.height || 0
286
286
  );
287
287
  }
@@ -4,7 +4,12 @@ import verticalImg from '../assets/middlecontrol.svg?url';
4
4
  import horizontalImg from '../assets/middlecontrolhoz.svg?url';
5
5
  import edgeImg from '../assets/edgecontrol.svg?url';
6
6
  import rotateImg from '../assets/rotateicon.svg?url';
7
- import type { IEditor, IPluginTempl } from '@hprint/core';
7
+ import type { IEditor, IPluginOption, IPluginTempl } from '@hprint/core';
8
+
9
+ interface ControlsPluginOptions extends IPluginOption {
10
+ /** 是否禁用多选对象的整体缩放,默认保留 Fabric 的缩放能力。 */
11
+ disableActiveSelectionScaling?: boolean;
12
+ }
8
13
 
9
14
  /**
10
15
  * 实际场景: 在进行某个对象缩放的时候,由于fabricjs默认精度使用的是toFixed(2)。
@@ -224,13 +229,14 @@ function rotationControl() {
224
229
  });
225
230
  }
226
231
 
227
- class ControlsPlugin implements IPluginTempl {
228
- static pluginName = 'ControlsPlugin';
229
- constructor(
230
- public canvas: fabric.Canvas,
231
- public editor: IEditor
232
- ) {
233
- this.init();
232
+ class ControlsPlugin implements IPluginTempl {
233
+ static pluginName = 'ControlsPlugin';
234
+ constructor(
235
+ public canvas: fabric.Canvas,
236
+ public editor: IEditor,
237
+ private options: ControlsPluginOptions = {}
238
+ ) {
239
+ this.init();
234
240
  }
235
241
  init() {
236
242
  // 删除图标
@@ -274,7 +280,39 @@ class ControlsPlugin implements IPluginTempl {
274
280
  /**
275
281
  * 自定义多选控制点,添加白色填充并确保在边框上方
276
282
  */
277
- customizeActiveSelection() {
283
+ customizeActiveSelection() {
284
+ const shouldDisableActiveSelectionScaling =
285
+ this.options.disableActiveSelectionScaling === true;
286
+ const scaleControlVisibility = {
287
+ tl: false,
288
+ tr: false,
289
+ bl: false,
290
+ br: false,
291
+ ml: false,
292
+ mr: false,
293
+ mt: false,
294
+ mb: false,
295
+ };
296
+
297
+ const disableActiveSelectionScaling = (target?: fabric.Object) => {
298
+ if (!shouldDisableActiveSelectionScaling) return;
299
+
300
+ const activeObject = target || this.canvas.getActiveObject();
301
+ if (!activeObject || activeObject.type !== 'activeSelection') return;
302
+
303
+ if (!activeObject.lockScalingX || !activeObject.lockScalingY) {
304
+ activeObject.set({
305
+ lockScalingX: true,
306
+ lockScalingY: true,
307
+ });
308
+ }
309
+ Object.entries(scaleControlVisibility).forEach(([key, visible]) => {
310
+ if (activeObject.isControlVisible(key) !== visible) {
311
+ activeObject.setControlVisible(key, visible);
312
+ }
313
+ });
314
+ };
315
+
278
316
  // 自定义控制点渲染函数
279
317
  const renderCircleControl = (
280
318
  ctx: CanvasRenderingContext2D,
@@ -326,25 +364,37 @@ class ControlsPlugin implements IPluginTempl {
326
364
  }
327
365
  });
328
366
 
329
- // 应用样式配置
330
- fabric.ActiveSelection.prototype.set(CONTROL_STYLES);
367
+ // hprint 默认保留多选缩放;由业务方按编辑器实例决定是否关闭。
368
+ fabric.ActiveSelection.prototype.set(CONTROL_STYLES);
369
+ if (shouldDisableActiveSelectionScaling) {
370
+ this.canvas.on('selection:created', (e: any) => {
371
+ disableActiveSelectionScaling(e.target);
372
+ });
373
+ this.canvas.on('selection:updated', (e: any) => {
374
+ disableActiveSelectionScaling(e.target);
375
+ });
376
+ // 覆盖鼠标框选和代码创建 ActiveSelection 未经过选择事件的情况。
377
+ this.canvas.on('before:render', () => {
378
+ disableActiveSelectionScaling();
379
+ });
380
+ }
331
381
 
332
- // 跟踪是否正在移动或缩放对象
333
- let isTransforming = false;
382
+ // 跟踪是否正在移动、缩放或旋转对象
383
+ let isTransforming = false;
334
384
 
335
385
  // 监听对象移动开始
336
- this.canvas.on('object:moving', (e: any) => {
386
+ this.canvas.on('object:moving', (e: any) => {
337
387
  if (e.target && e.target.type === 'activeSelection') {
338
388
  isTransforming = true;
339
389
  }
340
- });
341
-
342
- // 监听对象缩放开始
343
- this.canvas.on('object:scaling', (e: any) => {
344
- if (e.target && e.target.type === 'activeSelection') {
345
- isTransforming = true;
346
- }
347
- });
390
+ });
391
+
392
+ // 未关闭多选缩放时,缩放期间不重复绘制控制点。
393
+ this.canvas.on('object:scaling', (e: any) => {
394
+ if (e.target && e.target.type === 'activeSelection') {
395
+ isTransforming = true;
396
+ }
397
+ });
348
398
 
349
399
  // 监听对象旋转开始
350
400
  this.canvas.on('object:rotating', (e: any) => {
@@ -371,7 +421,7 @@ class ControlsPlugin implements IPluginTempl {
371
421
 
372
422
  // 监听canvas的after:render事件,在所有内容渲染完成后额外绘制多选控制点
373
423
  this.canvas.on('after:render', () => {
374
- // 如果正在变换(移动、缩放、旋转),不绘制控制点
424
+ // 如果正在变换(移动、旋转),不绘制控制点
375
425
  if (isTransforming) return;
376
426
 
377
427
  const activeObject = this.canvas.getActiveObject();
@@ -314,7 +314,7 @@ class CreateElementPlugin implements IPluginTempl {
314
314
  }
315
315
  return originalSet(key, value);
316
316
  };
317
- (obj as any).syncOriginSizeByUnit = function (fieldsOrDpi?: any, dpi?: number) {
317
+ (obj as any).syncOriginSizeByUnit = function (fieldsOrDpi?: any, dpi?: number) {
318
318
  const unit = getUnit(editorRef);
319
319
  if (unit === 'px') return;
320
320
  const hasFieldsArray = Array.isArray(fieldsOrDpi);
@@ -325,10 +325,10 @@ class CreateElementPlugin implements IPluginTempl {
325
325
  const isLineObject = (this as any).type === 'line' || (this as any).type === 'arrow' || (this as any).type === 'thinTailArrow';
326
326
  const targetFields: string[] =
327
327
  hasFieldsArray && (fieldsOrDpi as string[])?.length ? (fieldsOrDpi as string[]) : singleFields;
328
- targetFields.forEach((field) => {
329
- if (field === 'points') return;
330
- let currentVal: number | undefined;
331
- if (isImageObject && (field === 'width' || field === 'height')) {
328
+ targetFields.forEach((field) => {
329
+ if (field === 'points') return;
330
+ let currentVal: number | undefined;
331
+ if (isImageObject && (field === 'width' || field === 'height')) {
332
332
  if (field === 'width') {
333
333
  currentVal = (this as any).getScaledWidth?.();
334
334
  } else {