@leafer-in/editor 1.0.0-rc.3 → 1.0.0-rc.30

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 (41) hide show
  1. package/dist/editor.cjs +1937 -0
  2. package/dist/editor.esm.js +1822 -422
  3. package/dist/editor.esm.min.js +1 -1
  4. package/dist/editor.js +1848 -428
  5. package/dist/editor.min.cjs +1 -0
  6. package/dist/editor.min.js +1 -1
  7. package/package.json +12 -9
  8. package/src/Editor.ts +396 -145
  9. package/src/config.ts +38 -0
  10. package/src/decorator/data.ts +16 -0
  11. package/src/display/EditBox.ts +342 -0
  12. package/src/display/EditMask.ts +37 -0
  13. package/src/display/EditPoint.ts +9 -0
  14. package/src/display/EditSelect.ts +255 -0
  15. package/src/display/SelectArea.ts +30 -0
  16. package/src/display/Stroker.ts +92 -0
  17. package/src/editor/cursor.ts +45 -0
  18. package/src/editor/simulate.ts +14 -0
  19. package/src/editor/target.ts +39 -0
  20. package/src/event/EditorEvent.ts +33 -0
  21. package/src/event/EditorGroupEvent.ts +23 -0
  22. package/src/event/EditorMoveEvent.ts +17 -0
  23. package/src/event/EditorRotateEvent.ts +4 -10
  24. package/src/event/EditorScaleEvent.ts +28 -0
  25. package/src/event/EditorSkewEvent.ts +18 -0
  26. package/src/event/InnerEditorEvent.ts +23 -0
  27. package/src/helper/EditDataHelper.ts +183 -0
  28. package/src/helper/EditSelectHelper.ts +34 -0
  29. package/src/helper/EditorHelper.ts +73 -0
  30. package/src/index.ts +50 -3
  31. package/src/svg.ts +54 -0
  32. package/src/tool/EditTool.ts +99 -0
  33. package/src/tool/EditToolCreator.ts +32 -0
  34. package/src/tool/InnerEditor.ts +68 -0
  35. package/src/tool/LineEditTool.ts +135 -0
  36. package/types/index.d.ts +293 -45
  37. package/src/cursor.ts +0 -57
  38. package/src/event/EditorResizeEvent.ts +0 -34
  39. package/src/resize.ts +0 -87
  40. package/src/tool/LineTool.ts +0 -88
  41. package/src/tool/RectTool.ts +0 -139
@@ -1,510 +1,1910 @@
1
- import { MatrixHelper, Bounds, Matrix, Event, Group, Rect, Polygon, DataHelper, RotateEvent, PointHelper, MathHelper, DragEvent, PointerEvent, RenderEvent, KeyEvent } from '@leafer-ui/core';
2
-
3
- var IDirection8;
4
- (function (IDirection8) {
5
- IDirection8[IDirection8["topLeft"] = 0] = "topLeft";
6
- IDirection8[IDirection8["top"] = 1] = "top";
7
- IDirection8[IDirection8["topRight"] = 2] = "topRight";
8
- IDirection8[IDirection8["right"] = 3] = "right";
9
- IDirection8[IDirection8["bottomRight"] = 4] = "bottomRight";
10
- IDirection8[IDirection8["bottom"] = 5] = "bottom";
11
- IDirection8[IDirection8["bottomLeft"] = 6] = "bottomLeft";
12
- IDirection8[IDirection8["left"] = 7] = "left";
13
- })(IDirection8 || (IDirection8 = {}));
14
-
15
- const { scaleOfOuter, reset } = MatrixHelper;
16
- const { topLeft: topLeft$1, top: top$1, topRight: topRight$1, right: right$2, bottomRight: bottomRight$1, bottom: bottom$1, bottomLeft: bottomLeft$1, left: left$2 } = IDirection8;
17
- const matrix = {};
18
- function getResizeData(old, direction, move, lockRatio, around) {
19
- if (around) {
20
- move.x *= 2;
21
- move.y *= 2;
22
- }
23
- let origin, scaleX = 1, scaleY = 1;
24
- const { x, y, width, height } = old;
25
- const topScale = (-move.y + height) / height;
26
- const rightScale = (move.x + width) / width;
27
- const bottomScale = (move.y + height) / height;
28
- const leftScale = (-move.x + width) / width;
29
- switch (direction) {
30
- case top$1:
31
- scaleY = topScale;
32
- if (lockRatio)
33
- scaleX = scaleY;
34
- origin = { x: x + width / 2, y: y + height };
35
- break;
36
- case right$2:
37
- scaleX = rightScale;
38
- if (lockRatio)
39
- scaleY = scaleX;
40
- origin = { x, y: y + height / 2 };
41
- break;
42
- case bottom$1:
43
- scaleY = bottomScale;
44
- if (lockRatio)
45
- scaleX = scaleY;
46
- origin = { x: x + width / 2, y };
47
- break;
48
- case left$2:
49
- scaleX = leftScale;
50
- if (lockRatio)
51
- scaleY = scaleX;
52
- origin = { x: x + width, y: y + height / 2 };
53
- break;
54
- case topLeft$1:
55
- scaleY = topScale;
56
- scaleX = leftScale;
57
- if (lockRatio)
58
- scaleX = scaleY;
59
- origin = { x: x + width, y: y + height };
60
- break;
61
- case topRight$1:
62
- scaleY = topScale;
63
- scaleX = rightScale;
64
- if (lockRatio)
65
- scaleX = scaleY;
66
- origin = { x, y: y + height };
67
- break;
68
- case bottomRight$1:
69
- scaleY = bottomScale;
70
- scaleX = rightScale;
71
- if (lockRatio)
72
- scaleX = scaleY;
73
- origin = { x, y };
74
- break;
75
- case bottomLeft$1:
76
- scaleY = bottomScale;
77
- scaleX = leftScale;
78
- if (lockRatio)
79
- scaleX = scaleY;
80
- origin = { x: x + width, y };
81
- break;
82
- }
83
- if (around) {
84
- if (typeof around === 'object') {
85
- origin = { x: x + width / around.x, y: y + height / around.y };
1
+ import { PathCommandMap, MatrixHelper, Leaf, Text, Path, Line, Polygon, Group, Box, Event, defineKey, UI, Paint, Rect, Answer, Bounds, LeafList, PointHelper, AroundHelper, Direction9, MathHelper, Matrix, Debug, DataHelper, LeafHelper, RenderEvent, getPointData, Creator } from '@leafer-ui/draw';
2
+ import { PointerEvent, DragEvent, MoveEvent, ZoomEvent, RotateEvent, KeyEvent } from '@leafer-ui/core';
3
+
4
+ const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = PathCommandMap;
5
+ const PathScaler = {
6
+ scale(data, scaleX, scaleY) {
7
+ if (!data)
8
+ return;
9
+ let command;
10
+ let i = 0, len = data.length;
11
+ while (i < len) {
12
+ command = data[i];
13
+ switch (command) {
14
+ case M:
15
+ scalePoints(data, scaleX, scaleY, i, 1);
16
+ i += 3;
17
+ break;
18
+ case L:
19
+ scalePoints(data, scaleX, scaleY, i, 1);
20
+ i += 3;
21
+ break;
22
+ case C:
23
+ scalePoints(data, scaleX, scaleY, i, 3);
24
+ i += 7;
25
+ break;
26
+ case Q:
27
+ scalePoints(data, scaleX, scaleY, i, 2);
28
+ i += 5;
29
+ break;
30
+ case Z:
31
+ i += 1;
32
+ break;
33
+ case N:
34
+ scalePoints(data, scaleX, scaleY, i, 2);
35
+ i += 5;
36
+ break;
37
+ case D:
38
+ scalePoints(data, scaleX, scaleY, i, 2);
39
+ i += 9;
40
+ break;
41
+ case X:
42
+ scalePoints(data, scaleX, scaleY, i, 2);
43
+ i += 6;
44
+ break;
45
+ case G:
46
+ scalePoints(data, scaleX, scaleY, i, 2);
47
+ i += 9;
48
+ break;
49
+ case F:
50
+ scalePoints(data, scaleX, scaleY, i, 2);
51
+ i += 5;
52
+ break;
53
+ case O:
54
+ data[i] = G;
55
+ data.splice(i + 4, 0, data[i + 3], 0);
56
+ scalePoints(data, scaleX, scaleY, i, 2);
57
+ i += 7 + 2;
58
+ len += 2;
59
+ break;
60
+ case P:
61
+ data[i] = F;
62
+ data.splice(i + 4, 0, data[i + 3]);
63
+ scalePoints(data, scaleX, scaleY, i, 2);
64
+ i += 4 + 1;
65
+ len += 1;
66
+ break;
67
+ case U:
68
+ scalePoints(data, scaleX, scaleY, i, 2);
69
+ i += 6;
70
+ break;
71
+ }
86
72
  }
87
- else {
88
- origin = { x: x + width / 2, y: y + height / 2 };
73
+ },
74
+ scalePoints(data, scaleX, scaleY, start, pointCount) {
75
+ for (let i = pointCount ? start + 1 : 0, end = pointCount ? i + pointCount * 2 : data.length; i < end; i += 2) {
76
+ data[i] *= scaleX;
77
+ data[i + 1] *= scaleY;
89
78
  }
90
79
  }
91
- reset(matrix);
92
- scaleOfOuter(matrix, origin, scaleX, scaleY);
93
- const bounds = { x: old.x + matrix.e, y: old.y + matrix.f, width: width * scaleX, height: height * scaleY };
94
- return { bounds, old, origin, scaleX, scaleY, direction, lockRatio, around, };
80
+ };
81
+ const { scalePoints } = PathScaler;
82
+
83
+ const matrix$1 = MatrixHelper.get();
84
+ function scaleResize(leaf, scaleX, scaleY) {
85
+ if (leaf.pathInputed) {
86
+ scaleResizePath(leaf, scaleX, scaleY);
87
+ }
88
+ else {
89
+ if (scaleX !== 1)
90
+ leaf.width *= scaleX;
91
+ if (scaleY !== 1)
92
+ leaf.height *= scaleY;
93
+ }
94
+ }
95
+ function scaleResizeFontSize(leaf, scaleX, scaleY) {
96
+ const { width, height } = leaf.__localBoxBounds;
97
+ if (scaleX !== 1) {
98
+ leaf.fontSize *= scaleX;
99
+ leaf.y -= height * (scaleX - scaleY) / 2;
100
+ }
101
+ else if (scaleY !== 1) {
102
+ leaf.fontSize *= scaleY;
103
+ leaf.x -= width * (scaleY - scaleX) / 2;
104
+ }
105
+ }
106
+ function scaleResizePath(leaf, scaleX, scaleY) {
107
+ PathScaler.scale(leaf.__.path, scaleX, scaleY);
108
+ leaf.path = leaf.__.path;
109
+ }
110
+ function scaleResizePoints(leaf, scaleX, scaleY) {
111
+ PathScaler.scalePoints(leaf.__.points, scaleX, scaleY);
112
+ leaf.points = leaf.__.points;
113
+ }
114
+ function scaleResizeGroup(group, scaleX, scaleY) {
115
+ const { children } = group;
116
+ for (let i = 0; i < children.length; i++) {
117
+ matrix$1.a = scaleX;
118
+ matrix$1.d = scaleY;
119
+ children[i].transform(matrix$1, true);
120
+ }
95
121
  }
96
122
 
97
- const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = IDirection8;
98
- function updateCursor(editor, e) {
99
- const point = editor.enterPoint;
100
- if (!point || !editor.target || !editor.visible)
101
- return;
102
- let { rotation } = editor;
103
- let { resizeCursor, rotateCursor, resizeable } = editor.config;
104
- const mirror = editor.tool.getMirrorData(editor);
105
- const { __direction, __isResizePoint } = point.__;
106
- editor.enterPoint = point;
107
- if (__isResizePoint && (e.metaKey || e.ctrlKey || !resizeable))
108
- resizeCursor = rotateCursor;
109
- if (mirror.x || mirror.y) {
110
- mirrorCursors(resizeCursor = [...resizeCursor], mirror.x, mirror.y);
111
- mirrorCursors(rotateCursor = [...rotateCursor], mirror.y, mirror.x);
112
- if (mirror.x + mirror.y === 1)
113
- rotation = -rotation;
123
+ const leaf = Leaf.prototype;
124
+ leaf.scaleResize = function (scaleX, scaleY = scaleX, noResize) {
125
+ const data = this;
126
+ if (noResize || (data.editConfig && data.editConfig.editSize === 'scale')) {
127
+ data.scaleX *= scaleX;
128
+ data.scaleY *= scaleY;
129
+ }
130
+ else {
131
+ if (scaleX < 0)
132
+ data.scaleX *= -1, scaleX = -scaleX;
133
+ if (scaleY < 0)
134
+ data.scaleY *= -1, scaleY = -scaleY;
135
+ this.__scaleResize(scaleX, scaleY);
136
+ }
137
+ };
138
+ leaf.__scaleResize = function (scaleX, scaleY) {
139
+ scaleResize(this, scaleX, scaleY);
140
+ };
141
+ leaf.resizeWidth = function (width) {
142
+ const scale = width / this.getBounds('box', 'local').width;
143
+ this.scaleOf(this.__layout.boxBounds, scale, this.__.lockRatio ? scale : 1, true);
144
+ };
145
+ leaf.resizeHeight = function (height) {
146
+ const scale = height / this.getBounds('box', 'local').height;
147
+ this.scaleOf(this.__layout.boxBounds, this.__.lockRatio ? scale : 1, scale, true);
148
+ };
149
+ Text.prototype.__scaleResize = function (scaleX, scaleY) {
150
+ if (this.__.__autoSize && (this.__.resizeFontSize || (this.editConfig && this.editConfig.editSize === 'font-size'))) {
151
+ scaleResizeFontSize(this, scaleX, scaleY);
152
+ }
153
+ else {
154
+ scaleResize(this, scaleX, scaleY);
155
+ }
156
+ };
157
+ Path.prototype.__scaleResize = function (scaleX, scaleY) {
158
+ scaleResizePath(this, scaleX, scaleY);
159
+ };
160
+ Line.prototype.__scaleResize = function (scaleX, scaleY) {
161
+ if (this.pathInputed) {
162
+ scaleResizePath(this, scaleX, scaleY);
163
+ }
164
+ else if (this.points) {
165
+ scaleResizePoints(this, scaleX, scaleY);
166
+ }
167
+ else {
168
+ this.width *= scaleX;
169
+ }
170
+ };
171
+ Polygon.prototype.__scaleResize = function (scaleX, scaleY) {
172
+ if (this.pathInputed) {
173
+ scaleResizePath(this, scaleX, scaleY);
174
+ }
175
+ else if (this.points) {
176
+ scaleResizePoints(this, scaleX, scaleY);
177
+ }
178
+ else {
179
+ scaleResize(this, scaleX, scaleY);
180
+ }
181
+ };
182
+ Group.prototype.__scaleResize = function (scaleX, scaleY) {
183
+ scaleResizeGroup(this, scaleX, scaleY);
184
+ };
185
+ Box.prototype.__scaleResize = function (scaleX, scaleY) {
186
+ if (this.__.__autoSize && this.children.length) {
187
+ scaleResizeGroup(this, scaleX, scaleY);
188
+ }
189
+ else {
190
+ scaleResize(this, scaleX, scaleY);
191
+ if (this.__.resizeChildren)
192
+ scaleResizeGroup(this, scaleX, scaleY);
193
+ }
194
+ };
195
+
196
+ /******************************************************************************
197
+ Copyright (c) Microsoft Corporation.
198
+
199
+ Permission to use, copy, modify, and/or distribute this software for any
200
+ purpose with or without fee is hereby granted.
201
+
202
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
203
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
204
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
205
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
206
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
207
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
208
+ PERFORMANCE OF THIS SOFTWARE.
209
+ ***************************************************************************** */
210
+ /* global Reflect, Promise, SuppressedError, Symbol */
211
+
212
+
213
+ function __decorate(decorators, target, key, desc) {
214
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
215
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
216
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
217
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
218
+ }
219
+
220
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
221
+ var e = new Error(message);
222
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
223
+ };
224
+
225
+ function toList(value) {
226
+ return value ? (value instanceof Array ? value : [value]) : [];
227
+ }
228
+ class EditorEvent extends Event {
229
+ get list() { return toList(this.value); }
230
+ get oldList() { return toList(this.oldValue); }
231
+ constructor(type, data) {
232
+ super(type);
233
+ if (data)
234
+ Object.assign(this, data);
114
235
  }
115
- let index = (__direction + Math.round(rotation / 45)) % 8;
116
- if (index < 0)
117
- index += 8;
118
- point.cursor = __isResizePoint ? resizeCursor[index] : rotateCursor[index];
119
236
  }
120
- function mirrorCursors(mirror, mirrorX, mirrorY) {
121
- if (mirrorX) {
122
- const topCursor = mirror[top], topLeftCursor = mirror[topLeft], topRightCursor = mirror[topRight];
123
- mirror[top] = mirror[bottom];
124
- mirror[topLeft] = mirror[bottomLeft];
125
- mirror[topRight] = mirror[bottomRight];
126
- mirror[bottom] = topCursor;
127
- mirror[bottomLeft] = topLeftCursor;
128
- mirror[bottomRight] = topRightCursor;
129
- }
130
- if (mirrorY) {
131
- const leftCursor = mirror[left$1], topLeftCursor = mirror[topLeft], bottomLeftCursor = mirror[bottomLeft];
132
- mirror[left$1] = mirror[right$1];
133
- mirror[topLeft] = mirror[topRight];
134
- mirror[bottomLeft] = mirror[bottomRight];
135
- mirror[right$1] = leftCursor;
136
- mirror[topRight] = topLeftCursor;
137
- mirror[bottomRight] = bottomLeftCursor;
237
+ EditorEvent.SELECT = 'editor.select';
238
+ EditorEvent.HOVER = 'editor.hover';
239
+
240
+ class EditorMoveEvent extends EditorEvent {
241
+ constructor(type, data) {
242
+ super(type, data);
138
243
  }
139
244
  }
245
+ EditorMoveEvent.MOVE = 'editor.move';
140
246
 
141
- const RectTool = {
142
- name: 'RectTool',
143
- getMirrorData(editor) {
144
- const { scaleX, scaleY } = editor.target;
145
- return {
146
- x: scaleX < 0 ? 1 : 0,
147
- y: scaleY < 0 ? 1 : 0
148
- };
247
+ class EditorScaleEvent extends EditorEvent {
248
+ constructor(type, data) {
249
+ super(type, data);
250
+ }
251
+ }
252
+ EditorScaleEvent.SCALE = 'editor.scale';
253
+
254
+ class EditorRotateEvent extends EditorEvent {
255
+ constructor(type, data) {
256
+ super(type, data);
257
+ }
258
+ }
259
+ EditorRotateEvent.ROTATE = 'editor.rotate';
260
+
261
+ class EditorSkewEvent extends EditorEvent {
262
+ constructor(type, data) {
263
+ super(type, data);
264
+ }
265
+ }
266
+ EditorSkewEvent.SKEW = 'editor.skew';
267
+
268
+ function targetAttr(fn) {
269
+ return (target, key) => {
270
+ const privateKey = '_' + key;
271
+ defineKey(target, key, {
272
+ get() { return this[privateKey]; },
273
+ set(value) {
274
+ const old = this[privateKey];
275
+ if (old !== value)
276
+ this[privateKey] = value, fn(this, old);
277
+ }
278
+ });
279
+ };
280
+ }
281
+
282
+ const matrix = MatrixHelper.get();
283
+ const { abs } = Math;
284
+ const { copy: copy$1, scale } = MatrixHelper;
285
+ class Stroker extends UI {
286
+ constructor() {
287
+ super();
288
+ this.list = [];
289
+ this.hittable = false;
290
+ this.strokeAlign = 'center';
291
+ }
292
+ setTarget(target, style) {
293
+ this.set(style);
294
+ this.target = target;
295
+ }
296
+ __draw(canvas, options) {
297
+ const { list } = this;
298
+ if (list.length) {
299
+ let leaf;
300
+ const { stroke, strokeWidth, fill } = this.__;
301
+ const { bounds } = options;
302
+ for (let i = 0; i < list.length; i++) {
303
+ leaf = list[i];
304
+ if (bounds && bounds.hit(leaf.__world, options.matrix)) {
305
+ const aScaleX = abs(leaf.__world.scaleX), aScaleY = abs(leaf.__world.scaleY);
306
+ if (aScaleX !== aScaleY) {
307
+ copy$1(matrix, leaf.__world);
308
+ scale(matrix, 1 / aScaleX, 1 / aScaleY);
309
+ canvas.setWorld(matrix, options.matrix);
310
+ canvas.beginPath();
311
+ this.__.strokeWidth = strokeWidth;
312
+ const { x, y, width, height } = leaf.__layout.boxBounds;
313
+ canvas.rect(x * aScaleX, y * aScaleY, width * aScaleX, height * aScaleY);
314
+ }
315
+ else {
316
+ canvas.setWorld(leaf.__world, options.matrix);
317
+ canvas.beginPath();
318
+ if (leaf.__.__useArrow) {
319
+ leaf.__drawPath(canvas);
320
+ }
321
+ else {
322
+ leaf.__.__pathForRender ? leaf.__drawRenderPath(canvas) : leaf.__drawPathByBox(canvas);
323
+ }
324
+ this.__.strokeWidth = strokeWidth / abs(leaf.__world.scaleX);
325
+ }
326
+ if (stroke)
327
+ typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas) : Paint.strokes(stroke, this, canvas);
328
+ if (fill)
329
+ typeof fill === 'string' ? Paint.fill(fill, this, canvas) : Paint.fills(fill, this, canvas);
330
+ }
331
+ }
332
+ this.__.strokeWidth = strokeWidth;
333
+ }
334
+ }
335
+ destroy() {
336
+ this.target = null;
337
+ super.destroy();
338
+ }
339
+ }
340
+ __decorate([
341
+ targetAttr(onTarget$1)
342
+ ], Stroker.prototype, "target", void 0);
343
+ function onTarget$1(stroker) {
344
+ const value = stroker.target;
345
+ stroker.list = value ? (value instanceof Array ? value : [value]) : [];
346
+ stroker.forceUpdate();
347
+ }
348
+
349
+ class SelectArea extends Group {
350
+ constructor(data) {
351
+ super(data);
352
+ this.strokeArea = new Rect({ strokeAlign: 'center' });
353
+ this.fillArea = new Rect();
354
+ this.visible = this.hittable = false;
355
+ this.addMany(this.fillArea, this.strokeArea);
356
+ }
357
+ setStyle(style, userStyle) {
358
+ const { visible, stroke, strokeWidth } = style;
359
+ this.visible = visible;
360
+ this.strokeArea.reset(Object.assign({ stroke, strokeWidth }, (userStyle || {})));
361
+ this.fillArea.reset({ visible: userStyle ? false : true, fill: stroke, opacity: 0.2 });
362
+ }
363
+ setBounds(bounds) {
364
+ this.strokeArea.set(bounds);
365
+ this.fillArea.set(bounds);
366
+ }
367
+ }
368
+
369
+ const { No, Yes, NoAndSkip, YesAndSkip } = Answer;
370
+ const EditSelectHelper = {
371
+ findOne(path) {
372
+ return path.list.find((leaf) => leaf.editable);
149
373
  },
150
- resize(e) {
151
- const { target, bounds, resizeType, old } = e;
152
- const { x, y, width, height } = bounds;
153
- const point = { x: x - old.x, y: y - old.y };
154
- target.innerToWorld(point, null, true, target.parent);
155
- target.x += point.x;
156
- target.y += point.y;
157
- if (resizeType === 'scale') {
158
- target.scaleX *= width / old.width;
159
- target.scaleY *= height / old.height;
374
+ findBounds(leaf, bounds) {
375
+ if (leaf.__.hittable && leaf.__.visible && !leaf.__.locked && bounds.hit(leaf.__world)) {
376
+ if (leaf.__.editable) {
377
+ if (leaf.isBranch && !leaf.__.hitChildren) {
378
+ return leaf.__.hitSelf ? YesAndSkip : NoAndSkip;
379
+ }
380
+ else if (leaf.isFrame) {
381
+ return bounds.includes(leaf.__layout.boxBounds, leaf.__world) ? YesAndSkip : No;
382
+ }
383
+ else {
384
+ if (bounds.hit(leaf.__layout.boxBounds, leaf.__world) && leaf.__.hitSelf)
385
+ return Yes;
386
+ }
387
+ }
388
+ return No;
389
+ }
390
+ else {
391
+ return leaf.isBranch ? NoAndSkip : No;
392
+ }
393
+ }
394
+ };
395
+
396
+ const { findOne } = EditSelectHelper;
397
+ class EditSelect extends Group {
398
+ get dragging() { return !!this.originList; }
399
+ get running() { const { editor } = this; return this.hittable && editor.visible && editor.hittable && editor.mergeConfig.selector; }
400
+ get isMoveMode() { return this.app && this.app.interaction.moveMode; }
401
+ constructor(editor) {
402
+ super();
403
+ this.hoverStroker = new Stroker();
404
+ this.targetStroker = new Stroker();
405
+ this.bounds = new Bounds();
406
+ this.selectArea = new SelectArea();
407
+ this.__eventIds = [];
408
+ this.editor = editor;
409
+ this.addMany(this.targetStroker, this.hoverStroker, this.selectArea);
410
+ this.__listenEvents();
411
+ }
412
+ onHover() {
413
+ const { editor } = this;
414
+ if (this.running && !this.dragging && !editor.dragging) {
415
+ const { stroke, strokeWidth, hover, hoverStyle } = editor.mergeConfig;
416
+ this.hoverStroker.setTarget(hover ? this.editor.hoverTarget : null, Object.assign({ stroke, strokeWidth }, (hoverStyle || {})));
160
417
  }
161
418
  else {
162
- if (width < 0) {
163
- target.width = -width;
164
- target.scaleX *= -1;
419
+ this.hoverStroker.target = null;
420
+ }
421
+ }
422
+ onSelect() {
423
+ if (this.running) {
424
+ const { mergeConfig: config, list } = this.editor;
425
+ const { stroke, strokeWidth } = config;
426
+ this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2) });
427
+ this.hoverStroker.target = null;
428
+ }
429
+ }
430
+ update() {
431
+ if (this.targetStroker.target)
432
+ this.targetStroker.forceUpdate();
433
+ }
434
+ onPointerMove(e) {
435
+ const { app, editor } = this;
436
+ if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
437
+ const find = this.findUI(e);
438
+ editor.hoverTarget = editor.hasItem(find) ? null : find;
439
+ }
440
+ if (this.isMoveMode) {
441
+ editor.hoverTarget = null;
442
+ }
443
+ }
444
+ onBeforeDown(e) {
445
+ const { select } = this.editor.mergeConfig;
446
+ if (select === 'press')
447
+ this.checkAndSelect(e);
448
+ }
449
+ onTap(e) {
450
+ const { editor } = this;
451
+ const { select } = editor.mergeConfig;
452
+ if (select === 'tap')
453
+ this.checkAndSelect(e);
454
+ if (this.needRemoveItem) {
455
+ editor.removeItem(this.needRemoveItem);
456
+ }
457
+ else if (this.isMoveMode) {
458
+ editor.target = null;
459
+ }
460
+ }
461
+ checkAndSelect(e) {
462
+ this.needRemoveItem = null;
463
+ if (this.allowSelect(e)) {
464
+ const { editor } = this;
465
+ const find = this.findUI(e);
466
+ if (find) {
467
+ if (this.isMultipleSelect(e)) {
468
+ if (editor.hasItem(find))
469
+ this.needRemoveItem = find;
470
+ else
471
+ editor.addItem(find);
472
+ }
473
+ else {
474
+ editor.target = find;
475
+ }
165
476
  }
166
- else {
167
- if (target.width !== width)
168
- target.width = width;
477
+ else if (this.allow(e.target)) {
478
+ if (!e.shiftKey)
479
+ editor.target = null;
169
480
  }
170
- if (height < 0) {
171
- target.height = -height;
172
- target.scaleY *= -1;
481
+ }
482
+ }
483
+ onDragStart(e) {
484
+ if (this.allowDrag(e)) {
485
+ const { editor } = this;
486
+ const { stroke, area } = editor.mergeConfig;
487
+ const { x, y } = e.getInner(this);
488
+ this.bounds.set(x, y);
489
+ this.selectArea.setStyle({ visible: true, stroke, x, y }, area);
490
+ this.selectArea.setBounds(this.bounds.get());
491
+ this.originList = editor.leafList.clone();
492
+ }
493
+ }
494
+ onDrag(e) {
495
+ if (this.editor.dragging) {
496
+ this.onDragEnd();
497
+ return;
498
+ }
499
+ if (this.dragging) {
500
+ const { editor } = this;
501
+ const total = e.getInnerTotal(this);
502
+ const dragBounds = this.bounds.clone().unsign();
503
+ const list = new LeafList(editor.app.find(EditSelectHelper.findBounds, dragBounds));
504
+ this.bounds.width = total.x;
505
+ this.bounds.height = total.y;
506
+ this.selectArea.setBounds(dragBounds.get());
507
+ if (list.length) {
508
+ const selectList = [];
509
+ this.originList.forEach(item => { if (!list.has(item))
510
+ selectList.push(item); });
511
+ list.forEach(item => { if (!this.originList.has(item))
512
+ selectList.push(item); });
513
+ if (selectList.length !== editor.list.length || editor.list.some((child, index) => child !== selectList[index])) {
514
+ editor.target = selectList;
515
+ }
173
516
  }
174
517
  else {
175
- if (target.height !== height)
176
- target.height = height;
518
+ editor.target = this.originList.list;
519
+ }
520
+ }
521
+ }
522
+ onDragEnd() {
523
+ if (this.dragging)
524
+ this.originList = null, this.selectArea.visible = false;
525
+ }
526
+ onAutoMove(e) {
527
+ if (this.dragging) {
528
+ const { x, y } = e.getLocalMove(this);
529
+ this.bounds.x += x;
530
+ this.bounds.y += y;
531
+ }
532
+ }
533
+ allow(target) {
534
+ return target.leafer !== this.editor.leafer;
535
+ }
536
+ allowDrag(e) {
537
+ if (this.running && this.editor.mergeConfig.boxSelect && !e.target.draggable) {
538
+ return (!this.editor.editing && this.allow(e.target)) || (e.shiftKey && !findOne(e.path));
539
+ }
540
+ else {
541
+ return false;
542
+ }
543
+ }
544
+ allowSelect(e) {
545
+ return this.running && !this.isMoveMode && !e.middle;
546
+ }
547
+ findDeepOne(e) {
548
+ const options = { exclude: new LeafList(this.editor.editBox.rect) };
549
+ return findOne(e.target.leafer.interaction.findPath(e, options));
550
+ }
551
+ findUI(e) {
552
+ return this.isMultipleSelect(e) ? this.findDeepOne(e) : findOne(e.path);
553
+ }
554
+ isMultipleSelect(e) {
555
+ return e.shiftKey || this.editor.mergeConfig.continuousSelect;
556
+ }
557
+ __listenEvents() {
558
+ const { editor } = this;
559
+ editor.waitLeafer(() => {
560
+ const { app } = editor;
561
+ app.selector.proxy = editor;
562
+ this.__eventIds = [
563
+ editor.on_(EditorEvent.HOVER, this.onHover, this),
564
+ editor.on_(EditorEvent.SELECT, this.onSelect, this),
565
+ app.on_(PointerEvent.MOVE, this.onPointerMove, this),
566
+ app.on_(PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
567
+ app.on_(PointerEvent.TAP, this.onTap, this),
568
+ app.on_(DragEvent.START, this.onDragStart, this),
569
+ app.on_(DragEvent.DRAG, this.onDrag, this),
570
+ app.on_(DragEvent.END, this.onDragEnd, this),
571
+ app.on_(MoveEvent.MOVE, this.onAutoMove, this),
572
+ app.on_([ZoomEvent.ZOOM, MoveEvent.MOVE], () => { this.editor.hoverTarget = null; }),
573
+ ];
574
+ });
575
+ }
576
+ __removeListenEvents() {
577
+ if (this.__eventIds) {
578
+ this.off_(this.__eventIds);
579
+ this.__eventIds.length = 0;
580
+ }
581
+ }
582
+ destroy() {
583
+ this.editor = this.originList = this.needRemoveItem = null;
584
+ this.__removeListenEvents();
585
+ super.destroy();
586
+ }
587
+ }
588
+
589
+ const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = Direction9;
590
+ const { toPoint } = AroundHelper;
591
+ const EditDataHelper = {
592
+ getScaleData(bounds, direction, pointMove, lockRatio, around) {
593
+ let align, origin = {}, scaleX = 1, scaleY = 1;
594
+ const { width, height } = bounds;
595
+ if (around) {
596
+ pointMove.x *= 2;
597
+ pointMove.y *= 2;
598
+ }
599
+ if (Math.abs(pointMove.x) === width)
600
+ pointMove.x += 0.1;
601
+ if (Math.abs(pointMove.y) === height)
602
+ pointMove.y += 0.1;
603
+ const topScale = (-pointMove.y + height) / height;
604
+ const rightScale = (pointMove.x + width) / width;
605
+ const bottomScale = (pointMove.y + height) / height;
606
+ const leftScale = (-pointMove.x + width) / width;
607
+ switch (direction) {
608
+ case top:
609
+ scaleY = topScale;
610
+ align = 'bottom';
611
+ break;
612
+ case right$1:
613
+ scaleX = rightScale;
614
+ align = 'left';
615
+ break;
616
+ case bottom:
617
+ scaleY = bottomScale;
618
+ align = 'top';
619
+ break;
620
+ case left$1:
621
+ scaleX = leftScale;
622
+ align = 'right';
623
+ break;
624
+ case topLeft:
625
+ scaleY = topScale;
626
+ scaleX = leftScale;
627
+ align = 'bottom-right';
628
+ break;
629
+ case topRight:
630
+ scaleY = topScale;
631
+ scaleX = rightScale;
632
+ align = 'bottom-left';
633
+ break;
634
+ case bottomRight:
635
+ scaleY = bottomScale;
636
+ scaleX = rightScale;
637
+ align = 'top-left';
638
+ break;
639
+ case bottomLeft:
640
+ scaleY = bottomScale;
641
+ scaleX = leftScale;
642
+ align = 'top-right';
643
+ }
644
+ if (lockRatio) {
645
+ const unlockSide = lockRatio === 'corner' && direction % 2;
646
+ if (!unlockSide) {
647
+ const scale = Math.sqrt(Math.abs(scaleX * scaleY));
648
+ scaleX = scaleX < 0 ? -scale : scale;
649
+ scaleY = scaleY < 0 ? -scale : scale;
177
650
  }
178
651
  }
652
+ toPoint(around || align, bounds, origin);
653
+ return { origin, scaleX, scaleY, direction, lockRatio, around };
179
654
  },
180
- rotate(e) {
181
- const { target, rotation, origin } = e;
182
- target.rotateOf(origin, rotation);
655
+ getRotateData(bounds, direction, current, last, around) {
656
+ let align, origin = {};
657
+ switch (direction) {
658
+ case topLeft:
659
+ align = 'bottom-right';
660
+ break;
661
+ case topRight:
662
+ align = 'bottom-left';
663
+ break;
664
+ case bottomRight:
665
+ align = 'top-left';
666
+ break;
667
+ case bottomLeft:
668
+ align = 'top-right';
669
+ break;
670
+ default:
671
+ align = 'center';
672
+ }
673
+ toPoint(around || align, bounds, origin);
674
+ return { origin, rotation: PointHelper.getRotation(last, origin, current) };
183
675
  },
184
- update(editor) {
185
- const { target, config, rotatePoints, targetRect, rect, circle, resizeLines, resizePoints } = editor;
186
- const { type, resizeable, rotateable, stroke, pointFill, pointSize, pointRadius } = config;
187
- const defaultStyle = { fill: pointFill, stroke, width: pointSize, height: pointSize, cornerRadius: pointRadius };
188
- const pointStyles = config.point instanceof Array ? config.point : [config.point || defaultStyle];
189
- const box = new Bounds(target.boxBounds);
190
- const w = target.worldTransform, pw = editor.parent.worldTransform;
191
- const matrix = new Matrix(w);
192
- matrix.divide(pw);
193
- const worldX = matrix.e, worldY = matrix.f;
194
- let { scaleX, scaleY, rotation, skewX, skewY } = w;
195
- scaleX /= pw.scaleX, scaleY /= pw.scaleY, rotation -= pw.rotation, skewX -= pw.skewX, skewY -= pw.skewY;
196
- const { x, y, width, height } = box.scale(scaleX, scaleY);
197
- editor.set({ x: worldX, y: worldY, rotation, skewX, skewY });
198
- targetRect.set({ x, y, width: box.width / scaleX, height: box.height / scaleY, scaleX, scaleY, visible: true });
199
- const points = [
200
- { x, y },
201
- { x: x + width / 2, y },
202
- { x: x + width, y },
203
- { x: x + width, y: y + height / 2 },
204
- { x: x + width, y: y + height },
205
- { x: x + width / 2, y: y + height },
206
- { x, y: y + height },
207
- { x, y: y + height / 2 }
208
- ];
209
- const rectPoints = [];
210
- let point, style, rotateP, resizeP, resizeL;
676
+ getSkewData(bounds, direction, move, around) {
677
+ let align, origin = {}, skewX = 0, skewY = 0;
678
+ let last;
679
+ switch (direction) {
680
+ case top:
681
+ last = { x: 0.5, y: 0 };
682
+ align = 'bottom';
683
+ skewX = 1;
684
+ break;
685
+ case bottom:
686
+ last = { x: 0.5, y: 1 };
687
+ align = 'top';
688
+ skewX = 1;
689
+ break;
690
+ case left$1:
691
+ last = { x: 0, y: 0.5 };
692
+ align = 'right';
693
+ skewY = 1;
694
+ break;
695
+ case right$1:
696
+ last = { x: 1, y: 0.5 };
697
+ align = 'left';
698
+ skewY = 1;
699
+ }
700
+ const { x, y, width, height } = bounds;
701
+ last.x = x + last.x * width;
702
+ last.y = y + last.y * height;
703
+ toPoint(around || align, bounds, origin);
704
+ const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) });
705
+ skewX ? skewX = -rotation : skewY = rotation;
706
+ return { origin, skewX, skewY };
707
+ },
708
+ getAround(around, altKey) {
709
+ return (altKey && !around) ? 'center' : around;
710
+ },
711
+ getRotateDirection(direction, rotation, totalDirection = 8) {
712
+ direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection;
713
+ if (direction < 0)
714
+ direction += totalDirection;
715
+ return direction;
716
+ },
717
+ getFlipDirection(direction, flipedX, flipedY) {
718
+ if (flipedX) {
719
+ switch (direction) {
720
+ case left$1:
721
+ direction = right$1;
722
+ break;
723
+ case topLeft:
724
+ direction = topRight;
725
+ break;
726
+ case bottomLeft:
727
+ direction = bottomRight;
728
+ break;
729
+ case right$1:
730
+ direction = left$1;
731
+ break;
732
+ case topRight:
733
+ direction = topLeft;
734
+ break;
735
+ case bottomRight:
736
+ direction = bottomLeft;
737
+ break;
738
+ }
739
+ }
740
+ if (flipedY) {
741
+ switch (direction) {
742
+ case top:
743
+ direction = bottom;
744
+ break;
745
+ case topLeft:
746
+ direction = bottomLeft;
747
+ break;
748
+ case topRight:
749
+ direction = bottomRight;
750
+ break;
751
+ case bottom:
752
+ direction = top;
753
+ break;
754
+ case bottomLeft:
755
+ direction = topLeft;
756
+ break;
757
+ case bottomRight:
758
+ direction = topRight;
759
+ break;
760
+ }
761
+ }
762
+ return direction;
763
+ }
764
+ };
765
+
766
+ const cacheCursors = {};
767
+ function updateCursor(editor, e) {
768
+ const { editBox } = editor, point = editBox.enterPoint;
769
+ if (!point || !editor.editing || !editBox.visible)
770
+ return;
771
+ if (point.name === 'circle')
772
+ return;
773
+ let { rotation } = editBox;
774
+ const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
775
+ const { pointType } = point, { flippedX, flippedY } = editBox;
776
+ let showResize = pointType === 'resize';
777
+ if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable))
778
+ showResize = false;
779
+ const showSkew = skewable && !showResize && point.name === 'resize-line';
780
+ const cursor = showSkew ? skewCursor : (showResize ? resizeCursor : rotateCursor);
781
+ rotation += (EditDataHelper.getFlipDirection(point.direction, flippedX, flippedY) + 1) * 45;
782
+ rotation = Math.round(MathHelper.formatRotation(rotation, true) / 2) * 2;
783
+ const { url, x, y } = cursor;
784
+ const key = url + rotation;
785
+ if (cacheCursors[key]) {
786
+ point.cursor = cacheCursors[key];
787
+ }
788
+ else {
789
+ cacheCursors[key] = point.cursor = { url: toDataURL(url, rotation), x, y };
790
+ }
791
+ }
792
+ function updateMoveCursor(editor) {
793
+ editor.editBox.rect.cursor = editor.mergeConfig.moveCursor;
794
+ }
795
+ function toDataURL(svg, rotation) {
796
+ return '"data:image/svg+xml,' + encodeURIComponent(svg.replace('{{rotation}}', rotation.toString())) + '"';
797
+ }
798
+
799
+ class EditPoint extends Box {
800
+ }
801
+
802
+ const fourDirection = ['top', 'right', 'bottom', 'left'];
803
+ class EditBox extends Group {
804
+ get flipped() { return this.flippedX || this.flippedY; }
805
+ get flippedX() { return this.scaleX < 0; }
806
+ get flippedY() { return this.scaleY < 0; }
807
+ get flippedOne() { return this.scaleX * this.scaleY < 0; }
808
+ constructor(editor) {
809
+ super();
810
+ this.view = new Group();
811
+ this.rect = new Box({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 });
812
+ this.circle = new EditPoint({ name: 'circle', strokeAlign: 'center', around: 'center', cursor: 'crosshair', hitRadius: 5 });
813
+ this.buttons = new Group({ around: 'center', hitSelf: false });
814
+ this.resizePoints = [];
815
+ this.rotatePoints = [];
816
+ this.resizeLines = [];
817
+ this.__eventIds = [];
818
+ this.editor = editor;
819
+ this.visible = false;
820
+ this.create();
821
+ this.rect.syncEventer = editor;
822
+ this.__listenEvents();
823
+ }
824
+ create() {
825
+ let rotatePoint, resizeLine, resizePoint;
826
+ const { view, resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this;
827
+ const arounds = ['bottom-right', 'bottom', 'bottom-left', 'left', 'top-left', 'top', 'top-right', 'right'];
211
828
  for (let i = 0; i < 8; i++) {
212
- point = points[i];
213
- style = pointStyles[i % pointStyles.length];
214
- resizeP = resizePoints[i];
215
- resizeL = resizeLines[Math.floor(i / 2)];
216
- rotateP = rotatePoints[i];
217
- resizeP.set(style);
218
- resizeP.x = rotateP.x = resizeL.x = point.x;
219
- resizeP.y = rotateP.y = resizeL.y = point.y;
220
- resizeP.visible = resizeL.visible = resizeable || rotateable;
221
- rotateP.visible = rotateable && resizeable;
829
+ rotatePoint = new EditPoint({ name: 'rotate-point', around: arounds[i], width: 15, height: 15, hitFill: "all" });
830
+ rotatePoints.push(rotatePoint);
831
+ this.listenPointEvents(rotatePoint, 'rotate', i);
222
832
  if (i % 2) {
223
- if (((i + 1) / 2) % 2) {
224
- resizeL.width = Math.abs(width);
225
- rotateP.width = Math.max(10, Math.abs(width) - 30);
226
- }
227
- else {
228
- resizeL.height = Math.abs(height);
229
- rotateP.height = Math.max(10, Math.abs(height) - 30);
833
+ resizeLine = new EditPoint({ name: 'resize-line', around: 'center', width: 10, height: 10, hitFill: "all" });
834
+ resizeLines.push(resizeLine);
835
+ this.listenPointEvents(resizeLine, 'resize', i);
836
+ }
837
+ resizePoint = new EditPoint({ name: 'resize-point', hitRadius: 5 });
838
+ resizePoints.push(resizePoint);
839
+ this.listenPointEvents(resizePoint, 'resize', i);
840
+ }
841
+ buttons.add(circle);
842
+ this.listenPointEvents(circle, 'rotate', 2);
843
+ view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
844
+ this.add(view);
845
+ }
846
+ load() {
847
+ const { mergeConfig, element, single } = this.editor;
848
+ const { rect, circle, resizePoints } = this;
849
+ const { stroke, strokeWidth, moveable } = mergeConfig;
850
+ const pointsStyle = this.getPointsStyle();
851
+ const middlePointsStyle = this.getMiddlePointsStyle();
852
+ let resizeP;
853
+ for (let i = 0; i < 8; i++) {
854
+ resizeP = resizePoints[i];
855
+ resizeP.set(this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]));
856
+ if (!(i % 2))
857
+ resizeP.rotation = (i / 2) * 90;
858
+ }
859
+ circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]));
860
+ rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
861
+ rect.hittable = !single && moveable;
862
+ element.syncEventer = (single && moveable) ? rect : null;
863
+ this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null;
864
+ }
865
+ update(bounds) {
866
+ this.visible = !this.editor.element.locked;
867
+ if (this.view.worldOpacity) {
868
+ const { mergeConfig } = this.editor;
869
+ const { width, height } = bounds;
870
+ const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
871
+ const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
872
+ const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
873
+ const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
874
+ let point = {}, rotateP, resizeP, resizeL;
875
+ for (let i = 0; i < 8; i++) {
876
+ AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point);
877
+ resizeP = resizePoints[i];
878
+ rotateP = rotatePoints[i];
879
+ resizeL = resizeLines[Math.floor(i / 2)];
880
+ resizeP.set(point);
881
+ rotateP.set(point);
882
+ resizeL.set(point);
883
+ resizeP.visible = resizeL.visible = showPoints && !!(resizeable || rotateable);
884
+ rotateP.visible = showPoints && rotateable && resizeable && !mergeConfig.rotatePoint;
885
+ if (i % 2) {
886
+ resizeP.visible = rotateP.visible = showPoints && !!middlePoint;
887
+ if (((i + 1) / 2) % 2) {
888
+ resizeL.width = width;
889
+ if (resizeP.width > width - 30)
890
+ resizeP.visible = false;
891
+ }
892
+ else {
893
+ resizeL.height = height;
894
+ resizeP.rotation = 90;
895
+ if (resizeP.width > height - 30)
896
+ resizeP.visible = false;
897
+ }
230
898
  }
231
- resizeP.rotation = 90;
232
- resizeP.visible = type === 'mobile';
899
+ }
900
+ circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint;
901
+ if (rect.path)
902
+ rect.path = null;
903
+ rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
904
+ const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1);
905
+ this.buttons.visible = buttonVisible;
906
+ if (buttonVisible)
907
+ this.layoutButtons();
908
+ }
909
+ }
910
+ layoutButtons() {
911
+ const { buttons, resizePoints } = this;
912
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig;
913
+ const { flippedX, flippedY } = this;
914
+ let index = fourDirection.indexOf(buttonsDirection);
915
+ if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
916
+ if (buttonsFixed)
917
+ index = (index + 2) % 4;
918
+ }
919
+ const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
920
+ const point = resizePoints[direction * 2 + 1];
921
+ const useX = direction % 2;
922
+ const sign = (!direction || direction === 3) ? -1 : 1;
923
+ const useWidth = index % 2;
924
+ const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
925
+ if (useX) {
926
+ buttons.x = point.x + margin;
927
+ buttons.y = point.y;
928
+ }
929
+ else {
930
+ buttons.x = point.x;
931
+ buttons.y = point.y + margin;
932
+ }
933
+ if (buttonsFixed) {
934
+ buttons.rotation = (direction - index) * 90;
935
+ buttons.scaleX = flippedX ? -1 : 1;
936
+ buttons.scaleY = flippedY ? -1 : 1;
937
+ }
938
+ }
939
+ unload() {
940
+ this.visible = false;
941
+ }
942
+ getPointStyle(userStyle) {
943
+ const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig;
944
+ const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius };
945
+ return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle;
946
+ }
947
+ getPointsStyle() {
948
+ const { point } = this.editor.mergeConfig;
949
+ return point instanceof Array ? point : [point];
950
+ }
951
+ getMiddlePointsStyle() {
952
+ const { middlePoint } = this.editor.mergeConfig;
953
+ return middlePoint instanceof Array ? middlePoint : (middlePoint ? [middlePoint] : this.getPointsStyle());
954
+ }
955
+ onSelect(e) {
956
+ if (e.oldList.length === 1) {
957
+ e.oldList[0].syncEventer = null;
958
+ if (this.app)
959
+ this.app.interaction.bottomList = null;
960
+ }
961
+ }
962
+ onDragStart(e) {
963
+ this.dragging = true;
964
+ if (e.current.name === 'rect') {
965
+ const { editor } = this;
966
+ this.moving = true;
967
+ editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
968
+ editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
969
+ }
970
+ }
971
+ onDragEnd(e) {
972
+ this.dragging = false;
973
+ this.moving = false;
974
+ if (e.current.name === 'rect')
975
+ this.editor.opacity = 1;
976
+ }
977
+ onDrag(e) {
978
+ const { editor } = this;
979
+ const point = this.enterPoint = e.current;
980
+ if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) {
981
+ if (editor.mergeConfig.rotateable)
982
+ editor.onRotate(e);
983
+ }
984
+ else {
985
+ editor.onScale(e);
986
+ }
987
+ updateCursor(editor, e);
988
+ }
989
+ onArrow(e) {
990
+ if (this.editor.editing && this.editor.mergeConfig.keyEvent) {
991
+ const move = { x: 0, y: 0 };
992
+ const distance = e.shiftKey ? 10 : 1;
993
+ switch (e.code) {
994
+ case 'ArrowDown':
995
+ move.y = distance;
996
+ break;
997
+ case 'ArrowUp':
998
+ move.y = -distance;
999
+ break;
1000
+ case 'ArrowLeft':
1001
+ move.x = -distance;
1002
+ break;
1003
+ case 'ArrowRight':
1004
+ move.x = distance;
1005
+ }
1006
+ this.editor.move(move);
1007
+ }
1008
+ }
1009
+ onDoubleTap(e) {
1010
+ if (this.editor.mergeConfig.openInner === 'double')
1011
+ this.openInner(e);
1012
+ }
1013
+ onLongPress(e) {
1014
+ if (this.editor.mergeConfig.openInner === 'long')
1015
+ this.openInner(e);
1016
+ }
1017
+ openInner(e) {
1018
+ const { editor } = this;
1019
+ if (editor.single) {
1020
+ const { element } = editor;
1021
+ if (element.isBranch) {
1022
+ editor.openGroup(element);
1023
+ editor.target = editor.selector.findDeepOne(e);
233
1024
  }
234
1025
  else {
235
- rectPoints.push(point.x, point.y);
1026
+ editor.openInnerEditor();
236
1027
  }
237
1028
  }
238
- style = config.rotatePoint || style;
239
- circle.set(style);
240
- circle.x = x + width / 2;
241
- if (!style.y)
242
- circle.y = y - (10 + (resizeP.height + circle.height) / 2) * (this.getMirrorData(editor).y ? -1 : 1);
243
- circle.visible = rotateable && type === 'mobile';
244
- rect.set(config.rect || { stroke });
245
- rect.points = rectPoints;
246
- rect.visible = true;
247
1029
  }
1030
+ listenPointEvents(point, type, direction) {
1031
+ const { editor } = this;
1032
+ point.direction = direction;
1033
+ point.pointType = type;
1034
+ point.on_(DragEvent.START, this.onDragStart, this);
1035
+ point.on_(DragEvent.DRAG, this.onDrag, this);
1036
+ point.on_(DragEvent.END, this.onDragEnd, this);
1037
+ point.on_(PointerEvent.LEAVE, () => this.enterPoint = null);
1038
+ if (point.name !== 'circle')
1039
+ point.on_(PointerEvent.ENTER, (e) => { this.enterPoint = point, updateCursor(editor, e); });
1040
+ }
1041
+ __listenEvents() {
1042
+ const { rect, editor } = this;
1043
+ this.__eventIds = [
1044
+ editor.on_(EditorEvent.SELECT, this.onSelect, this),
1045
+ rect.on_(DragEvent.START, this.onDragStart, this),
1046
+ rect.on_(DragEvent.DRAG, editor.onMove, editor),
1047
+ rect.on_(DragEvent.END, this.onDragEnd, this),
1048
+ rect.on_(ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
1049
+ rect.on_(RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
1050
+ rect.on_(PointerEvent.ENTER, () => updateMoveCursor(editor)),
1051
+ rect.on_(PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
1052
+ rect.on_(PointerEvent.LONG_PRESS, this.onLongPress, this)
1053
+ ];
1054
+ }
1055
+ __removeListenEvents() {
1056
+ this.off_(this.__eventIds);
1057
+ this.__eventIds.length = 0;
1058
+ }
1059
+ destroy() {
1060
+ this.editor = null;
1061
+ this.__removeListenEvents();
1062
+ super.destroy();
1063
+ }
1064
+ }
1065
+
1066
+ class EditMask extends UI {
1067
+ constructor(editor) {
1068
+ super();
1069
+ this.editor = editor;
1070
+ this.hittable = false;
1071
+ }
1072
+ __draw(canvas, options) {
1073
+ const { editor } = this;
1074
+ const { mask } = editor.mergeConfig;
1075
+ if (mask && editor.list.length) {
1076
+ const { rect } = editor.editBox;
1077
+ const { width, height } = rect.__;
1078
+ canvas.resetTransform();
1079
+ canvas.fillWorld(canvas.bounds, mask);
1080
+ canvas.setWorld(rect.__world, options.matrix);
1081
+ canvas.clearRect(0, 0, width, height);
1082
+ }
1083
+ }
1084
+ destroy() {
1085
+ this.editor = null;
1086
+ super.destroy();
1087
+ }
1088
+ }
1089
+
1090
+ const filterStyle = `
1091
+ <feOffset dy="1"/>
1092
+ <feGaussianBlur stdDeviation="1.5"/>
1093
+ <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"/>
1094
+ <feBlend mode="normal" in="SourceGraphic" result="shape"/>`;
1095
+ const resizeSVG = `
1096
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
1097
+ <g filter="url(#f)">
1098
+ <g transform="rotate({{rotation}},12,12)">
1099
+ <path d="M7.5 8.0H8.5V5.9L6.8 7.2L7.5 8.0ZM3 11.4L2.3 10.6L1.3 11.4L2.3 12.2L3 11.4ZM7.5 10.4H6.5V11.4H7.5V10.4ZM16.5 10.4V11.4H17.5V10.4H16.5ZM16.5 8.0L17.1 7.2L15.5 5.9V8.0H16.5ZM21 11.4L21.6 12.2L22.6 11.4L21.6 10.6L21 11.4ZM16.5 14.9H15.5V16.9L17.1 15.7L16.5 14.9ZM16.5 12.4H17.5V11.4H16.5V12.4ZM7.5 12.4V11.4H6.5V12.4H7.5ZM7.5 14.9L6.8 15.7L8.5 16.9V14.9H7.5ZM6.8 7.2L2.3 10.6L3.6 12.2L8.1 8.7L6.8 7.2ZM8.5 10.4V8.0H6.5V10.4H8.5ZM16.5 9.4H7.5V11.4H16.5V9.4ZM17.5 10.4V8.0H15.5V10.4H17.5ZM15.8 8.7L20.3 12.2L21.6 10.6L17.1 7.2L15.8 8.7ZM20.3 10.6L15.8 14.1L17.1 15.7L21.6 12.2L20.3 10.6ZM17.5 14.9V12.4H15.5V14.9H17.5ZM7.5 13.4H16.5V11.4H7.5V13.4ZM8.5 14.9V12.4H6.5V14.9H8.5ZM2.3 12.2L6.8 15.7L8.1 14.1L3.6 10.6L2.3 12.2Z" fill="white"/>
1100
+ <path fill-rule="evenodd" d="M3 11.4L7.5 8.0V10.4H16.5V8.0L21 11.4L16.5 14.9V12.4H7.5V14.9L3 11.4Z" fill="black"/>
1101
+ </g>
1102
+ </g>
1103
+ <defs>
1104
+ <filter id="f" x="-1.6" y="3.9" width="27.2" height="16.9" filterUnits="userSpaceOnUse">
1105
+ ${filterStyle}
1106
+ </filter>
1107
+ </defs>
1108
+ </svg>
1109
+ `;
1110
+ const rotateSVG = `
1111
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
1112
+ <g filter="url(#f)">
1113
+ <g transform="rotate(135,12,12),rotate({{rotation}},12,12)">
1114
+ <path d="M20.4 8H21.4L20.8 7.1L17.3 2.6L17 2.1L16.6 2.6L13.1 7.1L12.5 8H13.5H15.4C14.9 11.8 11.8 14.9 8 15.4V13.5V12.5L7.1 13.1L2.6 16.6L2.1 17L2.6 17.3L7.1 20.8L8 21.4V20.4V18.4C13.5 17.9 17.9 13.5 18.4 8H20.4Z" stroke="white"/>
1115
+ <path fill-rule="evenodd" d="M17 3L20.4 7.5H17.9C17.7 13.1 13.1 17.7 7.5 17.9V20.4L3 17L7.5 13.5V15.9C12.0 15.7 15.7 12.0 15.9 7.5H13.5L17 3Z" fill="black"/>
1116
+ </g>
1117
+ </g>
1118
+ <defs>
1119
+ <filter id="f" x="-1.6" y="-0.6" width="27.1" height="27.1" filterUnits="userSpaceOnUse">
1120
+ ${filterStyle}
1121
+ </filter>
1122
+ </defs>
1123
+ </svg>
1124
+ `;
1125
+ const skewSVG = `
1126
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
1127
+ <g filter="url(#f)">
1128
+ <g transform="rotate(90,12,12),rotate({{rotation}},12,12)">
1129
+ <path d="M21 10.4L21 11.4L23.8 11.4L21.6 9.6L21 10.4ZM17 10.4V11.4L17 11.4L17 10.4ZM15.5 6L16.1 5.2L14.5 3.9V6H15.5ZM15.5 8.4V9.4H16.5V8.4H15.5ZM6 8.4V7.4H5V8.4H6ZM6 10.4H5V11.4H6V10.4ZM7 14.4V13.4L7 13.4L7 14.4ZM3 14.4L3 13.4L0.1 13.4L2.3 15.2L3 14.4ZM8.5 18.9L7.8 19.7L9.5 21.0V18.9H8.5ZM8.5 16.4V15.4H7.5V16.4H8.5ZM19 16.4V17.4H20V16.4H19ZM19 14.4H20V13.4H19V14.4ZM21 9.4L17 9.4L17 11.4L21 11.4L21 9.4ZM14.8 6.7L20.3 11.2L21.6 9.6L16.1 5.2L14.8 6.7ZM16.5 8.4V6H14.5V8.4H16.5ZM6 9.4H15.5V7.4H6V9.4ZM7 10.4V8.4H5V10.4H7ZM15.5 9.4H6V11.4H15.5V9.4ZM17 9.4H15.5V11.4H17V9.4ZM7 15.4H8.5V13.4H7V15.4ZM3 15.4L7 15.4L7 13.4L3 13.4L3 15.4ZM9.1 18.1L3.6 13.6L2.3 15.2L7.8 19.7L9.1 18.1ZM7.5 16.4V18.9H9.5V16.4H7.5ZM19 15.4H8.5V17.4H19V15.4ZM18 14.4V16.4H20V14.4H18ZM8.5 15.4H19V13.4H8.5V15.4Z" fill="white"/>
1130
+ <path fill-rule="evenodd" d="M17 10.4L21 10.4L15.5 6V8.4H6V10.4H15.5H17ZM8.5 14.4H7L3 14.4L8.5 18.9V16.4H19V14.4H8.5Z" fill="black"/>
1131
+ </g>
1132
+ </g>
1133
+ <defs>
1134
+ <filter x="-2.8" y="1.9" width="29.6" height="23.1" filterUnits="userSpaceOnUse" >
1135
+ ${filterStyle}
1136
+ </filter>
1137
+ </defs>
1138
+ </svg>
1139
+ `;
1140
+
1141
+ const config = {
1142
+ editSize: 'size',
1143
+ keyEvent: true,
1144
+ stroke: '#836DFF',
1145
+ strokeWidth: 2,
1146
+ pointFill: '#FFFFFF',
1147
+ pointSize: 10,
1148
+ pointRadius: 16,
1149
+ rotateGap: 45,
1150
+ buttonsDirection: 'bottom',
1151
+ buttonsMargin: 12,
1152
+ hideOnSmall: true,
1153
+ moveCursor: 'move',
1154
+ resizeCursor: { url: resizeSVG, x: 12, y: 12 },
1155
+ rotateCursor: { url: rotateSVG, x: 12, y: 12 },
1156
+ skewCursor: { url: skewSVG, x: 12, y: 12 },
1157
+ selector: true,
1158
+ hover: true,
1159
+ select: 'press',
1160
+ openInner: 'double',
1161
+ boxSelect: true,
1162
+ moveable: true,
1163
+ resizeable: true,
1164
+ rotateable: true,
1165
+ skewable: true
248
1166
  };
249
1167
 
250
- const { left, right } = IDirection8;
251
- const LineTool = {
252
- name: 'LineTool',
253
- getMirrorData(_editor) {
254
- return {
255
- x: 0,
256
- y: 0
257
- };
1168
+ function simulate(editor) {
1169
+ const { simulateTarget, leafList: targetList } = editor;
1170
+ const { x, y, width, height } = new Bounds().setListWithFn(targetList.list, (leaf) => leaf.worldBoxBounds);
1171
+ const parent = simulateTarget.parent = targetList.list[0].leafer.zoomLayer;
1172
+ const { scaleX, scaleY, e: worldX, f: worldY } = parent.__world;
1173
+ simulateTarget.reset({ x: (x - worldX) / scaleX, y: (y - worldY) / scaleY, width: width / scaleX, height: height / scaleY });
1174
+ }
1175
+
1176
+ function onTarget(editor, oldValue) {
1177
+ const { target } = editor;
1178
+ if (target) {
1179
+ editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target);
1180
+ }
1181
+ else {
1182
+ editor.leafList.reset();
1183
+ }
1184
+ editor.emitEvent(new EditorEvent(EditorEvent.SELECT, { editor, value: target, oldValue }));
1185
+ editor.checkOpenedGroups();
1186
+ if (editor.editing) {
1187
+ editor.waitLeafer(() => {
1188
+ if (editor.multiple)
1189
+ simulate(editor);
1190
+ updateMoveCursor(editor);
1191
+ editor.updateEditTool();
1192
+ editor.update();
1193
+ editor.listenTargetEvents();
1194
+ });
1195
+ }
1196
+ else {
1197
+ editor.updateEditTool();
1198
+ editor.removeTargetEvents();
1199
+ }
1200
+ }
1201
+ function onHover(editor, oldValue) {
1202
+ editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }));
1203
+ }
1204
+
1205
+ const order = (a, b) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b);
1206
+ const reverseOrder = (a, b) => b.parent.children.indexOf(b) - a.parent.children.indexOf(a);
1207
+ const EditorHelper = {
1208
+ group(list, element, userGroup) {
1209
+ list.sort(reverseOrder);
1210
+ const { app, parent } = list[0];
1211
+ let group;
1212
+ if (userGroup && userGroup.add) {
1213
+ group = userGroup;
1214
+ }
1215
+ else {
1216
+ group = new Group(userGroup);
1217
+ }
1218
+ parent.addAt(group, parent.children.indexOf(list[0]));
1219
+ list.sort(order);
1220
+ const matrx = new Matrix(element.worldTransform);
1221
+ matrx.divideParent(parent.worldTransform);
1222
+ group.setTransform(matrx);
1223
+ group.editable = true;
1224
+ group.hitChildren = false;
1225
+ app.lockLayout();
1226
+ list.forEach(child => child.dropTo(group));
1227
+ app.unlockLayout();
1228
+ return group;
258
1229
  },
259
- resize(e) {
260
- const { direction, dragEvent, lockRatio, around } = e;
261
- const target = e.target;
262
- const fromPoint = { x: 0, y: 0 };
263
- const { toPoint } = target;
264
- target.rotation = 0;
265
- let { x, y } = dragEvent.getInnerMove(target);
266
- if (lockRatio) {
267
- if (Math.abs(x) > Math.abs(y)) {
268
- y = 0;
1230
+ ungroup(list) {
1231
+ const { app } = list[0];
1232
+ const ungroupList = [];
1233
+ app.lockLayout();
1234
+ list.forEach(leaf => {
1235
+ if (leaf.isBranch) {
1236
+ const { parent, children } = leaf;
1237
+ while (children.length) {
1238
+ ungroupList.push(children[0]);
1239
+ children[0].dropTo(parent, parent.children.indexOf(leaf));
1240
+ }
1241
+ leaf.remove();
269
1242
  }
270
1243
  else {
271
- x = 0;
1244
+ ungroupList.push(leaf);
272
1245
  }
273
- }
274
- if (direction === left) {
275
- fromPoint.x += x;
276
- fromPoint.y += y;
277
- if (around) {
278
- toPoint.x -= x;
279
- toPoint.y -= y;
280
- }
281
- }
282
- else {
283
- if (around) {
284
- fromPoint.x -= x;
285
- fromPoint.y -= y;
286
- }
287
- toPoint.x += x;
288
- toPoint.y += y;
289
- }
290
- target.getLocalPointByInner(fromPoint, null, null, true);
291
- target.getLocalPointByInner(toPoint, null, null, true);
292
- target.x = fromPoint.x;
293
- target.y = fromPoint.y;
294
- target.getInnerPointByLocal(toPoint, null, null, true);
295
- target.toPoint = toPoint;
1246
+ });
1247
+ app.unlockLayout();
1248
+ return ungroupList;
296
1249
  },
297
- rotate(e) {
298
- RectTool.rotate(e);
1250
+ toTop(list) {
1251
+ list.sort(order);
1252
+ list.forEach(leaf => {
1253
+ if (leaf.parent)
1254
+ leaf.parent.add(leaf);
1255
+ });
299
1256
  },
300
- update(editor) {
301
- const { rotatePoints, circle, resizeLines, resizePoints } = editor;
302
- RectTool.update(editor);
303
- for (let i = 0; i < 8; i++) {
304
- if (i < 4)
305
- resizeLines[i].visible = false;
306
- resizePoints[i].visible = rotatePoints[i].visible = i === left || i === right;
307
- }
308
- circle.visible = false;
1257
+ toBottom(list) {
1258
+ list.sort(reverseOrder);
1259
+ list.forEach(leaf => {
1260
+ if (leaf.parent)
1261
+ leaf.parent.addAt(leaf, 0);
1262
+ });
1263
+ }
1264
+ };
1265
+
1266
+ const debug = Debug.get('EditToolCreator');
1267
+ function registerEditTool() {
1268
+ return (target) => {
1269
+ EditToolCreator.register(target);
1270
+ };
1271
+ }
1272
+ const registerInnerEditor = registerEditTool;
1273
+ const EditToolCreator = {
1274
+ list: {},
1275
+ register(EditTool) {
1276
+ const { tag } = EditTool.prototype;
1277
+ list[tag] ? debug.repeat(tag) : (list[tag] = EditTool);
1278
+ },
1279
+ get(tag, editor) {
1280
+ return new list[tag](editor);
309
1281
  }
310
1282
  };
1283
+ const { list } = EditToolCreator;
311
1284
 
312
- class EditorResizeEvent extends Event {
1285
+ class InnerEditorEvent extends EditorEvent {
313
1286
  constructor(type, data) {
314
- super(type);
315
- if (data)
316
- Object.assign(this, data);
1287
+ super(type, data);
317
1288
  }
318
1289
  }
319
- EditorResizeEvent.RESIZE = 'editor.resize';
1290
+ InnerEditorEvent.BEFORE_OPEN = 'innerEditor.before_open';
1291
+ InnerEditorEvent.OPEN = 'innerEditor.open';
1292
+ InnerEditorEvent.BEFORE_CLOSE = 'innerEditor.before_close';
1293
+ InnerEditorEvent.CLOSE = 'innerEditor.close';
320
1294
 
321
- class EditorRotateEvent extends Event {
1295
+ class EditorGroupEvent extends EditorEvent {
322
1296
  constructor(type, data) {
323
- super(type);
324
- if (data)
325
- Object.assign(this, data);
1297
+ super(type, data);
326
1298
  }
327
1299
  }
328
- EditorRotateEvent.ROTATE = 'editor.rotate';
1300
+ EditorGroupEvent.GROUP = 'editor.group';
1301
+ EditorGroupEvent.BEFORE_UNGROUP = 'editor.before_ungroup';
1302
+ EditorGroupEvent.UNGROUP = 'editor.ungroup';
1303
+ EditorGroupEvent.OPEN = 'editor.open_group';
1304
+ EditorGroupEvent.CLOSE = 'editor.close_group';
329
1305
 
330
1306
  class Editor extends Group {
331
- get target() { return this._target; }
332
- set target(value) {
333
- this.__removeTargetEvents();
334
- this.visible = !!value;
335
- this._target = value;
336
- if (value)
337
- this.onTarget();
1307
+ get mergeConfig() {
1308
+ const { element, config } = this;
1309
+ return this.single && element.editConfig ? Object.assign(Object.assign({}, config), element.editConfig) : config;
338
1310
  }
1311
+ get list() { return this.leafList.list; }
1312
+ get editing() { return !!this.list.length; }
1313
+ get groupOpening() { return !!this.openedGroupList.length; }
1314
+ get multiple() { return this.list.length > 1; }
1315
+ get single() { return this.list.length === 1; }
1316
+ get dragging() { return this.editBox.dragging; }
1317
+ get element() { return this.multiple ? this.simulateTarget : this.list[0]; }
1318
+ get buttons() { return this.editBox.buttons; }
339
1319
  constructor(userConfig, data) {
340
1320
  super(data);
341
- this.config = {
342
- type: 'pc',
343
- stroke: '#836DFF',
344
- pointFill: '#FFFFFF',
345
- pointSize: 10,
346
- pointRadius: 10,
347
- rotateGap: 90,
348
- hideOnMove: false,
349
- moveCursor: 'move',
350
- resizeType: 'auto',
351
- resizeCursor: ['nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize', 'nwse-resize', 'ns-resize', 'nesw-resize', 'ew-resize'],
352
- rotateCursor: ['ne-resize', 'e-resize', 'se-resize', 's-resize', 'sw-resize', 'w-resize', 'nw-resize', 'n-resize'],
353
- resizeable: true,
354
- rotateable: true
355
- };
356
- this.resizePoints = [];
357
- this.rotatePoints = [];
358
- this.resizeLines = [];
359
- this.targetRect = new Rect({ hitFill: 'all', hitRadius: 5 });
360
- this.rect = new Polygon({ hittable: false, strokeAlign: 'center' });
361
- this.circle = new Rect({ around: 'center', hitRadius: 10 });
362
- this.__eventIds = [];
363
- this.__targetEventIds = [];
1321
+ this.config = config;
1322
+ this.leafList = new LeafList();
1323
+ this.openedGroupList = new LeafList();
1324
+ this.simulateTarget = new Rect({ visible: false });
1325
+ this.editBox = new EditBox(this);
1326
+ this.editToolList = {};
1327
+ this.selector = new EditSelect(this);
1328
+ this.editMask = new EditMask(this);
1329
+ this.targetEventIds = [];
364
1330
  if (userConfig)
365
1331
  this.config = DataHelper.default(userConfig, this.config);
366
- this.init();
1332
+ this.addMany(this.editMask, this.selector, this.editBox);
367
1333
  }
368
- init() {
369
- let rotatePoint, resizeLine, resizePoint;
370
- const { resizePoints, rotatePoints, resizeLines } = this;
371
- for (let i = 0; i < 8; i++) {
372
- rotatePoint = new Rect({ around: 'center', width: 30, height: 30, hitRadius: 10, hitFill: "all" });
373
- rotatePoints.push(rotatePoint);
374
- this.__listenPointEvents(rotatePoint, 'rotate', i);
375
- if (i % 2) {
376
- resizeLine = new Rect({ around: 'center', width: 10, height: 10, hitFill: "all" });
377
- resizeLines.push(resizeLine);
378
- this.__listenPointEvents(resizeLine, 'resize', i);
379
- }
380
- resizePoint = new Rect({ around: 'center', hitRadius: 5 });
381
- resizePoints.push(resizePoint);
382
- this.__listenPointEvents(resizePoint, 'resize', i);
383
- }
384
- this.__listenPointEvents(this.circle, 'rotate', 1);
385
- this.addMany(...rotatePoints, this.targetRect, this.rect, this.circle, ...resizeLines, ...resizePoints);
386
- this.__listenEvents();
1334
+ select(target) {
1335
+ this.target = target;
387
1336
  }
388
- onTarget() {
389
- this.tool = this.getTool(this.target);
390
- this.waitLeafer(() => {
391
- this.update();
392
- this.updateMoveCursor();
393
- this.__listenTargetEvents();
394
- });
1337
+ cancel() {
1338
+ this.target = null;
1339
+ }
1340
+ hasItem(item) {
1341
+ return this.leafList.has(item);
395
1342
  }
396
- getTool(value) {
397
- return (value.tag === 'Line' && value.resizeable) ? LineTool : RectTool;
1343
+ addItem(item) {
1344
+ if (!this.hasItem(item) && !item.locked)
1345
+ this.leafList.add(item), this.target = this.leafList.list;
1346
+ }
1347
+ removeItem(item) {
1348
+ if (this.hasItem(item))
1349
+ this.leafList.remove(item), this.target = this.leafList.list;
1350
+ }
1351
+ shiftItem(item) {
1352
+ this.hasItem(item) ? this.removeItem(item) : this.addItem(item);
398
1353
  }
399
1354
  update() {
400
- if (!this.target)
401
- return;
402
- this.tool.update(this);
1355
+ if (this.editing) {
1356
+ if (this.innerEditing)
1357
+ this.innerEditor.update();
1358
+ this.editTool.update();
1359
+ this.selector.update();
1360
+ }
403
1361
  }
404
- onDrag(e) {
405
- const { resizeable, rotateable } = this.config;
406
- if (e.metaKey || e.ctrlKey || !resizeable) {
407
- if (rotateable)
408
- this.onRotate(e);
1362
+ updateEditBox() {
1363
+ if (this.multiple)
1364
+ simulate(this);
1365
+ this.update();
1366
+ }
1367
+ updateEditTool() {
1368
+ const tool = this.editTool;
1369
+ if (tool) {
1370
+ this.editBox.unload();
1371
+ tool.unload();
1372
+ this.editTool = null;
409
1373
  }
410
- else {
411
- this.onResize(e);
1374
+ if (this.editing) {
1375
+ const tag = this.single ? this.list[0].editOuter : 'EditTool';
1376
+ this.editTool = this.editToolList[tag] = this.editToolList[tag] || EditToolCreator.get(tag, this);
1377
+ this.editBox.load();
1378
+ this.editTool.load();
412
1379
  }
413
1380
  }
1381
+ getEditSize(_ui) {
1382
+ return this.mergeConfig.editSize;
1383
+ }
414
1384
  onMove(e) {
415
- const { target } = this;
416
- const { x, y } = e.getLocalMove(target);
1385
+ const total = { x: e.totalX, y: e.totalY };
417
1386
  if (e.shiftKey) {
418
- if (Math.abs(x) > Math.abs(y)) {
419
- target.x += x;
420
- }
421
- else {
422
- target.y += y;
1387
+ if (Math.abs(total.x) > Math.abs(total.y))
1388
+ total.y = 0;
1389
+ else
1390
+ total.x = 0;
1391
+ }
1392
+ this.move(DragEvent.getValidMove(this.element, this.dragStartPoint, total));
1393
+ }
1394
+ onScale(e) {
1395
+ const { element } = this;
1396
+ if (e instanceof ZoomEvent) {
1397
+ if (this.mergeConfig.resizeable === 'zoom') {
1398
+ e.stop();
1399
+ this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
423
1400
  }
424
1401
  }
425
1402
  else {
426
- target.x += x;
427
- target.y += y;
1403
+ const { direction } = e.current;
1404
+ let { around, lockRatio } = this.mergeConfig;
1405
+ if (e.shiftKey || element.lockRatio)
1406
+ lockRatio = true;
1407
+ const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
1408
+ if (this.editTool.onScaleWithDrag) {
1409
+ data.drag = e;
1410
+ this.scaleWithDrag(data);
1411
+ }
1412
+ else {
1413
+ this.scaleOf(data.origin, data.scaleX, data.scaleY);
1414
+ }
428
1415
  }
429
1416
  }
430
1417
  onRotate(e) {
431
- const { target } = this;
432
- const { rotateGap } = this.config;
433
- const { x, y, width, height } = target.boxBounds;
434
- const origin = { x: x + width / 2, y: y + height / 2 };
435
- let rotation;
1418
+ const { skewable, around, rotateGap } = this.mergeConfig;
1419
+ const { direction, name } = e.current;
1420
+ if (skewable && name === 'resize-line')
1421
+ return this.onSkew(e);
1422
+ const { element } = this;
1423
+ let origin, rotation;
436
1424
  if (e instanceof RotateEvent) {
437
- rotation = e.rotation;
1425
+ if (this.mergeConfig.rotateable === 'rotate') {
1426
+ e.stop();
1427
+ rotation = e.rotation, origin = element.getInnerPoint(e);
1428
+ }
1429
+ else
1430
+ return;
438
1431
  }
439
1432
  else {
440
- const point = e;
441
- const last = { x: point.x - e.moveX, y: point.y - e.moveY };
442
- rotation = PointHelper.getChangeAngle(last, target.getWorldPoint(origin), point);
443
- }
444
- rotation = MathHelper.getGapRotation(target.rotation + rotation, rotateGap) - target.rotation;
445
- const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { editor: this, target, origin, rotation });
446
- this.tool.rotate(event);
447
- target.emitEvent(event);
448
- }
449
- onResize(e) {
450
- const { target } = this;
451
- const { __direction } = e.current.__;
452
- let { resizeType, around, lockRatio } = this.config;
453
- if (e.shiftKey)
454
- lockRatio = true;
455
- if (e.altKey && !around)
456
- around = 'center';
457
- if (resizeType === 'auto')
458
- resizeType = target.resizeable ? 'size' : 'scale';
459
- const data = getResizeData(target.boxBounds, __direction, e.getInnerMove(this.targetRect), lockRatio, around);
460
- const event = new EditorResizeEvent(EditorResizeEvent.RESIZE, Object.assign(Object.assign({}, data), { target, editor: this, dragEvent: e, resizeType }));
461
- this.tool.resize(event);
462
- target.emitEvent(event);
463
- }
464
- updateMoveCursor() {
465
- this.targetRect.cursor = this.config.moveCursor;
1433
+ const last = { x: e.x - e.moveX, y: e.y - e.moveY };
1434
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
1435
+ rotation = data.rotation;
1436
+ origin = data.origin;
1437
+ }
1438
+ rotation = MathHelper.getGapRotation(rotation, rotateGap, element.rotation);
1439
+ if (!rotation)
1440
+ return;
1441
+ if (element.scaleX * element.scaleY < 0)
1442
+ rotation = -rotation;
1443
+ this.rotateOf(origin, MathHelper.float(rotation, 2));
466
1444
  }
467
- __listenEvents() {
468
- this.__eventIds = [
469
- this.targetRect.on_(DragEvent.START, () => { this.opacity = this.config.hideOnMove ? 0 : 1; }),
470
- this.targetRect.on_(DragEvent.DRAG, this.onMove, this),
471
- this.targetRect.on_(DragEvent.END, () => { this.opacity = 1; }),
472
- this.targetRect.on_(PointerEvent.ENTER, this.updateMoveCursor, this)
473
- ];
1445
+ onSkew(e) {
1446
+ const { element } = this;
1447
+ const { around } = this.mergeConfig;
1448
+ const { origin, skewX, skewY } = EditDataHelper.getSkewData(element.boxBounds, e.current.direction, e.getInnerMove(element), EditDataHelper.getAround(around, e.altKey));
1449
+ if (!skewX && !skewY)
1450
+ return;
1451
+ this.skewOf(origin, skewX, skewY);
474
1452
  }
475
- __removeListenEvents() {
476
- this.targetRect.off_(this.__eventIds);
477
- this.__eventIds.length = 0;
1453
+ move(x, y = 0) {
1454
+ if (!this.mergeConfig.moveable || this.element.locked)
1455
+ return;
1456
+ const { element } = this;
1457
+ const world = element.getWorldPointByLocal(typeof x === 'object' ? Object.assign({}, x) : { x, y }, null, true);
1458
+ const event = new EditorMoveEvent(EditorMoveEvent.MOVE, { target: element, editor: this, moveX: world.x, moveY: world.y });
1459
+ this.editTool.onMove(event);
1460
+ this.emitEvent(event);
1461
+ if (this.multiple)
1462
+ element.move(x, y);
478
1463
  }
479
- __listenPointEvents(point, type, direction) {
480
- point.__.__direction = direction;
481
- const resize = point.__.__isResizePoint = type === 'resize';
482
- point.on_(DragEvent.DRAG, resize ? this.onDrag : this.onRotate, this);
483
- point.on_(PointerEvent.LEAVE, () => this.enterPoint = null);
484
- point.on_(PointerEvent.ENTER, (e) => { this.enterPoint = point; updateCursor(this, e); });
1464
+ scaleWithDrag(data) {
1465
+ if (!this.mergeConfig.resizeable || this.element.locked)
1466
+ return;
1467
+ const { element } = this;
1468
+ const worldOrigin = element.getWorldPoint(data.origin);
1469
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
1470
+ this.editTool.onScaleWithDrag(event);
1471
+ this.emitEvent(event);
1472
+ }
1473
+ scaleOf(origin, scaleX, scaleY = scaleX, _resize) {
1474
+ if (!this.mergeConfig.resizeable || this.element.locked)
1475
+ return;
1476
+ const { element } = this;
1477
+ const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
1478
+ let transform;
1479
+ if (this.multiple) {
1480
+ const oldMatrix = new Matrix(element.worldTransform);
1481
+ element.scaleOf(origin, scaleX, scaleY);
1482
+ transform = new Matrix(element.worldTransform).divide(oldMatrix);
1483
+ }
1484
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
1485
+ this.editTool.onScale(event);
1486
+ this.emitEvent(event);
1487
+ }
1488
+ rotateOf(origin, rotation) {
1489
+ if (!this.mergeConfig.rotateable || this.element.locked)
1490
+ return;
1491
+ const { element } = this;
1492
+ const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
1493
+ let transform;
1494
+ if (this.multiple) {
1495
+ const oldMatrix = new Matrix(element.worldTransform);
1496
+ element.rotateOf(origin, rotation);
1497
+ transform = new Matrix(element.worldTransform).divide(oldMatrix);
1498
+ }
1499
+ const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
1500
+ this.editTool.onRotate(event);
1501
+ this.emitEvent(event);
1502
+ }
1503
+ skewOf(origin, skewX, skewY = 0, _resize) {
1504
+ if (!this.mergeConfig.skewable || this.element.locked)
1505
+ return;
1506
+ const { element } = this;
1507
+ const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
1508
+ let transform;
1509
+ if (this.multiple) {
1510
+ const oldMatrix = new Matrix(element.worldTransform);
1511
+ element.skewOf(origin, skewX, skewY);
1512
+ transform = new Matrix(element.worldTransform).divide(oldMatrix);
1513
+ }
1514
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
1515
+ target: element, editor: this, skewX, skewY, transform, worldOrigin
1516
+ });
1517
+ this.editTool.onSkew(event);
1518
+ this.emitEvent(event);
1519
+ }
1520
+ group(userGroup) {
1521
+ if (this.multiple) {
1522
+ this.target = EditorHelper.group(this.list, this.element, userGroup);
1523
+ this.emitGroupEvent(EditorGroupEvent.GROUP, this.target);
1524
+ }
1525
+ return this.target;
1526
+ }
1527
+ ungroup() {
1528
+ const { list } = this;
1529
+ if (list.length) {
1530
+ list.forEach(item => item.isBranch && this.emitGroupEvent(EditorGroupEvent.BEFORE_UNGROUP, item));
1531
+ this.target = EditorHelper.ungroup(list);
1532
+ list.forEach(item => item.isBranch && this.emitGroupEvent(EditorGroupEvent.UNGROUP, item));
1533
+ }
1534
+ return this.list;
1535
+ }
1536
+ openGroup(group) {
1537
+ this.openedGroupList.add(group);
1538
+ group.hitChildren = true;
1539
+ this.emitGroupEvent(EditorGroupEvent.OPEN, group);
1540
+ }
1541
+ closeGroup(group) {
1542
+ this.openedGroupList.remove(group);
1543
+ group.hitChildren = false;
1544
+ this.emitGroupEvent(EditorGroupEvent.CLOSE, group);
1545
+ }
1546
+ checkOpenedGroups() {
1547
+ const opened = this.openedGroupList;
1548
+ if (opened.length) {
1549
+ let { list } = opened;
1550
+ if (this.editing)
1551
+ list = [], opened.forEach(item => this.list.every(leaf => !LeafHelper.hasParent(leaf, item)) && list.push(item));
1552
+ list.forEach(item => this.closeGroup(item));
1553
+ }
1554
+ if (this.editing && !this.selector.dragging)
1555
+ this.checkDeepSelect();
1556
+ }
1557
+ checkDeepSelect() {
1558
+ let parent, { list } = this;
1559
+ for (let i = 0; i < list.length; i++) {
1560
+ parent = list[i].parent;
1561
+ while (parent && !parent.hitChildren) {
1562
+ this.openGroup(parent);
1563
+ parent = parent.parent;
1564
+ }
1565
+ }
1566
+ }
1567
+ emitGroupEvent(type, group) {
1568
+ const event = new EditorGroupEvent(type, { editTarget: group });
1569
+ this.emitEvent(event);
1570
+ group.emitEvent(event);
1571
+ }
1572
+ openInnerEditor(target) {
1573
+ if (target)
1574
+ this.target = target;
1575
+ if (this.single) {
1576
+ const editTarget = this.element;
1577
+ const tag = editTarget.editInner;
1578
+ if (tag && EditToolCreator.list[tag]) {
1579
+ this.editTool.unload();
1580
+ this.innerEditing = true;
1581
+ this.innerEditor = this.editToolList[tag] || EditToolCreator.get(tag, this);
1582
+ this.innerEditor.editTarget = editTarget;
1583
+ this.emitInnerEvent(InnerEditorEvent.BEFORE_OPEN);
1584
+ this.innerEditor.load();
1585
+ this.emitInnerEvent(InnerEditorEvent.OPEN);
1586
+ }
1587
+ }
1588
+ }
1589
+ closeInnerEditor() {
1590
+ if (this.innerEditing) {
1591
+ this.innerEditing = false;
1592
+ this.emitInnerEvent(InnerEditorEvent.BEFORE_CLOSE);
1593
+ this.innerEditor.unload();
1594
+ this.emitInnerEvent(InnerEditorEvent.CLOSE);
1595
+ this.editTool.load();
1596
+ this.innerEditor = null;
1597
+ }
1598
+ }
1599
+ emitInnerEvent(type) {
1600
+ const { innerEditor } = this;
1601
+ const { editTarget } = innerEditor;
1602
+ const event = new InnerEditorEvent(type, { editTarget, innerEditor });
1603
+ this.emitEvent(event);
1604
+ editTarget.emitEvent(event);
1605
+ }
1606
+ lock() {
1607
+ this.list.forEach(leaf => leaf.locked = true);
1608
+ this.update();
1609
+ }
1610
+ unlock() {
1611
+ this.list.forEach(leaf => leaf.locked = false);
1612
+ this.update();
1613
+ }
1614
+ toTop() {
1615
+ if (this.list.length) {
1616
+ EditorHelper.toTop(this.list);
1617
+ this.leafList.update();
1618
+ }
1619
+ }
1620
+ toBottom() {
1621
+ if (this.list.length) {
1622
+ EditorHelper.toBottom(this.list);
1623
+ this.leafList.update();
1624
+ }
485
1625
  }
486
- __listenTargetEvents() {
487
- if (this.target) {
488
- const { leafer } = this.target;
489
- this.__targetEventIds = [
1626
+ listenTargetEvents() {
1627
+ if (!this.targetEventIds.length) {
1628
+ const { leafer } = this.list[0];
1629
+ this.targetEventIds = [
490
1630
  leafer.on_(RenderEvent.START, this.update, this),
491
- leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); })
1631
+ leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); }),
1632
+ leafer.on_(KeyEvent.DOWN, this.editBox.onArrow, this.editBox)
492
1633
  ];
493
1634
  }
494
1635
  }
495
- __removeTargetEvents() {
496
- if (this.__targetEventIds.length) {
497
- const { leafer } = this.target;
498
- if (leafer)
499
- leafer.off_(this.__targetEventIds);
500
- this.__targetEventIds.length = 0;
1636
+ removeTargetEvents() {
1637
+ const { targetEventIds } = this;
1638
+ if (targetEventIds.length) {
1639
+ this.off_(targetEventIds);
1640
+ targetEventIds.length = 0;
501
1641
  }
502
1642
  }
503
1643
  destroy() {
504
- this.__removeListenEvents();
505
- this._target = null;
506
- super.destroy();
1644
+ if (!this.destroyed) {
1645
+ this.simulateTarget.destroy();
1646
+ Object.values(this.editToolList).forEach(item => item.destroy());
1647
+ this.editToolList = {};
1648
+ this.target = this.hoverTarget = this.simulateTarget = this.editTool = this.innerEditor = null;
1649
+ super.destroy();
1650
+ }
1651
+ }
1652
+ }
1653
+ __decorate([
1654
+ targetAttr(onHover)
1655
+ ], Editor.prototype, "hoverTarget", void 0);
1656
+ __decorate([
1657
+ targetAttr(onTarget)
1658
+ ], Editor.prototype, "target", void 0);
1659
+
1660
+ class InnerEditor {
1661
+ static registerInnerEditor() {
1662
+ EditToolCreator.register(this);
1663
+ }
1664
+ get tag() { return 'InnerEditor'; }
1665
+ get editBox() { return this.editor.editBox; }
1666
+ constructor(editor) {
1667
+ this.editor = editor;
1668
+ this.create();
1669
+ }
1670
+ onCreate() { }
1671
+ create() {
1672
+ this.view = new Group();
1673
+ this.onCreate();
1674
+ }
1675
+ onLoad() { }
1676
+ load() {
1677
+ this.editor.selector.hittable = this.editor.app.tree.hitChildren = false;
1678
+ this.onLoad();
1679
+ }
1680
+ onUpdate() { }
1681
+ update() { this.onUpdate(); }
1682
+ onUnload() { }
1683
+ unload() {
1684
+ this.editor.selector.hittable = this.editor.app.tree.hitChildren = true;
1685
+ this.onUnload();
1686
+ }
1687
+ onDestroy() { }
1688
+ destroy() {
1689
+ this.onDestroy();
1690
+ if (this.editor) {
1691
+ if (this.view)
1692
+ this.view.destroy();
1693
+ if (this.eventIds)
1694
+ this.editor.off_(this.eventIds);
1695
+ this.editor = this.view = this.eventIds = null;
1696
+ }
507
1697
  }
508
1698
  }
509
1699
 
510
- export { Editor, EditorResizeEvent, EditorRotateEvent, LineTool, RectTool };
1700
+ let EditTool = class EditTool extends InnerEditor {
1701
+ static registerEditTool() {
1702
+ EditToolCreator.register(this);
1703
+ }
1704
+ get tag() { return 'EditTool'; }
1705
+ onMove(e) {
1706
+ const { moveX, moveY, editor } = e;
1707
+ const { app, list } = editor;
1708
+ app.lockLayout();
1709
+ list.forEach(target => {
1710
+ target.moveWorld(moveX, moveY);
1711
+ });
1712
+ app.unlockLayout();
1713
+ }
1714
+ onScale(e) {
1715
+ const { scaleX, scaleY, transform, worldOrigin, editor } = e;
1716
+ const { app, list } = editor;
1717
+ app.lockLayout();
1718
+ list.forEach(target => {
1719
+ const resize = editor.getEditSize(target) !== 'scale';
1720
+ if (transform) {
1721
+ target.transformWorld(transform, resize);
1722
+ }
1723
+ else {
1724
+ target.scaleOfWorld(worldOrigin, scaleX, scaleY, resize);
1725
+ }
1726
+ });
1727
+ app.unlockLayout();
1728
+ }
1729
+ onRotate(e) {
1730
+ const { rotation, transform, worldOrigin, editor } = e;
1731
+ const { app, list } = editor;
1732
+ app.lockLayout();
1733
+ list.forEach(target => {
1734
+ const resize = editor.getEditSize(target) !== 'scale';
1735
+ if (transform) {
1736
+ target.transformWorld(transform, resize);
1737
+ }
1738
+ else {
1739
+ target.rotateOfWorld(worldOrigin, rotation);
1740
+ }
1741
+ });
1742
+ app.unlockLayout();
1743
+ }
1744
+ onSkew(e) {
1745
+ const { skewX, skewY, transform, worldOrigin, editor } = e;
1746
+ const { app, list } = editor;
1747
+ app.lockLayout();
1748
+ list.forEach(target => {
1749
+ const resize = editor.getEditSize(target) !== 'scale';
1750
+ if (transform) {
1751
+ target.transformWorld(transform, resize);
1752
+ }
1753
+ else {
1754
+ target.skewOfWorld(worldOrigin, skewX, skewY, resize);
1755
+ }
1756
+ });
1757
+ app.unlockLayout();
1758
+ }
1759
+ load() {
1760
+ this.editBox.view.visible = true;
1761
+ this.onLoad();
1762
+ }
1763
+ update() {
1764
+ const { editor, editBox } = this;
1765
+ const { simulateTarget, element } = editor;
1766
+ if (editor.multiple)
1767
+ simulateTarget.parent.updateLayout();
1768
+ const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true);
1769
+ editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY });
1770
+ editBox.update({ x: 0, y: 0, width, height });
1771
+ this.onUpdate();
1772
+ }
1773
+ unload() {
1774
+ this.editBox.view.visible = false;
1775
+ this.onUnload();
1776
+ }
1777
+ };
1778
+ EditTool = __decorate([
1779
+ registerEditTool()
1780
+ ], EditTool);
1781
+
1782
+ const { left, right } = Direction9;
1783
+ const { move, copy } = PointHelper;
1784
+ let LineEditTool = class LineEditTool extends EditTool {
1785
+ constructor() {
1786
+ super(...arguments);
1787
+ this.scaleOfEvent = true;
1788
+ }
1789
+ get tag() { return 'LineEditTool'; }
1790
+ onScaleWithDrag(e) {
1791
+ const { drag, direction, lockRatio, around } = e;
1792
+ const line = e.target;
1793
+ const isDragFrom = direction === left;
1794
+ if (line.pathInputed) {
1795
+ const { path } = line.__;
1796
+ const { from, to } = this.getFromToByPath(path);
1797
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio));
1798
+ path[1] = from.x, path[2] = from.y;
1799
+ path[4] = to.x, path[5] = to.y;
1800
+ line.path = path;
1801
+ }
1802
+ else if (line.points) {
1803
+ const { points } = line;
1804
+ const { from, to } = this.getFromToByPoints(points);
1805
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio));
1806
+ points[0] = from.x, points[1] = from.y;
1807
+ points[2] = to.x, points[3] = to.y;
1808
+ line.points = points;
1809
+ }
1810
+ else {
1811
+ const from = getPointData();
1812
+ const { toPoint } = line;
1813
+ line.rotation = 0;
1814
+ this.dragPoint(from, toPoint, isDragFrom, around, this.getInnerMove(line, drag, lockRatio));
1815
+ line.getLocalPointByInner(from, null, null, true);
1816
+ line.getLocalPointByInner(toPoint, null, null, true);
1817
+ line.x = from.x;
1818
+ line.y = from.y;
1819
+ line.getInnerPointByLocal(toPoint, null, null, true);
1820
+ line.toPoint = toPoint;
1821
+ }
1822
+ }
1823
+ getInnerMove(ui, event, lockRatio) {
1824
+ const movePoint = event.getInnerMove(ui);
1825
+ if (lockRatio) {
1826
+ if (Math.abs(movePoint.x) > Math.abs(movePoint.y)) {
1827
+ movePoint.y = 0;
1828
+ }
1829
+ else {
1830
+ movePoint.x = 0;
1831
+ }
1832
+ }
1833
+ return movePoint;
1834
+ }
1835
+ getFromToByPath(path) {
1836
+ return {
1837
+ from: { x: path[1], y: path[2] },
1838
+ to: { x: path[4], y: path[5] }
1839
+ };
1840
+ }
1841
+ getFromToByPoints(points) {
1842
+ return {
1843
+ from: { x: points[0], y: points[1] },
1844
+ to: { x: points[2], y: points[3] }
1845
+ };
1846
+ }
1847
+ dragPoint(fromPoint, toPoint, isDragFrom, around, movePoint) {
1848
+ const { x, y } = movePoint;
1849
+ if (isDragFrom) {
1850
+ move(fromPoint, x, y);
1851
+ if (around)
1852
+ move(toPoint, -x, -y);
1853
+ }
1854
+ else {
1855
+ if (around)
1856
+ move(fromPoint, -x, -y);
1857
+ move(toPoint, x, y);
1858
+ }
1859
+ }
1860
+ onSkew(_e) {
1861
+ }
1862
+ onUpdate() {
1863
+ const { editBox } = this, { rotatePoints, resizeLines, resizePoints, rect } = editBox;
1864
+ const line = this.editor.element;
1865
+ let fromTo, leftOrRight;
1866
+ if (line.pathInputed)
1867
+ fromTo = this.getFromToByPath(line.__.path);
1868
+ else if (line.points)
1869
+ fromTo = this.getFromToByPoints(line.__.points);
1870
+ if (fromTo) {
1871
+ const { from, to } = fromTo;
1872
+ line.innerToWorld(from, from, false, editBox);
1873
+ line.innerToWorld(to, to, false, editBox);
1874
+ rect.pen.clearPath().moveTo(from.x, from.y).lineTo(to.x, to.y);
1875
+ copy(resizePoints[7], from);
1876
+ copy(rotatePoints[7], from);
1877
+ copy(resizePoints[3], to);
1878
+ copy(rotatePoints[3], to);
1879
+ }
1880
+ for (let i = 0; i < 8; i++) {
1881
+ if (i < 4)
1882
+ resizeLines[i].visible = false;
1883
+ leftOrRight = i === left || i === right;
1884
+ resizePoints[i].visible = leftOrRight;
1885
+ rotatePoints[i].visible = fromTo ? false : leftOrRight;
1886
+ }
1887
+ }
1888
+ };
1889
+ LineEditTool = __decorate([
1890
+ registerEditTool()
1891
+ ], LineEditTool);
1892
+
1893
+ Creator.editor = function (options) { return new Editor(options); };
1894
+ UI.setEditConfig = function (config) {
1895
+ defineKey(this.prototype, 'editConfig', {
1896
+ get() { return typeof config === 'function' ? config(this) : config; }
1897
+ });
1898
+ };
1899
+ UI.setEditOuter = function (toolName) {
1900
+ defineKey(this.prototype, 'editOuter', {
1901
+ get() { return typeof toolName === 'string' ? toolName : toolName(this); }
1902
+ });
1903
+ };
1904
+ UI.setEditInner = function (editorName) {
1905
+ defineKey(this.prototype, 'editInner', {
1906
+ get() { return typeof editorName === 'string' ? editorName : editorName(this); }
1907
+ });
1908
+ };
1909
+
1910
+ export { EditBox, EditDataHelper, EditPoint, EditSelect, EditSelectHelper, EditTool, EditToolCreator, Editor, EditorEvent, EditorGroupEvent, EditorHelper, EditorMoveEvent, EditorRotateEvent, EditorScaleEvent, EditorSkewEvent, InnerEditor, InnerEditorEvent, LineEditTool, PathScaler, SelectArea, Stroker, registerEditTool, registerInnerEditor, scaleResize, scaleResizeFontSize, scaleResizeGroup, scaleResizePath, scaleResizePoints };