@leafer-in/editor 1.0.0-rc.9 → 1.0.1

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