@hprint/plugins 0.0.1-alpha.1 → 0.0.1-alpha.2
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/dist/index.js +122 -117
- package/dist/index.mjs +41243 -21115
- package/dist/src/plugins/BarCodePlugin.d.ts +4 -0
- package/dist/src/plugins/BarCodePlugin.d.ts.map +1 -1
- package/dist/src/plugins/CreateElementPlugin.d.ts +3 -9
- package/dist/src/plugins/CreateElementPlugin.d.ts.map +1 -1
- package/dist/src/plugins/QrCodePlugin.d.ts +14 -97
- package/dist/src/plugins/QrCodePlugin.d.ts.map +1 -1
- package/dist/src/plugins/ResizePlugin.d.ts.map +1 -1
- package/dist/src/plugins/UnitPlugin.d.ts.map +1 -1
- package/dist/src/plugins/WorkspacePlugin.d.ts.map +1 -1
- package/dist/src/utils/units.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/plugins/BarCodePlugin.ts +33 -27
- package/src/plugins/CreateElementPlugin.ts +14 -10
- package/src/plugins/QrCodePlugin.ts +85 -149
- package/src/plugins/ResizePlugin.ts +5 -1
- package/src/plugins/UnitPlugin.ts +2 -3
- package/src/plugins/WorkspacePlugin.ts +10 -6
- package/src/utils/units.ts +4 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { fabric } from '@hprint/core';
|
|
2
|
-
import
|
|
2
|
+
import bwipjs from 'bwip-js';
|
|
3
3
|
import { utils } from '@hprint/shared';
|
|
4
4
|
import { getUnit, processOptions, formatOriginValues } from '../utils/units';
|
|
5
5
|
import type { IEditor, IPluginTempl } from '@hprint/core';
|
|
6
6
|
|
|
7
|
-
type IPlugin = Pick<QrCodePlugin, 'addQrCode' | 'setQrCode'
|
|
7
|
+
type IPlugin = Pick<QrCodePlugin, 'addQrCode' | 'setQrCode'>;
|
|
8
8
|
|
|
9
9
|
declare module '@hprint/core' {
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
@@ -45,30 +45,12 @@ class QrParamsDefaults {
|
|
|
45
45
|
height = 300;
|
|
46
46
|
type = 'canvas' as const;
|
|
47
47
|
data = ' ';
|
|
48
|
-
|
|
49
|
-
qrOptions = {
|
|
50
|
-
errorCorrectionLevel: 'M' as const,
|
|
51
|
-
};
|
|
52
|
-
dotsOptions = {
|
|
53
|
-
color: '#000000',
|
|
54
|
-
type: 'square' as const,
|
|
55
|
-
};
|
|
56
|
-
cornersSquareOptions = {
|
|
57
|
-
color: '#000000',
|
|
58
|
-
type: 'square' as const,
|
|
59
|
-
};
|
|
60
|
-
cornersDotOptions = {
|
|
61
|
-
color: '#000000',
|
|
62
|
-
type: 'square' as const,
|
|
63
|
-
};
|
|
64
|
-
backgroundOptions = {
|
|
65
|
-
color: '#ffffff',
|
|
66
|
-
};
|
|
48
|
+
ecLevel = 'M' as const;
|
|
67
49
|
}
|
|
68
50
|
|
|
69
51
|
class QrCodePlugin implements IPluginTempl {
|
|
70
52
|
static pluginName = 'QrCodePlugin';
|
|
71
|
-
static apis = ['addQrCode', 'setQrCode'
|
|
53
|
+
static apis = ['addQrCode', 'setQrCode'];
|
|
72
54
|
constructor(
|
|
73
55
|
public canvas: fabric.Canvas,
|
|
74
56
|
public editor: IEditor
|
|
@@ -82,40 +64,50 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
82
64
|
}
|
|
83
65
|
}
|
|
84
66
|
|
|
67
|
+
async hookTransformObjectEnd({ originObject, fabricObject }: { originObject: any, fabricObject: any }) {
|
|
68
|
+
if (originObject.extensionType === 'qrcode') {
|
|
69
|
+
this._bindQrCodeEvents(fabricObject);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
85
73
|
async _getBase64Str(options: any): Promise<string> {
|
|
86
74
|
const zoom = this.canvas.getZoom() || 1;
|
|
87
75
|
const dpr = (window && (window as any).devicePixelRatio) || 1;
|
|
88
|
-
let scale = zoom * dpr;
|
|
89
|
-
const maxScale = 4;
|
|
90
|
-
if (!Number.isFinite(scale) || scale <= 0) scale = 1;
|
|
91
|
-
scale = Math.min(scale, maxScale);
|
|
92
76
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
77
|
+
const targetWidth = (options.width || 300) * zoom * dpr;
|
|
78
|
+
// 估算 module 数量,QR Code 通常在 21-177 之间,取一个中间值作为估算基础
|
|
79
|
+
const estimatedModules = 35;
|
|
80
|
+
let bwipScale = Math.ceil(targetWidth / estimatedModules);
|
|
81
|
+
if (bwipScale < 2) bwipScale = 2;
|
|
82
|
+
|
|
83
|
+
const canvas = document.createElement('canvas');
|
|
84
|
+
|
|
85
|
+
const barColor = options.color?.replace('#', '') || '000000';
|
|
86
|
+
const bgColor = options.bgColor?.replace('#', '') || 'ffffff';
|
|
87
|
+
const ecLevel = options.ecLevel || 'M';
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
bwipjs.toCanvas(canvas, {
|
|
91
|
+
bcid: 'qrcode',
|
|
92
|
+
text: options.data || ' ',
|
|
93
|
+
scale: bwipScale,
|
|
94
|
+
eclevel: ecLevel,
|
|
95
|
+
barcolor: barColor,
|
|
96
|
+
backgroundcolor: bgColor,
|
|
97
|
+
} as any);
|
|
98
|
+
return canvas.toDataURL('image/png');
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('QR Code generation failed:', error);
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
104
103
|
}
|
|
105
104
|
|
|
106
105
|
_defaultBarcodeOption() {
|
|
107
106
|
return {
|
|
108
|
-
value: '
|
|
107
|
+
value: '@hprint/print',
|
|
109
108
|
width: 300,
|
|
110
109
|
margin: 10,
|
|
111
|
-
|
|
112
|
-
dotsColor: '#000000',
|
|
113
|
-
dotsType: 'square',
|
|
114
|
-
cornersSquareColor: '#000000',
|
|
115
|
-
cornersSquareType: 'square',
|
|
116
|
-
cornersDotColor: '#000000',
|
|
117
|
-
cornersDotType: 'square',
|
|
118
|
-
background: '#ffffff',
|
|
110
|
+
ecLevel: 'M',
|
|
119
111
|
};
|
|
120
112
|
}
|
|
121
113
|
|
|
@@ -128,43 +120,15 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
128
120
|
const size = hasW && hasH
|
|
129
121
|
? Math.max(option.width, option.height)
|
|
130
122
|
: (hasW ? option.width : (hasH ? option.height : undefined));
|
|
131
|
-
const
|
|
123
|
+
const options = {
|
|
124
|
+
...option,
|
|
132
125
|
width: size,
|
|
133
126
|
height: size ?? option.width,
|
|
134
127
|
type: 'canvas',
|
|
135
128
|
data: option.value != null ? String(option.value) : undefined,
|
|
136
129
|
margin: option.margin,
|
|
137
|
-
qrOptions: {
|
|
138
|
-
errorCorrectionLevel: option.errorCorrectionLevel,
|
|
139
|
-
},
|
|
140
|
-
dotsOptions: {
|
|
141
|
-
color: option.dotsColor,
|
|
142
|
-
type: option.dotsType,
|
|
143
|
-
},
|
|
144
|
-
cornersSquareOptions: {
|
|
145
|
-
color: option.cornersSquareColor,
|
|
146
|
-
type: option.cornersSquareType,
|
|
147
|
-
},
|
|
148
|
-
cornersDotOptions: {
|
|
149
|
-
color: option.cornersDotColor,
|
|
150
|
-
type: option.cornersDotType,
|
|
151
|
-
},
|
|
152
|
-
backgroundOptions: {
|
|
153
|
-
color: option.background,
|
|
154
|
-
},
|
|
155
130
|
};
|
|
156
|
-
|
|
157
|
-
const merged = Object.assign({}, defaultParams, base);
|
|
158
|
-
merged.qrOptions = Object.assign({}, defaultParams.qrOptions, base.qrOptions);
|
|
159
|
-
merged.dotsOptions = Object.assign({}, defaultParams.dotsOptions, base.dotsOptions);
|
|
160
|
-
merged.cornersSquareOptions = Object.assign({}, defaultParams.cornersSquareOptions, base.cornersSquareOptions);
|
|
161
|
-
merged.cornersDotOptions = Object.assign({}, defaultParams.cornersDotOptions, base.cornersDotOptions);
|
|
162
|
-
merged.backgroundOptions = Object.assign({}, defaultParams.backgroundOptions, base.backgroundOptions);
|
|
163
|
-
|
|
164
|
-
if (!merged.data || (typeof merged.data === 'string' && merged.data.trim() === '')) {
|
|
165
|
-
merged.data = defaultParams.data;
|
|
166
|
-
}
|
|
167
|
-
return merged;
|
|
131
|
+
return options;
|
|
168
132
|
}
|
|
169
133
|
|
|
170
134
|
private async _updateQrCodeImage(imgEl: fabric.Image, immediate = false) {
|
|
@@ -221,6 +185,44 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
221
185
|
}
|
|
222
186
|
}
|
|
223
187
|
|
|
188
|
+
/**
|
|
189
|
+
* 绑定二维码相关事件与方法
|
|
190
|
+
*/
|
|
191
|
+
private _bindQrCodeEvents(imgEl: fabric.Image) {
|
|
192
|
+
(imgEl as any).setExtension = async (fields: Record<string, any>) => {
|
|
193
|
+
const currentExt = (imgEl.get('extension') as any) || {};
|
|
194
|
+
const merged = { ...currentExt, ...(fields || {}) };
|
|
195
|
+
imgEl.set('extension', merged);
|
|
196
|
+
await this._updateQrCodeImage(imgEl, true);
|
|
197
|
+
};
|
|
198
|
+
(imgEl as any).setExtensionByUnit = async (
|
|
199
|
+
fields: Record<string, any>,
|
|
200
|
+
dpi?: number
|
|
201
|
+
) => {
|
|
202
|
+
const curUnit = getUnit(this.editor);
|
|
203
|
+
const { processed, originByUnit } = processOptions(fields || {}, curUnit, dpi);
|
|
204
|
+
const precision = (this.editor as any).getPrecision?.();
|
|
205
|
+
const formattedOrigin = formatOriginValues(originByUnit[curUnit] || {}, precision);
|
|
206
|
+
const originSize = (imgEl as any)._originSize || {};
|
|
207
|
+
const unitOrigin = originSize[curUnit] || {};
|
|
208
|
+
unitOrigin.extension = { ...(unitOrigin.extension || {}), ...formattedOrigin };
|
|
209
|
+
(imgEl as any)._originSize = { ...originSize, [curUnit]: unitOrigin };
|
|
210
|
+
const currentExt = (imgEl.get('extension') as any) || {};
|
|
211
|
+
const merged = { ...currentExt, ...processed };
|
|
212
|
+
imgEl.set('extension', merged);
|
|
213
|
+
await this._updateQrCodeImage(imgEl, true);
|
|
214
|
+
};
|
|
215
|
+
(imgEl as any).off?.('modified');
|
|
216
|
+
(imgEl as any).off?.('scaled');
|
|
217
|
+
imgEl.on('modified', async (event: any) => {
|
|
218
|
+
const target = (event?.target as fabric.Image) || imgEl;
|
|
219
|
+
await this._updateQrCodeImage(target, true);
|
|
220
|
+
});
|
|
221
|
+
imgEl.on('scaled', async () => {
|
|
222
|
+
await this._updateQrCodeImage(imgEl, true);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
224
226
|
/**
|
|
225
227
|
* 创建二维码,支持传入内容与样式,进行单位转换并存储原始尺寸
|
|
226
228
|
*/
|
|
@@ -231,15 +233,9 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
231
233
|
top?: number;
|
|
232
234
|
width?: number;
|
|
233
235
|
height?: number;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
dotsType?: string;
|
|
238
|
-
cornersSquareColor?: string;
|
|
239
|
-
cornersSquareType?: string;
|
|
240
|
-
cornersDotColor?: string;
|
|
241
|
-
cornersDotType?: string;
|
|
242
|
-
background?: string;
|
|
236
|
+
ecLevel?: 'L' | 'M' | 'Q' | 'H';
|
|
237
|
+
color: string;
|
|
238
|
+
bgColor: string;
|
|
243
239
|
},
|
|
244
240
|
dpi?: number
|
|
245
241
|
): Promise<fabric.Image> {
|
|
@@ -250,19 +246,7 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
250
246
|
};
|
|
251
247
|
const unit = getUnit(this.editor);
|
|
252
248
|
const { processed, originByUnit } = processOptions(option, unit, dpi, ['left', 'top', 'width', 'height', 'margin']);
|
|
253
|
-
const
|
|
254
|
-
const finalOption = {
|
|
255
|
-
...finalOptionBase,
|
|
256
|
-
width: Number.isFinite(finalOptionBase.width) && finalOptionBase.width > 0
|
|
257
|
-
? finalOptionBase.width
|
|
258
|
-
: this._defaultBarcodeOption().width,
|
|
259
|
-
height: Number.isFinite(finalOptionBase.height) && finalOptionBase.height > 0
|
|
260
|
-
? finalOptionBase.height
|
|
261
|
-
: finalOptionBase.width,
|
|
262
|
-
margin: Number.isFinite(finalOptionBase.margin) && finalOptionBase.margin >= 0
|
|
263
|
-
? finalOptionBase.margin
|
|
264
|
-
: this._defaultBarcodeOption().margin,
|
|
265
|
-
};
|
|
249
|
+
const finalOption = { ...option, ...processed };
|
|
266
250
|
const paramsOption = this._paramsToOption(finalOption);
|
|
267
251
|
const url = await this._getBase64Str(paramsOption);
|
|
268
252
|
return new Promise<fabric.Image>((resolve) => {
|
|
@@ -302,38 +286,7 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
302
286
|
originMapped.height = originMapped.width;
|
|
303
287
|
}
|
|
304
288
|
(imgEl as any)._originSize = { [unit]: originMapped };
|
|
305
|
-
(imgEl
|
|
306
|
-
const currentExt = (imgEl.get('extension') as any) || {};
|
|
307
|
-
const merged = { ...currentExt, ...(fields || {}) };
|
|
308
|
-
imgEl.set('extension', merged);
|
|
309
|
-
await this._updateQrCodeImage(imgEl, true);
|
|
310
|
-
};
|
|
311
|
-
(imgEl as any).setExtensionByUnit = async (
|
|
312
|
-
fields: Record<string, any>,
|
|
313
|
-
dpi?: number
|
|
314
|
-
) => {
|
|
315
|
-
const curUnit = getUnit(this.editor);
|
|
316
|
-
const { processed, originByUnit } = processOptions(fields || {}, curUnit, dpi);
|
|
317
|
-
const precision = (this.editor as any).getPrecision?.();
|
|
318
|
-
const formattedOrigin = formatOriginValues(originByUnit[curUnit] || {}, precision);
|
|
319
|
-
const originSize = (imgEl as any)._originSize || {};
|
|
320
|
-
const unitOrigin = originSize[curUnit] || {};
|
|
321
|
-
unitOrigin.extension = { ...(unitOrigin.extension || {}), ...formattedOrigin };
|
|
322
|
-
(imgEl as any)._originSize = { ...originSize, [curUnit]: unitOrigin };
|
|
323
|
-
const currentExt = (imgEl.get('extension') as any) || {};
|
|
324
|
-
const merged = { ...currentExt, ...processed };
|
|
325
|
-
imgEl.set('extension', merged);
|
|
326
|
-
await this._updateQrCodeImage(imgEl, true);
|
|
327
|
-
};
|
|
328
|
-
(imgEl as any).off?.('modified');
|
|
329
|
-
(imgEl as any).off?.('scaled');
|
|
330
|
-
imgEl.on('modified', async (event: any) => {
|
|
331
|
-
const target = (event?.target as fabric.Image) || imgEl;
|
|
332
|
-
await this._updateQrCodeImage(target, true);
|
|
333
|
-
});
|
|
334
|
-
imgEl.on('scaled', async () => {
|
|
335
|
-
await this._updateQrCodeImage(imgEl, true);
|
|
336
|
-
});
|
|
289
|
+
this._bindQrCodeEvents(imgEl);
|
|
337
290
|
resolve(imgEl);
|
|
338
291
|
},
|
|
339
292
|
{ crossOrigin: 'anonymous' }
|
|
@@ -356,15 +309,7 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
356
309
|
extension: { ...option },
|
|
357
310
|
});
|
|
358
311
|
imgEl.scaleToWidth(activeObject.getScaledWidth());
|
|
359
|
-
|
|
360
|
-
imgEl.off('scaled');
|
|
361
|
-
imgEl.on('modified', async (event: any) => {
|
|
362
|
-
const target = (event?.target as fabric.Image) || imgEl;
|
|
363
|
-
await this._updateQrCodeImage(target, true);
|
|
364
|
-
});
|
|
365
|
-
imgEl.on('scaled', async () => {
|
|
366
|
-
await this._updateQrCodeImage(imgEl, true);
|
|
367
|
-
});
|
|
312
|
+
this._bindQrCodeEvents(imgEl);
|
|
368
313
|
this.editor.del();
|
|
369
314
|
this.canvas.add(imgEl);
|
|
370
315
|
this.canvas.setActiveObject(imgEl);
|
|
@@ -376,15 +321,6 @@ class QrCodePlugin implements IPluginTempl {
|
|
|
376
321
|
}
|
|
377
322
|
}
|
|
378
323
|
|
|
379
|
-
getQrCodeTypes() {
|
|
380
|
-
return {
|
|
381
|
-
DotsType: Object.values(DotsType),
|
|
382
|
-
CornersType: Object.values(CornersType),
|
|
383
|
-
cornersDotType: Object.values(cornersDotType),
|
|
384
|
-
errorCorrectionLevelType: Object.values(errorCorrectionLevelType),
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
324
|
destroy() {
|
|
389
325
|
console.log('pluginDestroy');
|
|
390
326
|
}
|
|
@@ -244,7 +244,11 @@ class ResizePlugin implements IPluginTempl {
|
|
|
244
244
|
if (this.editor.getUnit() !== 'px') {
|
|
245
245
|
({ width: curUnitWidth, height: curUnitHeight } = this.editor.getOriginSize());
|
|
246
246
|
}
|
|
247
|
-
this.editor.emit('sizeChange', {
|
|
247
|
+
this.editor.emit('sizeChange', {
|
|
248
|
+
width: this.editor.getSizeByUnit(curUnitWidth),
|
|
249
|
+
height: this.editor.getSizeByUnit(curUnitHeight),
|
|
250
|
+
unit: this.editor.getUnit()
|
|
251
|
+
});
|
|
248
252
|
}
|
|
249
253
|
}
|
|
250
254
|
|
|
@@ -218,13 +218,13 @@ class UnitPlugin implements IPluginTempl {
|
|
|
218
218
|
setSizeByUnit(width: number, height: number, options: { dpi: number, slient?: boolean }) {
|
|
219
219
|
const unit = (this.editor as any).getUnit?.() || 'px';
|
|
220
220
|
if (unit === 'mm') {
|
|
221
|
-
return this.setSizeMm(width, height, options
|
|
221
|
+
return this.setSizeMm(width, height, options?.dpi);
|
|
222
222
|
}
|
|
223
223
|
if (unit === 'inch') {
|
|
224
224
|
this._syncOriginSize(width, height);
|
|
225
225
|
const wmm = width * LengthConvert.CONSTANTS.INCH_TO_MM;
|
|
226
226
|
const hmm = height * LengthConvert.CONSTANTS.INCH_TO_MM;
|
|
227
|
-
return this.setSizeMm(wmm, hmm, options
|
|
227
|
+
return this.setSizeMm(wmm, hmm, options?.dpi);
|
|
228
228
|
}
|
|
229
229
|
this.editor.setSize(width, height, { slient: options.slient });
|
|
230
230
|
}
|
|
@@ -240,7 +240,6 @@ class UnitPlugin implements IPluginTempl {
|
|
|
240
240
|
height: this.canvas.getHeight(),
|
|
241
241
|
};
|
|
242
242
|
}
|
|
243
|
-
|
|
244
243
|
const ensureMmWidth = originMm.width !== undefined
|
|
245
244
|
? originMm.width
|
|
246
245
|
: LengthConvert.pxToMm(this.canvas.getWidth(), dpi, { direct: true });
|
|
@@ -91,9 +91,11 @@ class WorkspacePlugin implements IPluginTempl {
|
|
|
91
91
|
if (workspace.width && workspace.height) {
|
|
92
92
|
this.setSize(workspace.width, workspace.height);
|
|
93
93
|
this.editor.emit(
|
|
94
|
-
'sizeChange',
|
|
95
|
-
workspace.width,
|
|
96
|
-
workspace.height
|
|
94
|
+
'sizeChange', {
|
|
95
|
+
width: this.editor.getSizeByUnit(workspace.width),
|
|
96
|
+
height: this.editor.getSizeByUnit(workspace.height),
|
|
97
|
+
unit: this.editor.getUnit(),
|
|
98
|
+
}
|
|
97
99
|
);
|
|
98
100
|
}
|
|
99
101
|
}
|
|
@@ -194,9 +196,11 @@ class WorkspacePlugin implements IPluginTempl {
|
|
|
194
196
|
this.workspace.set('width', width);
|
|
195
197
|
this.workspace.set('height', height);
|
|
196
198
|
options?.slient !== true && this.editor.emit(
|
|
197
|
-
'sizeChange',
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
199
|
+
'sizeChange', {
|
|
200
|
+
width: this.editor.getSizeByUnit(width),
|
|
201
|
+
height: this.editor.getSizeByUnit(height),
|
|
202
|
+
unit: this.editor.getUnit(),
|
|
203
|
+
}
|
|
200
204
|
);
|
|
201
205
|
this.auto();
|
|
202
206
|
}
|
package/src/utils/units.ts
CHANGED
|
@@ -45,12 +45,14 @@ export function applyMmToObject(
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export function syncMmFromObject(obj: fabric.Object, dpi?: number, precision?: number) {
|
|
48
|
+
const isImage = obj.type === 'image';
|
|
48
49
|
const toMm = (v: number | undefined) =>
|
|
49
50
|
v === undefined ? undefined : applyPrecision(LengthConvert.pxToMm(v, dpi), precision);
|
|
50
51
|
const left = obj.left as number | undefined;
|
|
51
52
|
const top = obj.top as number | undefined;
|
|
52
|
-
|
|
53
|
-
const
|
|
53
|
+
// 图片的width是图片的实际宽度,应取在画布中绘制用的宽度obj.getScaledWidth()
|
|
54
|
+
const width = isImage ? obj.getScaledWidth() : obj.width as number | undefined;
|
|
55
|
+
const height = isImage ? obj.getScaledHeight() : obj.height as number | undefined;
|
|
54
56
|
const strokeWidth = obj.strokeWidth as number | undefined;
|
|
55
57
|
const fontSize = (obj as any).fontSize as number | undefined;
|
|
56
58
|
|