@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.
- package/dist/index.js +34 -34
- package/dist/index.mjs +4609 -4577
- 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/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 +95 -95
- package/src/plugins/ControlsPlugin.ts +73 -23
- package/src/plugins/CreateElementPlugin.ts +5 -5
- package/src/plugins/GroupAlignPlugin.ts +59 -37
- package/src/plugins/UnitPlugin.ts +48 -15
- package/src/utils/units.ts +5 -5
|
@@ -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() {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { IEditor, IPluginTempl } from '@hprint/core';
|
|
2
|
-
import { LengthConvert } from '@hprint/shared';
|
|
3
|
-
import {
|
|
4
|
-
import { fabric } from '@hprint/core';
|
|
1
|
+
import type { IEditor, IPluginTempl } from '@hprint/core';
|
|
2
|
+
import { LengthConvert } from '@hprint/shared';
|
|
3
|
+
import { fabric } from '@hprint/core';
|
|
5
4
|
import { throttle } from 'lodash-es';
|
|
6
5
|
|
|
7
6
|
type IPlugin = Pick<
|
|
@@ -305,14 +304,17 @@ class UnitPlugin implements IPluginTempl {
|
|
|
305
304
|
}
|
|
306
305
|
}
|
|
307
306
|
|
|
308
|
-
_bindEvents() {
|
|
309
|
-
const throttledSync = throttle((obj: fabric.Object) => {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
307
|
+
_bindEvents() {
|
|
308
|
+
const throttledSync = throttle((obj: fabric.Object) => {
|
|
309
|
+
// 多选坐标只需在 object:modified 时同步,避免拖动过程中反复创建计算对象。
|
|
310
|
+
if (obj.type !== 'activeSelection') {
|
|
311
|
+
(obj as any).syncOriginSizeByUnit?.();
|
|
312
|
+
}
|
|
313
|
+
}, 30);
|
|
314
|
+
|
|
315
|
+
this.canvas.on('object:modified', (e: any) => {
|
|
316
|
+
const target = e.target as fabric.Object | undefined;
|
|
317
|
+
if (target) this._syncTargetOriginSize(target);
|
|
316
318
|
});
|
|
317
319
|
|
|
318
320
|
this.canvas.on('object:moving', (e: any) => {
|
|
@@ -330,15 +332,46 @@ class UnitPlugin implements IPluginTempl {
|
|
|
330
332
|
if (target) throttledSync(target);
|
|
331
333
|
});
|
|
332
334
|
|
|
333
|
-
this.editor.on?.('sizeChange', (event: { width: number, height: number }) => {
|
|
335
|
+
this.editor.on?.('sizeChange', (event: { width: number, height: number }) => {
|
|
334
336
|
const unit = this.getUnit();
|
|
335
337
|
if (unit === 'px') return;
|
|
336
338
|
if (unit === 'mm') {
|
|
337
339
|
this._syncOriginSize(event.width, event.height);
|
|
338
340
|
return
|
|
339
341
|
}
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
_syncTargetOriginSize(target: fabric.Object) {
|
|
346
|
+
if (target.type !== 'activeSelection') {
|
|
347
|
+
(target as any).syncOriginSizeByUnit?.();
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// 将 ActiveSelection 的平移和旋转真正应用到每个子元素。
|
|
352
|
+
// 之后重新创建选区,避免子元素继续保留相对于旧选区的坐标。
|
|
353
|
+
const objects = (target as fabric.ActiveSelection).getObjects();
|
|
354
|
+
const absoluteAngles = new Map<fabric.Object, number>();
|
|
355
|
+
objects.forEach((item: fabric.Object) => {
|
|
356
|
+
// item.angle 在 ActiveSelection 内是相对角度。必须先通过完整变换矩阵
|
|
357
|
+
// 取得画布上的绝对角度,再销毁选区并写回子元素。
|
|
358
|
+
const { angle } = fabric.util.qrDecompose(item.calcTransformMatrix());
|
|
359
|
+
absoluteAngles.set(item, ((angle % 360) + 360) % 360);
|
|
360
|
+
});
|
|
361
|
+
this.canvas.discardActiveObject();
|
|
362
|
+
objects.forEach((item: fabric.Object) => {
|
|
363
|
+
item.set('angle', absoluteAngles.get(item) ?? 0);
|
|
364
|
+
item.setCoords();
|
|
365
|
+
// 仅同步位置;旋转角度已由 ActiveSelection 变换写回 item.angle。
|
|
366
|
+
(item as any).syncOriginSizeByUnit?.(['left', 'top']);
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
const normalizedSelection = new fabric.ActiveSelection(objects, {
|
|
370
|
+
canvas: this.canvas,
|
|
371
|
+
});
|
|
372
|
+
this.canvas.setActiveObject(normalizedSelection);
|
|
373
|
+
this.canvas.requestRenderAll();
|
|
374
|
+
}
|
|
342
375
|
|
|
343
376
|
destroy() {
|
|
344
377
|
console.log('pluginDestroy');
|
package/src/utils/units.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function applyMmToObject(
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export function syncMmFromObject(obj: fabric.Object, dpi?: number, precision?: number) {
|
|
52
|
+
export function syncMmFromObject(obj: fabric.Object, dpi?: number, precision?: number) {
|
|
53
53
|
const isImage = obj.type === 'image';
|
|
54
54
|
const toMm = (v: number | undefined) =>
|
|
55
55
|
v === undefined ? undefined : applyPrecision(LengthConvert.pxToMm(v, dpi), precision);
|
|
@@ -76,10 +76,10 @@ export function syncMmFromObject(obj: fabric.Object, dpi?: number, precision?: n
|
|
|
76
76
|
strokeWidth: toMm(strokeWidth),
|
|
77
77
|
fontSize: toMm(fontSize),
|
|
78
78
|
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export type UnitType = 'px' | 'mm' | 'inch';
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type UnitType = 'px' | 'mm' | 'inch';
|
|
83
83
|
|
|
84
84
|
export function getUnit(editor: IEditor): UnitType {
|
|
85
85
|
return (editor as any).getUnit?.() ?? 'px';
|