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