@leafer-in/editor 1.0.0-rc.2 → 1.0.0-rc.20

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