@hprint/plugins 0.0.9-alpha.0 → 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.
- package/dist/index.js +34 -34
- package/dist/index.mjs +4710 -4618
- package/dist/src/plugins/ActualContentLayoutPlugin.d.ts +3 -0
- package/dist/src/plugins/ActualContentLayoutPlugin.d.ts.map +1 -1
- package/dist/src/plugins/ControlsPlugin.d.ts +7 -2
- package/dist/src/plugins/ControlsPlugin.d.ts.map +1 -1
- package/dist/src/plugins/GroupAlignPlugin.d.ts +2 -0
- package/dist/src/plugins/GroupAlignPlugin.d.ts.map +1 -1
- package/dist/src/plugins/HistoryPlugin.d.ts +1 -0
- package/dist/src/plugins/HistoryPlugin.d.ts.map +1 -1
- package/dist/src/plugins/ImageTextListPlugin.d.ts.map +1 -1
- package/dist/src/plugins/QrCodePlugin.d.ts +1 -0
- package/dist/src/plugins/QrCodePlugin.d.ts.map +1 -1
- package/dist/src/plugins/UnitPlugin.d.ts +1 -0
- package/dist/src/plugins/UnitPlugin.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/plugins/ActualContentLayoutPlugin.ts +309 -276
- package/src/plugins/ControlsPlugin.ts +73 -23
- package/src/plugins/CreateElementPlugin.ts +5 -5
- package/src/plugins/GroupAlignPlugin.ts +59 -37
- package/src/plugins/HistoryPlugin.ts +52 -12
- package/src/plugins/ImageTextListPlugin.ts +541 -540
- package/src/plugins/QrCodePlugin.ts +33 -15
- package/src/plugins/UnitPlugin.ts +48 -15
- package/src/utils/units.ts +5 -5
|
@@ -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
|
-
|
|
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 {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fabric } from '@hprint/core';
|
|
2
|
-
import type { IEditor, IPluginTempl } from '@hprint/core';
|
|
1
|
+
import { fabric } from '@hprint/core';
|
|
2
|
+
import type { IEditor, IPluginTempl } from '@hprint/core';
|
|
3
3
|
|
|
4
4
|
type IPlugin = Pick<
|
|
5
5
|
GroupAlignPlugin,
|
|
@@ -31,10 +31,22 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
31
31
|
'yequation',
|
|
32
32
|
];
|
|
33
33
|
// public hotkeys: string[] = ['space'];
|
|
34
|
-
constructor(
|
|
35
|
-
public canvas: fabric.Canvas,
|
|
36
|
-
public editor: IEditor
|
|
37
|
-
) { }
|
|
34
|
+
constructor(
|
|
35
|
+
public canvas: fabric.Canvas,
|
|
36
|
+
public editor: IEditor
|
|
37
|
+
) { }
|
|
38
|
+
|
|
39
|
+
_refreshObjectCoordinates(objects: fabric.Object[]) {
|
|
40
|
+
objects.forEach((item) => {
|
|
41
|
+
item.setCoords();
|
|
42
|
+
(item as any).syncOriginSizeByUnit?.(['left', 'top']);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_notifySelectionModified(selection: fabric.ActiveSelection) {
|
|
47
|
+
this.canvas.fire('object:modified', { target: selection });
|
|
48
|
+
this.canvas.requestRenderAll();
|
|
49
|
+
}
|
|
38
50
|
|
|
39
51
|
left() {
|
|
40
52
|
const { canvas } = this;
|
|
@@ -51,15 +63,16 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
51
63
|
});
|
|
52
64
|
item.setCoords();
|
|
53
65
|
});
|
|
54
|
-
|
|
66
|
+
this._refreshObjectCoordinates(selectObjects);
|
|
67
|
+
const activeSelection = new fabric.ActiveSelection(selectObjects, {
|
|
55
68
|
canvas: canvas,
|
|
56
69
|
});
|
|
57
70
|
canvas.setActiveObject(activeSelection);
|
|
58
|
-
|
|
71
|
+
this._notifySelectionModified(activeSelection);
|
|
59
72
|
}
|
|
60
73
|
}
|
|
61
74
|
|
|
62
|
-
right() {
|
|
75
|
+
right() {
|
|
63
76
|
const { canvas } = this;
|
|
64
77
|
|
|
65
78
|
const activeObject = canvas.getActiveObject();
|
|
@@ -77,15 +90,16 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
77
90
|
Number(item.left),
|
|
78
91
|
});
|
|
79
92
|
});
|
|
80
|
-
|
|
93
|
+
this._refreshObjectCoordinates(selectObjects);
|
|
94
|
+
const activeSelection = new fabric.ActiveSelection(selectObjects, {
|
|
81
95
|
canvas: canvas,
|
|
82
96
|
});
|
|
83
97
|
canvas.setActiveObject(activeSelection);
|
|
84
|
-
|
|
98
|
+
this._notifySelectionModified(activeSelection);
|
|
85
99
|
}
|
|
86
100
|
}
|
|
87
101
|
|
|
88
|
-
xcenter() {
|
|
102
|
+
xcenter() {
|
|
89
103
|
const { canvas } = this;
|
|
90
104
|
|
|
91
105
|
const activeObject = canvas.getActiveObject();
|
|
@@ -103,15 +117,16 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
103
117
|
Number(item.left),
|
|
104
118
|
});
|
|
105
119
|
});
|
|
106
|
-
|
|
120
|
+
this._refreshObjectCoordinates(selectObjects);
|
|
121
|
+
const activeSelection = new fabric.ActiveSelection(selectObjects, {
|
|
107
122
|
canvas: canvas,
|
|
108
123
|
});
|
|
109
124
|
canvas.setActiveObject(activeSelection);
|
|
110
|
-
|
|
125
|
+
this._notifySelectionModified(activeSelection);
|
|
111
126
|
}
|
|
112
127
|
}
|
|
113
128
|
|
|
114
|
-
ycenter() {
|
|
129
|
+
ycenter() {
|
|
115
130
|
const { canvas } = this;
|
|
116
131
|
|
|
117
132
|
const activeObject = canvas.getActiveObject();
|
|
@@ -129,15 +144,16 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
129
144
|
Number(item.top),
|
|
130
145
|
});
|
|
131
146
|
});
|
|
132
|
-
|
|
147
|
+
this._refreshObjectCoordinates(selectObjects);
|
|
148
|
+
const activeSelection = new fabric.ActiveSelection(selectObjects, {
|
|
133
149
|
canvas: canvas,
|
|
134
150
|
});
|
|
135
151
|
canvas.setActiveObject(activeSelection);
|
|
136
|
-
|
|
152
|
+
this._notifySelectionModified(activeSelection);
|
|
137
153
|
}
|
|
138
154
|
}
|
|
139
155
|
|
|
140
|
-
top() {
|
|
156
|
+
top() {
|
|
141
157
|
const { canvas } = this;
|
|
142
158
|
|
|
143
159
|
const activeObject = canvas.getActiveObject();
|
|
@@ -151,15 +167,16 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
151
167
|
top: top - bounding.top + Number(item.top),
|
|
152
168
|
});
|
|
153
169
|
});
|
|
154
|
-
|
|
170
|
+
this._refreshObjectCoordinates(selectObjects);
|
|
171
|
+
const activeSelection = new fabric.ActiveSelection(selectObjects, {
|
|
155
172
|
canvas: canvas,
|
|
156
173
|
});
|
|
157
174
|
canvas.setActiveObject(activeSelection);
|
|
158
|
-
|
|
175
|
+
this._notifySelectionModified(activeSelection);
|
|
159
176
|
}
|
|
160
177
|
}
|
|
161
178
|
|
|
162
|
-
bottom() {
|
|
179
|
+
bottom() {
|
|
163
180
|
const { canvas } = this;
|
|
164
181
|
|
|
165
182
|
const activeObject = canvas.getActiveObject();
|
|
@@ -177,11 +194,12 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
177
194
|
Number(item.top),
|
|
178
195
|
});
|
|
179
196
|
});
|
|
180
|
-
|
|
197
|
+
this._refreshObjectCoordinates(selectObjects);
|
|
198
|
+
const activeSelection = new fabric.ActiveSelection(selectObjects, {
|
|
181
199
|
canvas: canvas,
|
|
182
200
|
});
|
|
183
201
|
canvas.setActiveObject(activeSelection);
|
|
184
|
-
|
|
202
|
+
this._notifySelectionModified(activeSelection);
|
|
185
203
|
}
|
|
186
204
|
}
|
|
187
205
|
|
|
@@ -256,21 +274,23 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
256
274
|
|
|
257
275
|
const objecs = canvas.getActiveObjects();
|
|
258
276
|
canvas.discardActiveObject();
|
|
259
|
-
objecs.forEach((item: fabric.Object) => {
|
|
260
|
-
let x = Infinity;
|
|
277
|
+
objecs.forEach((item: fabric.Object) => {
|
|
278
|
+
let x = Infinity;
|
|
261
279
|
for (const key in item.aCoords) {
|
|
262
280
|
if (item.aCoords[key].x < x) {
|
|
263
281
|
x = item.aCoords[key].x;
|
|
264
282
|
}
|
|
265
283
|
}
|
|
266
|
-
item.set('left', 2 * item.left - x);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
|
|
284
|
+
item.set('left', 2 * item.left - x);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
this._refreshObjectCoordinates(objecs);
|
|
288
|
+
|
|
289
|
+
const sel = new fabric.ActiveSelection(objecs, {
|
|
270
290
|
canvas: canvas,
|
|
271
291
|
});
|
|
272
292
|
canvas.setActiveObject(sel);
|
|
273
|
-
|
|
293
|
+
this._notifySelectionModified(sel);
|
|
274
294
|
}
|
|
275
295
|
|
|
276
296
|
yequation() {
|
|
@@ -340,21 +360,23 @@ class GroupAlignPlugin implements IPluginTempl {
|
|
|
340
360
|
|
|
341
361
|
const objecs = canvas.getActiveObjects();
|
|
342
362
|
canvas.discardActiveObject();
|
|
343
|
-
objecs.forEach((item) => {
|
|
344
|
-
let y = Infinity;
|
|
363
|
+
objecs.forEach((item) => {
|
|
364
|
+
let y = Infinity;
|
|
345
365
|
for (const key in item.aCoords) {
|
|
346
366
|
if (item.aCoords[key].y < y) {
|
|
347
367
|
y = item.aCoords[key].y;
|
|
348
368
|
}
|
|
349
369
|
}
|
|
350
|
-
item.set('top', 2 * item.top - y);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
|
|
370
|
+
item.set('top', 2 * item.top - y);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
this._refreshObjectCoordinates(objecs);
|
|
374
|
+
|
|
375
|
+
const sel = new fabric.ActiveSelection(objecs, {
|
|
354
376
|
canvas: canvas,
|
|
355
377
|
});
|
|
356
378
|
canvas.setActiveObject(sel);
|
|
357
|
-
|
|
379
|
+
this._notifySelectionModified(sel);
|
|
358
380
|
}
|
|
359
381
|
|
|
360
382
|
destroy() {
|
|
@@ -86,7 +86,11 @@ class HistoryPlugin implements IPluginTempl {
|
|
|
86
86
|
// 加载状态
|
|
87
87
|
private _loadState(state: string, eventName: string, callback?: callback) {
|
|
88
88
|
this.isLoading = true;
|
|
89
|
-
this.isProcessing = true;
|
|
89
|
+
this.isProcessing = true;
|
|
90
|
+
const activeIds = this.canvas
|
|
91
|
+
.getActiveObjects()
|
|
92
|
+
.map((object: any) => object?.id)
|
|
93
|
+
.filter(Boolean);
|
|
90
94
|
|
|
91
95
|
// 处理 workspace 的特殊情况
|
|
92
96
|
const parsedState = JSON.parse(state);
|
|
@@ -97,17 +101,53 @@ class HistoryPlugin implements IPluginTempl {
|
|
|
97
101
|
workspace.evented = false;
|
|
98
102
|
}
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
const hookPromises: Promise<void>[] = [];
|
|
105
|
+
this.canvas.loadFromJSON(
|
|
106
|
+
state,
|
|
107
|
+
() => {
|
|
108
|
+
Promise.all(hookPromises).then(() => {
|
|
109
|
+
this.restoreActiveObjects(activeIds);
|
|
110
|
+
this.canvas.renderAll();
|
|
111
|
+
this.canvas.fire(eventName);
|
|
112
|
+
this.isProcessing = false;
|
|
113
|
+
this.isLoading = false;
|
|
114
|
+
callback?.();
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
(originObject: any, fabricObject: fabric.Object) => {
|
|
118
|
+
hookPromises.push(
|
|
119
|
+
new Promise((resolve) => {
|
|
120
|
+
this.editor.hooksEntity.hookTransformObjectEnd.callAsync(
|
|
121
|
+
{ originObject, fabricObject },
|
|
122
|
+
() => resolve()
|
|
123
|
+
);
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private restoreActiveObjects(activeIds: string[]) {
|
|
131
|
+
this.canvas.discardActiveObject();
|
|
132
|
+
if (!activeIds.length) return;
|
|
133
|
+
|
|
134
|
+
const objects = this.canvas
|
|
135
|
+
.getObjects()
|
|
136
|
+
.filter((object: any) => activeIds.includes(object?.id));
|
|
137
|
+
if (objects.length === 1) {
|
|
138
|
+
this.canvas.setActiveObject(objects[0]);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
if (objects.length > 1) {
|
|
142
|
+
const selection = new fabric.ActiveSelection(objects, {
|
|
143
|
+
canvas: this.canvas,
|
|
144
|
+
});
|
|
145
|
+
this.canvas.setActiveObject(selection);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 获取历史记录状态
|
|
150
|
+
private getState() {
|
|
111
151
|
return {
|
|
112
152
|
undoCount: this.currentIndex - 1,
|
|
113
153
|
redoCount: this.stack.length - this.currentIndex,
|