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