@leafer-in/editor 1.0.0-beta.18 → 1.0.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,522 @@
1
- import { MatrixHelper, Bounds, Matrix, Event, Group, Rect, Polygon, DataHelper, RotateEvent, PointHelper, MathHelper, DragEvent, PointerEvent, RenderEvent, KeyEvent } from '@leafer-ui/core';
1
+ import { PathCommandMap, Leaf, Path, Line, Polygon, MatrixHelper, Group, Box } from '@leafer-ui/draw';
2
+ import { Event, defineKey, MatrixHelper as MatrixHelper$1, UI, Paint, Group as Group$1, Rect, Answer, Bounds, LeafList, PointerEvent, DragEvent, MoveEvent, ZoomEvent, PointHelper, AroundHelper, Box as Box$1, LeafHelper, getPointData, Line as Line$1, Matrix, DataHelper, RotateEvent, MathHelper, RenderEvent, KeyEvent, Creator } 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
+ }
72
+ }
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;
78
+ }
79
+ }
80
+ };
81
+ const { scalePoints } = PathScaler;
82
+
83
+ Leaf.prototype.scaleResize = function (scaleX, scaleY = scaleX, noResize) {
84
+ const data = this;
85
+ if (noResize) {
86
+ data.scaleX *= scaleX;
87
+ data.scaleY *= scaleY;
88
+ }
89
+ else {
90
+ if (scaleX < 0)
91
+ data.scaleX *= -1, scaleX = -scaleX;
92
+ if (scaleY < 0)
93
+ data.scaleY *= -1, scaleY = -scaleY;
94
+ this.__scaleResize(scaleX, scaleY);
95
+ }
96
+ };
97
+ function scaleResize(leaf, scaleX, scaleY) {
98
+ if (scaleX !== 1)
99
+ leaf.width *= scaleX;
100
+ if (scaleY !== 1)
101
+ leaf.height *= scaleY;
102
+ }
103
+ Leaf.prototype.__scaleResize = function (scaleX, scaleY) {
104
+ scaleResize(this, scaleX, scaleY);
105
+ };
106
+ Path.prototype.__scaleResize = function (scaleX, scaleY) {
107
+ PathScaler.scale(this.__.path, scaleX, scaleY);
108
+ this.path = this.__.path;
109
+ };
110
+ Line.prototype.__scaleResize = function (scaleX, scaleY) {
111
+ if (this.points) {
112
+ PathScaler.scalePoints(this.__.points, scaleX, scaleY);
113
+ this.points = this.__.points;
114
+ }
115
+ else {
116
+ const point = this.toPoint;
117
+ point.x *= scaleX;
118
+ point.y *= scaleY;
119
+ this.toPoint = point;
120
+ }
121
+ };
122
+ Polygon.prototype.__scaleResize = function (scaleX, scaleY) {
123
+ if (this.points) {
124
+ PathScaler.scalePoints(this.__.points, scaleX, scaleY);
125
+ this.points = this.__.points;
126
+ }
127
+ else {
128
+ scaleResize(this, scaleX, scaleY);
129
+ }
130
+ };
131
+ const matrix$1 = MatrixHelper.get();
132
+ function groupScaleResize(group, scaleX, scaleY) {
133
+ const { children } = group;
134
+ for (let i = 0; i < children.length; i++) {
135
+ matrix$1.a = scaleX;
136
+ matrix$1.d = scaleY;
137
+ children[i].transform(matrix$1, true);
138
+ }
139
+ }
140
+ Group.prototype.__scaleResize = function (scaleX, scaleY) {
141
+ groupScaleResize(this, scaleX, scaleY);
142
+ };
143
+ Box.prototype.__scaleResize = function (scaleX, scaleY) {
144
+ if (this.__.__autoBounds && this.children.length) {
145
+ groupScaleResize(this, scaleX, scaleY);
146
+ }
147
+ else {
148
+ scaleResize(this, scaleX, scaleY);
149
+ }
150
+ };
151
+
152
+ /******************************************************************************
153
+ Copyright (c) Microsoft Corporation.
154
+
155
+ Permission to use, copy, modify, and/or distribute this software for any
156
+ purpose with or without fee is hereby granted.
157
+
158
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
159
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
160
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
161
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
162
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
163
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
164
+ PERFORMANCE OF THIS SOFTWARE.
165
+ ***************************************************************************** */
166
+ /* global Reflect, Promise, SuppressedError, Symbol */
167
+
168
+
169
+ function __decorate(decorators, target, key, desc) {
170
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
171
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
172
+ 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;
173
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
174
+ }
175
+
176
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
177
+ var e = new Error(message);
178
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
179
+ };
180
+
181
+ class EditorEvent extends Event {
182
+ constructor(type, data) {
183
+ super(type);
184
+ if (data)
185
+ Object.assign(this, data);
186
+ }
187
+ }
188
+ EditorEvent.SELECT = 'editor.select';
189
+ EditorEvent.HOVER = 'editor.hover';
190
+
191
+ class EditorMoveEvent extends EditorEvent {
192
+ constructor(type, data) {
193
+ super(type, data);
194
+ }
195
+ }
196
+ EditorMoveEvent.MOVE = 'editor.move';
197
+
198
+ class EditorScaleEvent extends EditorEvent {
199
+ constructor(type, data) {
200
+ super(type, data);
201
+ }
202
+ }
203
+ EditorScaleEvent.SCALE = 'editor.scale';
204
+
205
+ class EditorRotateEvent extends EditorEvent {
206
+ constructor(type, data) {
207
+ super(type, data);
208
+ }
209
+ }
210
+ EditorRotateEvent.ROTATE = 'editor.rotate';
211
+
212
+ class EditorSkewEvent extends EditorEvent {
213
+ constructor(type, data) {
214
+ super(type, data);
215
+ }
216
+ }
217
+ EditorSkewEvent.SKEW = 'editor.skew';
218
+
219
+ function targetAttr(fn) {
220
+ return (target, key) => {
221
+ const privateKey = '_' + key;
222
+ defineKey(target, key, {
223
+ get() { return this[privateKey]; },
224
+ set(value) {
225
+ const old = this[privateKey];
226
+ if (old !== value)
227
+ this[privateKey] = value, fn(this, old);
228
+ }
229
+ });
230
+ };
231
+ }
232
+
233
+ const matrix = MatrixHelper$1.get();
234
+ const { abs } = Math;
235
+ const { copy, scale } = MatrixHelper$1;
236
+ class Stroker extends UI {
237
+ constructor() {
238
+ super();
239
+ this.list = [];
240
+ this.hittable = false;
241
+ this.strokeAlign = 'center';
242
+ }
243
+ setTarget(target, style) {
244
+ const { stroke, strokeWidth } = style;
245
+ this.set({ stroke, strokeWidth });
246
+ this.target = target;
247
+ }
248
+ __draw(canvas, options) {
249
+ const { list } = this;
250
+ if (list.length) {
251
+ let leaf;
252
+ const { stroke, strokeWidth } = this.__;
253
+ const { bounds } = options;
254
+ for (let i = 0; i < list.length; i++) {
255
+ leaf = list[i];
256
+ if (bounds && bounds.hit(leaf.__world, options.matrix)) {
257
+ let drewPath;
258
+ if (leaf.__.editSize === 'scale') {
259
+ const aScaleX = abs(leaf.__world.scaleX), aScaleY = abs(leaf.__world.scaleY);
260
+ if (aScaleX !== aScaleY) {
261
+ copy(matrix, leaf.__world);
262
+ scale(matrix, 1 / aScaleX, 1 / aScaleY);
263
+ canvas.setWorld(matrix, options.matrix);
264
+ canvas.beginPath();
265
+ this.__.strokeWidth = strokeWidth;
266
+ const { x, y, width, height } = leaf.__layout.boxBounds;
267
+ canvas.rect(x * aScaleX, y * aScaleY, width * aScaleX, height * aScaleY);
268
+ drewPath = true;
269
+ }
270
+ }
271
+ if (!drewPath) {
272
+ canvas.setWorld(leaf.__world, options.matrix);
273
+ canvas.beginPath();
274
+ leaf.__.__pathForRender ? leaf.__drawRenderPath(canvas) : leaf.__drawPathByBox(canvas);
275
+ this.__.strokeWidth = strokeWidth / abs(leaf.__world.scaleX);
276
+ }
277
+ typeof stroke === 'string' ? Paint.stroke(stroke, this, canvas) : Paint.strokes(stroke, this, canvas);
278
+ }
279
+ }
280
+ this.__.strokeWidth = strokeWidth;
281
+ }
282
+ }
283
+ destroy() {
284
+ this.target = null;
285
+ super.destroy();
286
+ }
287
+ }
288
+ __decorate([
289
+ targetAttr(onTarget$1)
290
+ ], Stroker.prototype, "target", void 0);
291
+ function onTarget$1(stroker) {
292
+ const value = stroker.target;
293
+ stroker.list = value ? (value instanceof Array ? value : [value]) : [];
294
+ stroker.forceUpdate();
295
+ }
296
+
297
+ class SelectArea extends Group$1 {
298
+ constructor(data) {
299
+ super(data);
300
+ this.strokeArea = new Rect({ strokeAlign: 'center' });
301
+ this.fillArea = new Rect();
302
+ this.visible = this.hittable = false;
303
+ this.addMany(this.fillArea, this.strokeArea);
304
+ }
305
+ setStyle(style, userStyle) {
306
+ const { visible, stroke, strokeWidth } = style;
307
+ this.visible = visible;
308
+ this.strokeArea.reset(Object.assign({ stroke, strokeWidth }, (userStyle || {})));
309
+ this.fillArea.reset({ visible: userStyle ? false : true, fill: stroke, opacity: 0.2 });
310
+ }
311
+ setBounds(bounds) {
312
+ this.strokeArea.set(bounds);
313
+ this.fillArea.set(bounds);
314
+ }
315
+ }
316
+
317
+ const { No, Yes, NoAndSkip, YesAndSkip } = Answer;
318
+ const EditSelectHelper = {
319
+ findOne(path) {
320
+ return path.list.find((leaf) => leaf.editable);
321
+ },
322
+ findBounds(leaf, bounds) {
323
+ if (leaf.__.hittable && leaf.__.visible && !leaf.__.locked && bounds.hit(leaf.__world)) {
324
+ if (leaf.__.editable) {
325
+ if (leaf.isBranch && !leaf.__.hitChildren) {
326
+ return leaf.__.hitSelf ? YesAndSkip : NoAndSkip;
327
+ }
328
+ else if (leaf.isFrame) {
329
+ return bounds.includes(leaf.__layout.boxBounds, leaf.__world) ? YesAndSkip : No;
330
+ }
331
+ else {
332
+ if (bounds.hit(leaf.__layout.boxBounds, leaf.__world) && leaf.__.hitSelf)
333
+ return Yes;
334
+ }
335
+ }
336
+ return No;
337
+ }
338
+ else {
339
+ return leaf.isBranch ? NoAndSkip : No;
340
+ }
341
+ }
342
+ };
343
+
344
+ const { findOne } = EditSelectHelper;
345
+ class EditSelect extends Group$1 {
346
+ get dragging() { return !!this.originList; }
347
+ get running() { return this.editor.hittable && this.editor.config.selector; }
348
+ get isMoveMode() { return this.app && this.app.interaction.moveMode; }
349
+ constructor(editor) {
350
+ super();
351
+ this.hoverStroker = new Stroker();
352
+ this.targetStroker = new Stroker();
353
+ this.bounds = new Bounds();
354
+ this.selectArea = new SelectArea();
355
+ this.__eventIds = [];
356
+ this.editor = editor;
357
+ this.addMany(this.targetStroker, this.hoverStroker, this.selectArea);
358
+ this.__listenEvents();
359
+ }
360
+ onHover() {
361
+ const { editor } = this;
362
+ if (this.running && !this.dragging && !editor.dragging) {
363
+ const { stroke, strokeWidth, hover } = editor.config;
364
+ this.hoverStroker.setTarget(hover ? this.editor.hoverTarget : null, { stroke, strokeWidth });
365
+ }
366
+ else {
367
+ this.hoverStroker.target = null;
368
+ }
369
+ }
370
+ onSelect() {
371
+ if (this.running) {
372
+ const { config, list } = this.editor;
373
+ const { stroke, strokeWidth } = config;
374
+ this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2) });
375
+ this.hoverStroker.target = null;
376
+ }
377
+ }
378
+ update() {
379
+ if (this.running)
380
+ this.targetStroker.forceUpdate();
381
+ }
382
+ onPointerMove(e) {
383
+ if (this.running && !this.isMoveMode) {
384
+ const find = e.shiftKey ? this.findDeepOne(e) : findOne(e.path);
385
+ this.editor.hoverTarget = this.editor.hasItem(find) ? null : find;
386
+ }
387
+ if (this.isMoveMode) {
388
+ this.editor.hoverTarget = null;
389
+ }
390
+ }
391
+ onBeforeDown(e) {
392
+ if (this.running && !this.isMoveMode && !e.middle) {
393
+ const find = this.lastDownLeaf = findOne(e.path);
394
+ if (find) {
395
+ if (e.shiftKey) {
396
+ this.editor.shiftItem(find);
397
+ }
398
+ else {
399
+ this.editor.target = find;
400
+ }
401
+ this.editor.updateLayout();
402
+ if (!find.locked)
403
+ this.app.interaction.updateDownData(null, { findList: [this.editor.editBox.rect] });
404
+ }
405
+ else if (this.allow(e.target)) {
406
+ if (!e.shiftKey)
407
+ this.editor.target = null;
408
+ }
409
+ }
410
+ }
411
+ onTap(e) {
412
+ if (this.running && e.shiftKey && !e.middle && !this.lastDownLeaf) {
413
+ const find = this.findDeepOne(e);
414
+ if (find)
415
+ this.editor.shiftItem(find);
416
+ }
417
+ else if (this.isMoveMode) {
418
+ this.editor.target = null;
419
+ }
420
+ this.lastDownLeaf = null;
421
+ }
422
+ onDragStart(e) {
423
+ if (this.running && this.allowDrag(e)) {
424
+ const { editor } = this;
425
+ const { stroke, strokeWidth, area } = editor.config;
426
+ const { x, y } = e.getInner(this);
427
+ this.bounds.set(x, y);
428
+ this.selectArea.setStyle({ visible: true, stroke, strokeWidth, x, y }, area);
429
+ this.selectArea.setBounds(this.bounds.get());
430
+ this.originList = editor.leafList.clone();
431
+ }
432
+ }
433
+ onDrag(e) {
434
+ if (this.editor.dragging) {
435
+ this.onDragEnd();
436
+ return;
437
+ }
438
+ if (this.dragging) {
439
+ const { editor } = this;
440
+ const total = e.getInnerTotal(this);
441
+ const dragBounds = this.bounds.clone().unsign();
442
+ const list = new LeafList(editor.app.find(EditSelectHelper.findBounds, dragBounds));
443
+ this.bounds.width = total.x;
444
+ this.bounds.height = total.y;
445
+ this.selectArea.setBounds(dragBounds.get());
446
+ if (list.length) {
447
+ const selectList = [];
448
+ this.originList.forEach(item => { if (!list.has(item))
449
+ selectList.push(item); });
450
+ list.forEach(item => { if (!this.originList.has(item))
451
+ selectList.push(item); });
452
+ if (selectList.length !== editor.list.length || editor.list.some((child, index) => child !== selectList[index])) {
453
+ editor.target = selectList;
454
+ }
455
+ }
456
+ else {
457
+ editor.target = this.originList.list;
458
+ if (editor.leafList.length)
459
+ editor.update();
460
+ }
461
+ }
462
+ }
463
+ onDragEnd() {
464
+ if (this.dragging)
465
+ this.originList = null, this.selectArea.visible = false;
466
+ }
467
+ onAutoMove(e) {
468
+ if (this.dragging) {
469
+ const { x, y } = e.getLocalMove(this);
470
+ this.bounds.x += x;
471
+ this.bounds.y += y;
472
+ }
473
+ }
474
+ allow(target) {
475
+ return target.leafer !== this.editor.leafer;
476
+ }
477
+ allowDrag(e) {
478
+ if (this.editor.config.boxSelect && !e.target.draggable) {
479
+ return (!this.editor.hasTarget && this.allow(e.target)) || (e.shiftKey && !findOne(e.path));
480
+ }
481
+ else {
482
+ return false;
483
+ }
484
+ }
485
+ findDeepOne(e) {
486
+ const options = { exclude: new LeafList(this.editor.editBox.rect) };
487
+ return findOne(e.target.leafer.interaction.findPath(e, options));
488
+ }
489
+ __listenEvents() {
490
+ const { editor } = this;
491
+ editor.waitLeafer(() => {
492
+ const { app } = editor;
493
+ app.selector.proxy = editor;
494
+ this.__eventIds = [
495
+ editor.on_(EditorEvent.HOVER, this.onHover, this),
496
+ editor.on_(EditorEvent.SELECT, this.onSelect, this),
497
+ app.on_(PointerEvent.MOVE, this.onPointerMove, this),
498
+ app.on_(PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
499
+ app.on_(PointerEvent.TAP, this.onTap, this),
500
+ app.on_(DragEvent.START, this.onDragStart, this),
501
+ app.on_(DragEvent.DRAG, this.onDrag, this),
502
+ app.on_(DragEvent.END, this.onDragEnd, this),
503
+ app.on_(MoveEvent.MOVE, this.onAutoMove, this),
504
+ app.on_([ZoomEvent.ZOOM, MoveEvent.MOVE], () => { this.editor.hoverTarget = null; }),
505
+ ];
506
+ });
507
+ }
508
+ __removeListenEvents() {
509
+ if (this.__eventIds) {
510
+ this.off_(this.__eventIds);
511
+ this.__eventIds.length = 0;
512
+ }
513
+ }
514
+ destroy() {
515
+ this.editor = this.originList = this.lastDownLeaf = null;
516
+ this.__removeListenEvents();
517
+ super.destroy();
518
+ }
519
+ }
2
520
 
3
521
  var IDirection8;
4
522
  (function (IDirection8) {
@@ -12,257 +530,573 @@ var IDirection8;
12
530
  IDirection8[IDirection8["left"] = 7] = "left";
13
531
  })(IDirection8 || (IDirection8 = {}));
14
532
 
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)
533
+ const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = IDirection8;
534
+ const { toPoint } = AroundHelper;
535
+ const EditDataHelper = {
536
+ getScaleData(bounds, direction, pointMove, lockRatio, around) {
537
+ let origin, scaleX = 1, scaleY = 1;
538
+ const { width, height } = bounds;
539
+ if (around) {
540
+ pointMove.x *= 2;
541
+ pointMove.y *= 2;
542
+ }
543
+ if (Math.abs(pointMove.x) === width)
544
+ pointMove.x += 0.1;
545
+ if (Math.abs(pointMove.y) === height)
546
+ pointMove.y += 0.1;
547
+ const topScale = (-pointMove.y + height) / height;
548
+ const rightScale = (pointMove.x + width) / width;
549
+ const bottomScale = (pointMove.y + height) / height;
550
+ const leftScale = (-pointMove.x + width) / width;
551
+ switch (direction) {
552
+ case top:
553
+ scaleY = topScale;
554
+ origin = { x: 0.5, y: 1 };
555
+ break;
556
+ case right$1:
557
+ scaleX = rightScale;
558
+ origin = { x: 0, y: 0.5 };
559
+ break;
560
+ case bottom:
561
+ scaleY = bottomScale;
562
+ origin = { x: 0.5, y: 0 };
563
+ break;
564
+ case left$1:
565
+ scaleX = leftScale;
566
+ origin = { x: 1, y: 0.5 };
567
+ break;
568
+ case topLeft:
569
+ scaleY = topScale;
570
+ scaleX = leftScale;
571
+ origin = { x: 1, y: 1 };
572
+ break;
573
+ case topRight:
574
+ scaleY = topScale;
575
+ scaleX = rightScale;
576
+ origin = { x: 0, y: 1 };
577
+ break;
578
+ case bottomRight:
579
+ scaleY = bottomScale;
580
+ scaleX = rightScale;
581
+ origin = { x: 0, y: 0 };
582
+ break;
583
+ case bottomLeft:
584
+ scaleY = bottomScale;
585
+ scaleX = leftScale;
586
+ origin = { x: 1, y: 0 };
587
+ }
588
+ if (lockRatio) {
589
+ if (scaleX !== 1)
51
590
  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)
591
+ else
58
592
  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 };
86
593
  }
87
- else {
88
- origin = { x: x + width / 2, y: y + height / 2 };
594
+ toPoint(around || origin, bounds, origin);
595
+ return { origin, scaleX, scaleY, direction, lockRatio, around };
596
+ },
597
+ getRotateData(bounds, direction, current, last, around) {
598
+ let origin;
599
+ switch (direction) {
600
+ case topLeft:
601
+ origin = { x: 1, y: 1 };
602
+ break;
603
+ case topRight:
604
+ origin = { x: 0, y: 1 };
605
+ break;
606
+ case bottomRight:
607
+ origin = { x: 0, y: 0 };
608
+ break;
609
+ case bottomLeft:
610
+ origin = { x: 1, y: 0 };
611
+ break;
612
+ default:
613
+ origin = { x: 0.5, y: 0.5 };
614
+ }
615
+ toPoint(around || origin, bounds, origin);
616
+ return { origin, rotation: PointHelper.getRotation(last, origin, current) };
617
+ },
618
+ getSkewData(bounds, direction, move, around) {
619
+ let origin, skewX = 0, skewY = 0;
620
+ let last;
621
+ switch (direction) {
622
+ case top:
623
+ last = { x: 0.5, y: 0 };
624
+ origin = { x: 0.5, y: 1 };
625
+ skewX = 1;
626
+ break;
627
+ case bottom:
628
+ last = { x: 0.5, y: 1 };
629
+ origin = { x: 0.5, y: 0 };
630
+ skewX = 1;
631
+ break;
632
+ case left$1:
633
+ last = { x: 0, y: 0.5 };
634
+ origin = { x: 1, y: 0.5 };
635
+ skewY = 1;
636
+ break;
637
+ case right$1:
638
+ last = { x: 1, y: 0.5 };
639
+ origin = { x: 0, y: 0.5 };
640
+ skewY = 1;
641
+ }
642
+ const { x, y, width, height } = bounds;
643
+ last.x = x + last.x * width;
644
+ last.y = y + last.y * height;
645
+ toPoint(around || origin, bounds, origin);
646
+ const rotation = PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) });
647
+ skewX ? skewX = -rotation : skewY = rotation;
648
+ return { origin, skewX, skewY };
649
+ },
650
+ getAround(around, altKey) {
651
+ return (altKey && !around) ? 'center' : around;
652
+ },
653
+ getRotateDirection(direction, rotation, totalDirection = 8) {
654
+ direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection;
655
+ if (direction < 0)
656
+ direction += totalDirection;
657
+ return direction;
658
+ },
659
+ getFlipDirection(direction, flipedX, flipedY) {
660
+ if (flipedX) {
661
+ switch (direction) {
662
+ case left$1:
663
+ direction = right$1;
664
+ break;
665
+ case topLeft:
666
+ direction = topRight;
667
+ break;
668
+ case bottomLeft:
669
+ direction = bottomRight;
670
+ break;
671
+ case right$1:
672
+ direction = left$1;
673
+ break;
674
+ case topRight:
675
+ direction = topLeft;
676
+ break;
677
+ case bottomRight:
678
+ direction = bottomLeft;
679
+ break;
680
+ }
89
681
  }
682
+ if (flipedY) {
683
+ switch (direction) {
684
+ case top:
685
+ direction = bottom;
686
+ break;
687
+ case topLeft:
688
+ direction = bottomLeft;
689
+ break;
690
+ case topRight:
691
+ direction = bottomRight;
692
+ break;
693
+ case bottom:
694
+ direction = top;
695
+ break;
696
+ case bottomLeft:
697
+ direction = topLeft;
698
+ break;
699
+ case bottomRight:
700
+ direction = topRight;
701
+ break;
702
+ }
703
+ }
704
+ return direction;
90
705
  }
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, };
95
- }
706
+ };
96
707
 
97
- const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = IDirection8;
98
708
  function updateCursor(editor, e) {
99
- const point = editor.enterPoint;
100
- if (!point || !editor.target || !editor.visible)
709
+ const { editBox } = editor, point = editBox.enterPoint;
710
+ if (!point || !editor.hasTarget || !editBox.visible)
101
711
  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;
114
- }
115
- let index = (__direction + Math.round(rotation / 45)) % 8;
116
- if (index < 0)
117
- index += 8;
118
- point.cursor = __isResizePoint ? resizeCursor[index] : rotateCursor[index];
712
+ let { rotation } = editBox;
713
+ const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.config;
714
+ const { pointType } = point, { flippedX, flippedY } = editBox;
715
+ let showResize = pointType === 'resize';
716
+ if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable))
717
+ showResize = false;
718
+ const showSkew = skewable && !showResize && point.name === 'resize-line';
719
+ const cursor = showSkew ? skewCursor : (showResize ? resizeCursor : rotateCursor);
720
+ rotation += (EditDataHelper.getFlipDirection(point.direction, flippedX, flippedY) + 1) * 45;
721
+ const { url, x, y } = cursor;
722
+ point.cursor = { url: toDataURL(url, rotation), x, y };
119
723
  }
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;
138
- }
724
+ function updateMoveCursor(editor) {
725
+ editor.editBox.rect.cursor = editor.config.moveCursor;
726
+ }
727
+ function toDataURL(svg, rotation) {
728
+ return '"data:image/svg+xml,' + encodeURIComponent(svg.replace('{{rotation}}', rotation.toString())) + '"';
139
729
  }
140
730
 
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
- };
149
- },
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;
160
- }
161
- else {
162
- if (width < 0) {
163
- target.width = -width;
164
- target.scaleX *= -1;
165
- }
166
- else {
167
- if (target.width !== width)
168
- target.width = width;
169
- }
170
- if (height < 0) {
171
- target.height = -height;
172
- target.scaleY *= -1;
173
- }
174
- else {
175
- if (target.height !== height)
176
- target.height = height;
731
+ class EditPoint extends Box$1 {
732
+ }
733
+
734
+ const fourDirection = ['top', 'right', 'bottom', 'left'];
735
+ class EditBox extends Group$1 {
736
+ get flipped() { return this.flippedX || this.flippedY; }
737
+ get flippedX() { return this.scaleX < 0; }
738
+ get flippedY() { return this.scaleY < 0; }
739
+ get flippedOne() { return this.scaleX * this.scaleY < 0; }
740
+ constructor(editor) {
741
+ super();
742
+ this.rect = new Box$1({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 });
743
+ this.circle = new EditPoint({ name: 'circle', strokeAlign: 'center', around: 'center', cursor: 'crosshair', hitRadius: 5 });
744
+ this.buttons = new Group$1({ around: 'center', hitSelf: false });
745
+ this.resizePoints = [];
746
+ this.rotatePoints = [];
747
+ this.resizeLines = [];
748
+ this.__eventIds = [];
749
+ this.editor = editor;
750
+ this.visible = false;
751
+ this.create();
752
+ this.__listenEvents();
753
+ }
754
+ create() {
755
+ let rotatePoint, resizeLine, resizePoint;
756
+ const { resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this;
757
+ const arounds = [{ x: 1, y: 1 }, { x: 0.5, y: 1 }, { x: 0, y: 1 }, { x: 0, y: 0.5 }, { x: 0, y: 0 }, { x: 0.5, y: 0 }, { x: 1, y: 0 }, { x: 1, y: 0.5 }];
758
+ for (let i = 0; i < 8; i++) {
759
+ rotatePoint = new EditPoint({ name: 'rotate-point', around: arounds[i], width: 15, height: 15, hitFill: "all" });
760
+ rotatePoints.push(rotatePoint);
761
+ this.listenPointEvents(rotatePoint, 'rotate', i);
762
+ if (i % 2) {
763
+ resizeLine = new EditPoint({ name: 'resize-line', around: 'center', width: 10, height: 10, hitFill: "all" });
764
+ resizeLines.push(resizeLine);
765
+ this.listenPointEvents(resizeLine, 'resize', i);
177
766
  }
767
+ resizePoint = new EditPoint({ name: 'resize-point', around: 'center', strokeAlign: 'center', hitRadius: 5 });
768
+ resizePoints.push(resizePoint);
769
+ this.listenPointEvents(resizePoint, 'resize', i);
178
770
  }
179
- },
180
- rotate(e) {
181
- const { target, rotation, origin } = e;
182
- target.rotateOf(origin, rotation);
183
- },
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;
771
+ buttons.add(circle);
772
+ this.listenPointEvents(circle, 'rotate', 2);
773
+ this.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
774
+ }
775
+ update(bounds) {
776
+ const { config, list } = this.editor;
777
+ const { width, height } = bounds;
778
+ const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
779
+ const { middlePoint, resizeable, rotateable, stroke, strokeWidth } = config;
780
+ const pointsStyle = this.getPointsStyle();
781
+ const middlePointsStyle = this.getMiddlePointsStyle();
782
+ const showPoints = width > 20 || height > 20;
783
+ this.visible = list[0] && !list[0].locked;
784
+ let point = {}, style, rotateP, resizeP, resizeL;
211
785
  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];
786
+ AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point);
787
+ style = this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]);
788
+ resizeP = resizePoints[i], rotateP = rotatePoints[i], resizeL = resizeLines[Math.floor(i / 2)];
217
789
  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;
790
+ resizeP.set(point), rotateP.set(point), resizeL.set(point);
791
+ resizeP.visible = resizeL.visible = showPoints && (resizeable || rotateable);
792
+ rotateP.visible = showPoints && rotateable && resizeable;
222
793
  if (i % 2) {
794
+ resizeP.visible = rotateP.visible = showPoints && !!middlePoint;
223
795
  if (((i + 1) / 2) % 2) {
224
- resizeL.width = Math.abs(width);
225
- rotateP.width = Math.max(10, Math.abs(width) - 30);
796
+ resizeL.width = width;
797
+ if (resizeP.width > width - 30)
798
+ resizeP.visible = false;
226
799
  }
227
800
  else {
228
- resizeL.height = Math.abs(height);
229
- rotateP.height = Math.max(10, Math.abs(height) - 30);
801
+ resizeL.height = height;
802
+ resizeP.rotation = 90;
803
+ if (resizeP.width > height - 30)
804
+ resizeP.visible = false;
230
805
  }
231
- resizeP.rotation = 90;
232
- resizeP.visible = type === 'mobile';
233
806
  }
234
807
  else {
235
- rectPoints.push(point.x, point.y);
808
+ resizeP.rotation = (i / 2) * 90;
236
809
  }
237
810
  }
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;
811
+ circle.visible = showPoints && rotateable && !!config.rotatePoint;
812
+ circle.set(this.getPointStyle(config.rotatePoint || pointsStyle[0]));
813
+ rect.set(Object.assign({ stroke, strokeWidth }, (config.rect || {})));
814
+ rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
815
+ this.buttons.visible = showPoints;
816
+ this.layoutButtons();
817
+ }
818
+ layoutButtons() {
819
+ const { buttons, resizePoints } = this;
820
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.config;
821
+ const { flippedX, flippedY } = this;
822
+ let index = fourDirection.indexOf(buttonsDirection);
823
+ if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
824
+ if (buttonsFixed)
825
+ index = (index + 2) % 4;
826
+ }
827
+ const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
828
+ const point = resizePoints[direction * 2 + 1];
829
+ const useX = direction % 2;
830
+ const sign = (!direction || direction === 3) ? -1 : 1;
831
+ const useWidth = index % 2;
832
+ const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
833
+ if (useX) {
834
+ buttons.x = point.x + margin;
835
+ buttons.y = point.y;
836
+ }
837
+ else {
838
+ buttons.x = point.x;
839
+ buttons.y = point.y + margin;
840
+ }
841
+ if (buttonsFixed) {
842
+ buttons.rotation = (direction - index) * 90;
843
+ buttons.scaleX = flippedX ? -1 : 1;
844
+ buttons.scaleY = flippedY ? -1 : 1;
845
+ }
846
+ }
847
+ getPointStyle(userStyle) {
848
+ const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.config;
849
+ const defaultStyle = { fill: pointFill, stroke, strokeWidth, width: pointSize, height: pointSize, cornerRadius: pointRadius };
850
+ return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle;
851
+ }
852
+ getPointsStyle() {
853
+ const { point } = this.editor.config;
854
+ return point instanceof Array ? point : [point];
855
+ }
856
+ getMiddlePointsStyle() {
857
+ const { middlePoint } = this.editor.config;
858
+ return middlePoint instanceof Array ? middlePoint : (middlePoint ? [middlePoint] : this.getPointsStyle());
859
+ }
860
+ onDragStart(e) {
861
+ this.dragging = true;
862
+ if (e.target.name === 'rect') {
863
+ this.moving = true;
864
+ this.editor.opacity = this.editor.config.hideOnMove ? 0 : 1;
865
+ }
866
+ }
867
+ onDragEnd(e) {
868
+ this.dragging = false;
869
+ this.moving = false;
870
+ if (e.target.name === 'rect')
871
+ this.editor.opacity = 1;
872
+ }
873
+ onDrag(e) {
874
+ const { editor } = this;
875
+ const point = this.enterPoint = e.current;
876
+ if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.config.resizeable) {
877
+ if (editor.config.rotateable)
878
+ editor.onRotate(e);
879
+ updateCursor(editor, e);
880
+ }
881
+ else {
882
+ editor.onScale(e);
883
+ }
884
+ }
885
+ onArrow(e) {
886
+ if (this.editor.hasTarget) {
887
+ const move = { x: 0, y: 0 };
888
+ const distance = e.shiftKey ? 10 : 1;
889
+ switch (e.code) {
890
+ case 'ArrowDown':
891
+ move.y = distance;
892
+ break;
893
+ case 'ArrowUp':
894
+ move.y = -distance;
895
+ break;
896
+ case 'ArrowLeft':
897
+ move.x = -distance;
898
+ break;
899
+ case 'ArrowRight':
900
+ move.x = distance;
901
+ }
902
+ if (move.x || move.y)
903
+ this.editor.move(move.x, move.y);
904
+ }
905
+ }
906
+ onDoubleClick() {
907
+ const { editor } = this;
908
+ if (editor.single && editor.element.isBranch) ;
909
+ }
910
+ listenPointEvents(point, type, direction) {
911
+ const { editor } = this;
912
+ point.direction = direction;
913
+ point.pointType = type;
914
+ point.on_(DragEvent.START, this.onDragStart, this);
915
+ point.on_(DragEvent.DRAG, this.onDrag, this);
916
+ point.on_(DragEvent.END, this.onDragEnd, this);
917
+ point.on_(PointerEvent.LEAVE, () => this.enterPoint = null);
918
+ if (point.name !== 'circle')
919
+ point.on_(PointerEvent.ENTER, (e) => { this.enterPoint = point, updateCursor(editor, e); });
920
+ }
921
+ __listenEvents() {
922
+ const { rect, editor } = this;
923
+ this.__eventIds = [
924
+ editor.on_(EditorEvent.SELECT, () => { this.visible = editor.hasTarget; }),
925
+ rect.on_(DragEvent.START, this.onDragStart, this),
926
+ rect.on_(DragEvent.DRAG, editor.onMove, editor),
927
+ rect.on_(DragEvent.END, this.onDragEnd, this),
928
+ rect.on_(PointerEvent.ENTER, () => updateMoveCursor(editor)),
929
+ rect.on_(PointerEvent.DOUBLE_CLICK, this.onDoubleClick, this)
930
+ ];
931
+ }
932
+ __removeListenEvents() {
933
+ this.off_(this.__eventIds);
934
+ this.__eventIds.length = 0;
247
935
  }
936
+ destroy() {
937
+ this.editor = null;
938
+ this.__removeListenEvents();
939
+ super.destroy();
940
+ }
941
+ }
942
+
943
+ const filterStyle = `
944
+ <feOffset dy="1"/>
945
+ <feGaussianBlur stdDeviation="1.5"/>
946
+ <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"/>
947
+ <feBlend mode="normal" in="SourceGraphic" result="shape"/>`;
948
+ const resizeSVG = `
949
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
950
+ <g filter="url(#f)">
951
+ <g transform="rotate({{rotation}},12,12)">
952
+ <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"/>
953
+ <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"/>
954
+ </g>
955
+ </g>
956
+ <defs>
957
+ <filter id="f" x="-1.6" y="3.9" width="27.2" height="16.9" filterUnits="userSpaceOnUse">
958
+ ${filterStyle}
959
+ </filter>
960
+ </defs>
961
+ </svg>
962
+ `;
963
+ const rotateSVG = `
964
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
965
+ <g filter="url(#f)">
966
+ <g transform="rotate(135,12,12),rotate({{rotation}},12,12)">
967
+ <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"/>
968
+ <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"/>
969
+ </g>
970
+ </g>
971
+ <defs>
972
+ <filter id="f" x="-1.6" y="-0.6" width="27.1" height="27.1" filterUnits="userSpaceOnUse">
973
+ ${filterStyle}
974
+ </filter>
975
+ </defs>
976
+ </svg>
977
+ `;
978
+ const skewSVG = `
979
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
980
+ <g filter="url(#f)">
981
+ <g transform="rotate(90,12,12),rotate({{rotation}},12,12)">
982
+ <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"/>
983
+ <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"/>
984
+ </g>
985
+ </g>
986
+ <defs>
987
+ <filter x="-2.8" y="1.9" width="29.6" height="23.1" filterUnits="userSpaceOnUse" >
988
+ ${filterStyle}
989
+ </filter>
990
+ </defs>
991
+ </svg>
992
+ `;
993
+
994
+ const config = {
995
+ editSize: 'auto',
996
+ stroke: '#836DFF',
997
+ strokeWidth: 2,
998
+ pointFill: '#FFFFFF',
999
+ pointSize: 10,
1000
+ pointRadius: 16,
1001
+ rotateGap: 45,
1002
+ buttonsDirection: 'bottom',
1003
+ buttonsMargin: 12,
1004
+ moveCursor: 'move',
1005
+ resizeCursor: { url: resizeSVG, x: 12, y: 12 },
1006
+ rotateCursor: { url: rotateSVG, x: 12, y: 12 },
1007
+ skewCursor: { url: skewSVG, x: 12, y: 12 },
1008
+ selector: true,
1009
+ hover: true,
1010
+ boxSelect: true,
1011
+ resizeable: true,
1012
+ rotateable: true,
1013
+ skewable: true
248
1014
  };
249
1015
 
1016
+ const { transformWorld, zoomOfWorld, skewOfWorld, rotateOfWorld, moveWorld } = LeafHelper;
1017
+ class EditTool {
1018
+ constructor() {
1019
+ this.tag = 'EditTool';
1020
+ }
1021
+ onMove(e) {
1022
+ const { moveX, moveY, editor } = e;
1023
+ const { app, list } = editor;
1024
+ app.lockLayout();
1025
+ list.forEach(target => {
1026
+ moveWorld(target, moveX, moveY);
1027
+ });
1028
+ app.unlockLayout();
1029
+ }
1030
+ onScale(e) {
1031
+ const { scaleX, scaleY, transform, worldOrigin, editor } = e;
1032
+ const { app, list } = editor;
1033
+ app.lockLayout();
1034
+ list.forEach(target => {
1035
+ const resize = editor.getEditSize(target) === 'size';
1036
+ if (transform) {
1037
+ transformWorld(target, transform, resize);
1038
+ }
1039
+ else {
1040
+ zoomOfWorld(target, worldOrigin, scaleX, scaleY, resize);
1041
+ }
1042
+ });
1043
+ app.unlockLayout();
1044
+ }
1045
+ onRotate(e) {
1046
+ const { rotation, transform, worldOrigin, editor } = e;
1047
+ const { app, list } = editor;
1048
+ app.lockLayout();
1049
+ list.forEach(target => {
1050
+ const resize = editor.getEditSize(target) === 'size';
1051
+ if (transform) {
1052
+ transformWorld(target, transform, resize);
1053
+ }
1054
+ else {
1055
+ rotateOfWorld(target, worldOrigin, rotation);
1056
+ }
1057
+ });
1058
+ app.unlockLayout();
1059
+ }
1060
+ onSkew(e) {
1061
+ const { skewX, skewY, transform, worldOrigin, editor } = e;
1062
+ const { app, list } = editor;
1063
+ app.lockLayout();
1064
+ list.forEach(target => {
1065
+ const resize = editor.getEditSize(target) === 'size';
1066
+ if (transform) {
1067
+ transformWorld(target, transform, resize);
1068
+ }
1069
+ else {
1070
+ skewOfWorld(target, worldOrigin, skewX, skewY, resize);
1071
+ }
1072
+ });
1073
+ app.unlockLayout();
1074
+ }
1075
+ update(editor) {
1076
+ const { simulateTarget, element } = editor;
1077
+ if (editor.multiple)
1078
+ simulateTarget.parent.updateLayout();
1079
+ const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true);
1080
+ editor.editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY });
1081
+ editor.editBox.update({ x: 0, y: 0, width, height });
1082
+ }
1083
+ }
1084
+ EditTool.list = [];
1085
+
250
1086
  const { left, right } = IDirection8;
251
- const LineTool = {
252
- name: 'LineTool',
253
- getMirrorData(_editor) {
254
- return {
255
- x: 0,
256
- y: 0
257
- };
258
- },
259
- resize(e) {
260
- const { direction, dragEvent, lockRatio, around } = e;
1087
+ class LineEditTool extends EditTool {
1088
+ constructor() {
1089
+ super(...arguments);
1090
+ this.tag = 'LineEditTool';
1091
+ this.scaleOfEvent = true;
1092
+ }
1093
+ onScaleWithDrag(e) {
1094
+ const { drag, direction, lockRatio, around } = e;
261
1095
  const target = e.target;
262
- const fromPoint = { x: 0, y: 0 };
1096
+ const fromPoint = getPointData();
263
1097
  const { toPoint } = target;
264
1098
  target.rotation = 0;
265
- let { x, y } = dragEvent.getInnerMove(target);
1099
+ let { x, y } = drag.getInnerMove(target);
266
1100
  if (lockRatio) {
267
1101
  if (Math.abs(x) > Math.abs(y)) {
268
1102
  y = 0;
@@ -293,218 +1127,356 @@ const LineTool = {
293
1127
  target.y = fromPoint.y;
294
1128
  target.getInnerPointByLocal(toPoint, null, null, true);
295
1129
  target.toPoint = toPoint;
296
- },
297
- rotate(e) {
298
- RectTool.rotate(e);
299
- },
1130
+ }
1131
+ onSkew(_e) {
1132
+ }
300
1133
  update(editor) {
301
- const { rotatePoints, circle, resizeLines, resizePoints } = editor;
302
- RectTool.update(editor);
1134
+ const { rotatePoints, resizeLines, resizePoints } = editor.editBox;
1135
+ super.update(editor);
303
1136
  for (let i = 0; i < 8; i++) {
304
1137
  if (i < 4)
305
1138
  resizeLines[i].visible = false;
306
- resizePoints[i].visible = rotatePoints[i].visible = i === left || i === right;
1139
+ resizePoints[i].visible = rotatePoints[i].visible = (i === left || i === right);
307
1140
  }
308
- circle.visible = false;
309
1141
  }
310
- };
1142
+ }
311
1143
 
312
- class EditorResizeEvent extends Event {
313
- constructor(type, data) {
314
- super(type);
315
- if (data)
316
- Object.assign(this, data);
1144
+ function getEditTool(list) {
1145
+ if (list.length === 1) {
1146
+ const leaf = list[0];
1147
+ if (leaf instanceof Line$1 && !leaf.points) {
1148
+ return new LineEditTool();
1149
+ }
1150
+ else {
1151
+ return new EditTool();
1152
+ }
1153
+ }
1154
+ else {
1155
+ return new EditTool();
317
1156
  }
318
1157
  }
319
- EditorResizeEvent.RESIZE = 'editor.resize';
320
1158
 
321
- class EditorRotateEvent extends Event {
322
- constructor(type, data) {
323
- super(type);
324
- if (data)
325
- Object.assign(this, data);
1159
+ function simulate(editor) {
1160
+ const { simulateTarget, leafList: targetList } = editor;
1161
+ const { x, y, width, height } = new Bounds().setListWithFn(targetList.list, (leaf) => leaf.worldBoxBounds);
1162
+ const parent = simulateTarget.parent = targetList.list[0].leafer.zoomLayer;
1163
+ const { scaleX, scaleY, e: worldX, f: worldY } = parent.__world;
1164
+ simulateTarget.reset({ x: (x - worldX) / scaleX, y: (y - worldY) / scaleY, width: width / scaleX, height: height / scaleY });
1165
+ }
1166
+
1167
+ function onTarget(editor, oldValue) {
1168
+ const { target } = editor;
1169
+ if (target) {
1170
+ editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target);
1171
+ }
1172
+ else {
1173
+ editor.leafList.reset();
1174
+ }
1175
+ editor.emitEvent(new EditorEvent(EditorEvent.SELECT, { editor, value: target, oldValue }));
1176
+ if (editor.hasTarget) {
1177
+ editor.waitLeafer(() => {
1178
+ if (editor.multiple)
1179
+ simulate(editor);
1180
+ updateMoveCursor(editor);
1181
+ editor.updateEditTool();
1182
+ editor.update();
1183
+ editor.listenTargetEvents();
1184
+ });
1185
+ }
1186
+ else {
1187
+ editor.removeTargetEvents();
326
1188
  }
327
1189
  }
328
- EditorRotateEvent.ROTATE = 'editor.rotate';
1190
+ function onHover(editor, oldValue) {
1191
+ editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }));
1192
+ }
329
1193
 
330
- 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();
1194
+ const order = (a, b) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b);
1195
+ const reverseOrder = (a, b) => b.parent.children.indexOf(b) - a.parent.children.indexOf(a);
1196
+ const EditorHelper = {
1197
+ group(list, element, userGroup) {
1198
+ list.sort(reverseOrder);
1199
+ const { app, parent } = list[0];
1200
+ let group;
1201
+ if (userGroup && userGroup.add) {
1202
+ group = userGroup;
1203
+ }
1204
+ else {
1205
+ group = new Group$1(userGroup);
1206
+ }
1207
+ parent.addAt(group, parent.children.indexOf(list[0]));
1208
+ list.sort(order);
1209
+ const matrx = new Matrix(element.worldTransform);
1210
+ matrx.divideParent(parent.worldTransform);
1211
+ group.setTransform(matrx);
1212
+ group.editable = true;
1213
+ group.hitChildren = false;
1214
+ app.lockLayout();
1215
+ list.forEach(child => child.dropTo(group));
1216
+ app.unlockLayout();
1217
+ return group;
1218
+ },
1219
+ ungroup(list) {
1220
+ const { app } = list[0];
1221
+ const ungroupList = [];
1222
+ app.lockLayout();
1223
+ list.forEach(leaf => {
1224
+ if (leaf.isBranch) {
1225
+ const { parent, children } = leaf;
1226
+ while (children.length) {
1227
+ ungroupList.push(children[0]);
1228
+ children[0].dropTo(parent, parent.children.indexOf(leaf));
1229
+ }
1230
+ leaf.remove();
1231
+ }
1232
+ else {
1233
+ ungroupList.push(leaf);
1234
+ }
1235
+ });
1236
+ app.unlockLayout();
1237
+ return ungroupList;
1238
+ },
1239
+ toTop(list) {
1240
+ list.sort(order);
1241
+ list.forEach(leaf => {
1242
+ if (leaf.parent)
1243
+ leaf.parent.add(leaf);
1244
+ });
1245
+ },
1246
+ toBottom(list) {
1247
+ list.sort(reverseOrder);
1248
+ list.forEach(leaf => {
1249
+ if (leaf.parent)
1250
+ leaf.parent.addAt(leaf, 0);
1251
+ });
338
1252
  }
1253
+ };
1254
+
1255
+ class Editor extends Group$1 {
1256
+ get list() { return this.leafList.list; }
1257
+ get hasTarget() { return !!this.list.length; }
1258
+ get multiple() { return this.list.length > 1; }
1259
+ get single() { return this.list.length === 1; }
1260
+ get element() { return this.multiple ? this.simulateTarget : this.list[0]; }
1261
+ get buttons() { return this.editBox.buttons; }
1262
+ get dragging() { return this.editBox.dragging; }
339
1263
  constructor(userConfig, data) {
340
1264
  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 = [];
1265
+ this.config = config;
1266
+ this.leafList = new LeafList();
1267
+ this.simulateTarget = new Rect({ visible: false });
1268
+ this.editBox = new EditBox(this);
1269
+ this.selector = new EditSelect(this);
1270
+ this.targetEventIds = [];
364
1271
  if (userConfig)
365
1272
  this.config = DataHelper.default(userConfig, this.config);
366
- this.init();
1273
+ this.addMany(this.selector, this.editBox);
367
1274
  }
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();
1275
+ hasItem(item) {
1276
+ return this.leafList.has(item);
387
1277
  }
388
- onTarget() {
389
- this.tool = this.getTool(this.target);
390
- this.waitLeafer(() => {
391
- this.update();
392
- this.updateMoveCursor();
393
- this.__listenTargetEvents();
394
- });
1278
+ addItem(item) {
1279
+ if (!this.hasItem(item) && !item.locked)
1280
+ this.leafList.add(item), this.target = this.leafList.list;
395
1281
  }
396
- getTool(value) {
397
- return (value.tag === 'Line' && value.resizeable) ? LineTool : RectTool;
1282
+ removeItem(item) {
1283
+ if (this.hasItem(item))
1284
+ this.leafList.remove(item), this.target = this.leafList.list;
398
1285
  }
399
- update() {
400
- if (!this.target)
401
- return;
402
- this.tool.update(this);
1286
+ shiftItem(item) {
1287
+ this.hasItem(item) ? this.removeItem(item) : this.addItem(item);
403
1288
  }
404
- onDrag(e) {
405
- const { resizeable, rotateable } = this.config;
406
- if (e.metaKey || e.ctrlKey || !resizeable) {
407
- if (rotateable)
408
- this.onRotate(e);
409
- }
410
- else {
411
- this.onResize(e);
1289
+ update() {
1290
+ if (this.target) {
1291
+ if (this.editTool)
1292
+ this.editTool.update(this);
1293
+ this.selector.update();
412
1294
  }
413
1295
  }
1296
+ updateEditTool() {
1297
+ this.editTool = getEditTool(this.list);
1298
+ }
1299
+ getEditSize(ui) {
1300
+ let { editSize } = this.config;
1301
+ return editSize === 'auto' ? ui.editSize : editSize;
1302
+ }
414
1303
  onMove(e) {
415
- const { target } = this;
416
- const { x, y } = e.getLocalMove(target);
1304
+ const move = e.getLocalMove(this.element);
417
1305
  if (e.shiftKey) {
418
- if (Math.abs(x) > Math.abs(y)) {
419
- target.x += x;
420
- }
421
- else {
422
- target.y += y;
423
- }
1306
+ if (Math.abs(move.x) > Math.abs(move.y))
1307
+ move.y = 0;
1308
+ else
1309
+ move.x = 0;
1310
+ }
1311
+ this.move(move.x, move.y);
1312
+ }
1313
+ onScale(e) {
1314
+ const { element } = this;
1315
+ const { direction } = e.current;
1316
+ let { around, lockRatio } = this.config;
1317
+ if (e.shiftKey)
1318
+ lockRatio = true;
1319
+ const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
1320
+ if (this.editTool.onScaleWithDrag) {
1321
+ data.drag = e;
1322
+ this.scaleWithDrag(data);
424
1323
  }
425
1324
  else {
426
- target.x += x;
427
- target.y += y;
1325
+ this.scaleOf(data.origin, data.scaleX, data.scaleY);
428
1326
  }
429
1327
  }
430
1328
  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;
1329
+ const { skewable, around, rotateGap } = this.config;
1330
+ const { direction, name } = e.current;
1331
+ if (skewable && name === 'resize-line')
1332
+ return this.onSkew(e);
1333
+ const { element } = this;
1334
+ let origin, rotation;
436
1335
  if (e instanceof RotateEvent) {
437
- rotation = e.rotation;
1336
+ rotation = e.rotation, origin = element.getInnerPoint(e);
438
1337
  }
439
1338
  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;
1339
+ const last = { x: e.x - e.moveX, y: e.y - e.moveY };
1340
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
1341
+ rotation = data.rotation;
1342
+ origin = data.origin;
1343
+ }
1344
+ rotation = MathHelper.getGapRotation(rotation, rotateGap, element.rotation);
1345
+ if (!rotation)
1346
+ return;
1347
+ if (element.scaleX * element.scaleY < 0)
1348
+ rotation = -rotation;
1349
+ this.rotateOf(origin, MathHelper.float(rotation, 2));
466
1350
  }
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
- ];
1351
+ onSkew(e) {
1352
+ const { element } = this;
1353
+ const { around } = this.config;
1354
+ const { origin, skewX, skewY } = EditDataHelper.getSkewData(element.boxBounds, e.current.direction, e.getInnerMove(element), EditDataHelper.getAround(around, e.altKey));
1355
+ if (!skewX && !skewY)
1356
+ return;
1357
+ this.skewOf(origin, skewX, skewY);
474
1358
  }
475
- __removeListenEvents() {
476
- this.targetRect.off_(this.__eventIds);
477
- this.__eventIds.length = 0;
1359
+ move(x, y) {
1360
+ const { element } = this;
1361
+ const world = element.getWorldPointByLocal({ x, y }, null, true);
1362
+ const event = new EditorMoveEvent(EditorMoveEvent.MOVE, { target: element, editor: this, moveX: world.x, moveY: world.y });
1363
+ this.editTool.onMove(event);
1364
+ this.emitEvent(event);
1365
+ if (this.multiple)
1366
+ element.move(x, y);
478
1367
  }
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); });
1368
+ scaleWithDrag(data) {
1369
+ const { element } = this;
1370
+ const worldOrigin = element.getWorldPoint(data.origin);
1371
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
1372
+ this.editTool.onScaleWithDrag(event);
1373
+ this.emitEvent(event);
485
1374
  }
486
- __listenTargetEvents() {
487
- if (this.target) {
488
- const { leafer } = this.target;
489
- this.__targetEventIds = [
1375
+ scaleOf(origin, scaleX, scaleY = scaleX, _resize) {
1376
+ const { element } = this;
1377
+ const worldOrigin = element.getWorldPoint(origin);
1378
+ let transform;
1379
+ if (this.multiple) {
1380
+ const oldMatrix = new Matrix(element.worldTransform);
1381
+ element.scaleOf(origin, scaleX, scaleY);
1382
+ transform = new Matrix(element.worldTransform).divide(oldMatrix);
1383
+ }
1384
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
1385
+ this.editTool.onScale(event);
1386
+ this.emitEvent(event);
1387
+ }
1388
+ rotateOf(origin, rotation) {
1389
+ const { element } = this;
1390
+ const worldOrigin = element.getWorldPoint(origin);
1391
+ let transform;
1392
+ if (this.multiple) {
1393
+ const oldMatrix = new Matrix(element.worldTransform);
1394
+ element.rotateOf(origin, rotation);
1395
+ transform = new Matrix(element.worldTransform).divide(oldMatrix);
1396
+ }
1397
+ const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
1398
+ this.editTool.onRotate(event);
1399
+ this.emitEvent(event);
1400
+ }
1401
+ skewOf(origin, skewX, skewY = 0, _resize) {
1402
+ const { element } = this;
1403
+ const worldOrigin = element.getWorldPoint(origin);
1404
+ let transform;
1405
+ if (this.multiple) {
1406
+ const oldMatrix = new Matrix(element.worldTransform);
1407
+ element.skewOf(origin, skewX, skewY);
1408
+ transform = new Matrix(element.worldTransform).divide(oldMatrix);
1409
+ }
1410
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
1411
+ target: element, editor: this, skewX, skewY, transform, worldOrigin
1412
+ });
1413
+ this.editTool.onSkew(event);
1414
+ this.emitEvent(event);
1415
+ }
1416
+ group(userGroup) {
1417
+ if (this.multiple)
1418
+ this.target = EditorHelper.group(this.list, this.element, userGroup);
1419
+ return this.target;
1420
+ }
1421
+ ungroup() {
1422
+ if (this.list.length)
1423
+ this.target = EditorHelper.ungroup(this.list);
1424
+ return this.list;
1425
+ }
1426
+ lock() {
1427
+ this.list.forEach(leaf => leaf.locked = true);
1428
+ this.update();
1429
+ }
1430
+ unlock() {
1431
+ this.list.forEach(leaf => leaf.locked = false);
1432
+ this.update();
1433
+ }
1434
+ toTop() {
1435
+ if (this.list.length) {
1436
+ EditorHelper.toTop(this.list);
1437
+ this.leafList.update();
1438
+ }
1439
+ }
1440
+ toBottom() {
1441
+ if (this.list.length) {
1442
+ EditorHelper.toBottom(this.list);
1443
+ this.leafList.update();
1444
+ }
1445
+ }
1446
+ listenTargetEvents() {
1447
+ if (!this.targetEventIds.length) {
1448
+ const { leafer } = this.list[0];
1449
+ this.targetEventIds = [
490
1450
  leafer.on_(RenderEvent.START, this.update, this),
491
- leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); })
1451
+ leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); }),
1452
+ leafer.on_(KeyEvent.DOWN, this.editBox.onArrow, this.editBox)
492
1453
  ];
493
1454
  }
494
1455
  }
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;
1456
+ removeTargetEvents() {
1457
+ const { targetEventIds } = this;
1458
+ if (targetEventIds.length) {
1459
+ this.off_(targetEventIds);
1460
+ targetEventIds.length = 0;
501
1461
  }
502
1462
  }
503
1463
  destroy() {
504
- this.__removeListenEvents();
505
- this._target = null;
506
- super.destroy();
1464
+ if (!this.destroyed) {
1465
+ this.simulateTarget.destroy();
1466
+ this.target = this.hoverTarget = this.simulateTarget = null;
1467
+ super.destroy();
1468
+ }
507
1469
  }
508
1470
  }
1471
+ __decorate([
1472
+ targetAttr(onHover)
1473
+ ], Editor.prototype, "hoverTarget", void 0);
1474
+ __decorate([
1475
+ targetAttr(onTarget)
1476
+ ], Editor.prototype, "target", void 0);
1477
+
1478
+ Creator.editor = function (options) {
1479
+ return new Editor(options);
1480
+ };
509
1481
 
510
- export { Editor, EditorResizeEvent, EditorRotateEvent, LineTool, RectTool };
1482
+ export { EditBox, EditDataHelper, EditPoint, EditSelect, EditSelectHelper, EditTool, Editor, EditorEvent, EditorHelper, EditorMoveEvent, EditorRotateEvent, EditorScaleEvent, EditorSkewEvent, LineEditTool, SelectArea, Stroker };