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

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,1937 @@
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.config.pointer.hover && !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
+ const { select } = this.editor.mergeConfig;
448
+ if (select === 'press')
449
+ this.checkAndSelect(e);
450
+ }
451
+ onTap(e) {
452
+ const { editor } = this;
453
+ const { select } = editor.mergeConfig;
454
+ if (select === 'tap')
455
+ this.checkAndSelect(e);
456
+ if (this.needRemoveItem) {
457
+ editor.removeItem(this.needRemoveItem);
458
+ }
459
+ else if (this.isMoveMode) {
460
+ editor.target = null;
461
+ }
462
+ }
463
+ checkAndSelect(e) {
464
+ this.needRemoveItem = null;
465
+ if (this.allowSelect(e)) {
466
+ const { editor } = this;
467
+ const find = this.findUI(e);
468
+ if (find) {
469
+ if (this.isMultipleSelect(e)) {
470
+ if (editor.hasItem(find))
471
+ this.needRemoveItem = find;
472
+ else
473
+ editor.addItem(find);
474
+ }
475
+ else {
476
+ editor.target = find;
477
+ }
478
+ }
479
+ else if (this.allow(e.target)) {
480
+ if (!e.shiftKey)
481
+ editor.target = null;
482
+ }
483
+ }
484
+ }
485
+ onDragStart(e) {
486
+ if (this.allowDrag(e)) {
487
+ const { editor } = this;
488
+ const { stroke, area } = editor.mergeConfig;
489
+ const { x, y } = e.getInner(this);
490
+ this.bounds.set(x, y);
491
+ this.selectArea.setStyle({ visible: true, stroke, x, y }, area);
492
+ this.selectArea.setBounds(this.bounds.get());
493
+ this.originList = editor.leafList.clone();
494
+ }
495
+ }
496
+ onDrag(e) {
497
+ if (this.editor.dragging) {
498
+ this.onDragEnd();
499
+ return;
500
+ }
501
+ if (this.dragging) {
502
+ const { editor } = this;
503
+ const total = e.getInnerTotal(this);
504
+ const dragBounds = this.bounds.clone().unsign();
505
+ const list = new draw.LeafList(editor.app.find(EditSelectHelper.findBounds, dragBounds));
506
+ this.bounds.width = total.x;
507
+ this.bounds.height = total.y;
508
+ this.selectArea.setBounds(dragBounds.get());
509
+ if (list.length) {
510
+ const selectList = [];
511
+ this.originList.forEach(item => { if (!list.has(item))
512
+ selectList.push(item); });
513
+ list.forEach(item => { if (!this.originList.has(item))
514
+ selectList.push(item); });
515
+ if (selectList.length !== editor.list.length || editor.list.some((child, index) => child !== selectList[index])) {
516
+ editor.target = selectList;
517
+ }
518
+ }
519
+ else {
520
+ editor.target = this.originList.list;
521
+ }
522
+ }
523
+ }
524
+ onDragEnd() {
525
+ if (this.dragging)
526
+ this.originList = null, this.selectArea.visible = false;
527
+ }
528
+ onAutoMove(e) {
529
+ if (this.dragging) {
530
+ const { x, y } = e.getLocalMove(this);
531
+ this.bounds.x += x;
532
+ this.bounds.y += y;
533
+ }
534
+ }
535
+ allow(target) {
536
+ return target.leafer !== this.editor.leafer;
537
+ }
538
+ allowDrag(e) {
539
+ if (this.running && this.editor.mergeConfig.boxSelect && !e.target.draggable) {
540
+ return (!this.editor.editing && this.allow(e.target)) || (e.shiftKey && !findOne(e.path));
541
+ }
542
+ else {
543
+ return false;
544
+ }
545
+ }
546
+ allowSelect(e) {
547
+ return this.running && !this.isMoveMode && !e.middle;
548
+ }
549
+ findDeepOne(e) {
550
+ const options = { exclude: new draw.LeafList(this.editor.editBox.rect) };
551
+ return findOne(e.target.leafer.interaction.findPath(e, options));
552
+ }
553
+ findUI(e) {
554
+ return this.isMultipleSelect(e) ? this.findDeepOne(e) : findOne(e.path);
555
+ }
556
+ isMultipleSelect(e) {
557
+ return e.shiftKey || this.editor.mergeConfig.continuousSelect;
558
+ }
559
+ __listenEvents() {
560
+ const { editor } = this;
561
+ editor.waitLeafer(() => {
562
+ const { app } = editor;
563
+ app.selector.proxy = editor;
564
+ this.__eventIds = [
565
+ editor.on_(EditorEvent.HOVER, this.onHover, this),
566
+ editor.on_(EditorEvent.SELECT, this.onSelect, this),
567
+ app.on_(core.PointerEvent.MOVE, this.onPointerMove, this),
568
+ app.on_(core.PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
569
+ app.on_(core.PointerEvent.TAP, this.onTap, this),
570
+ app.on_(core.DragEvent.START, this.onDragStart, this),
571
+ app.on_(core.DragEvent.DRAG, this.onDrag, this),
572
+ app.on_(core.DragEvent.END, this.onDragEnd, this),
573
+ app.on_(core.MoveEvent.MOVE, this.onAutoMove, this),
574
+ app.on_([core.ZoomEvent.ZOOM, core.MoveEvent.MOVE], () => { this.editor.hoverTarget = null; }),
575
+ ];
576
+ });
577
+ }
578
+ __removeListenEvents() {
579
+ if (this.__eventIds) {
580
+ this.off_(this.__eventIds);
581
+ this.__eventIds.length = 0;
582
+ }
583
+ }
584
+ destroy() {
585
+ this.editor = this.originList = this.needRemoveItem = null;
586
+ this.__removeListenEvents();
587
+ super.destroy();
588
+ }
589
+ }
590
+
591
+ const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = draw.Direction9;
592
+ const { toPoint } = draw.AroundHelper;
593
+ const EditDataHelper = {
594
+ getScaleData(bounds, direction, pointMove, lockRatio, around) {
595
+ let align, origin = {}, scaleX = 1, scaleY = 1;
596
+ const { width, height } = bounds;
597
+ if (around) {
598
+ pointMove.x *= 2;
599
+ pointMove.y *= 2;
600
+ }
601
+ if (Math.abs(pointMove.x) === width)
602
+ pointMove.x += 0.1;
603
+ if (Math.abs(pointMove.y) === height)
604
+ pointMove.y += 0.1;
605
+ const topScale = (-pointMove.y + height) / height;
606
+ const rightScale = (pointMove.x + width) / width;
607
+ const bottomScale = (pointMove.y + height) / height;
608
+ const leftScale = (-pointMove.x + width) / width;
609
+ switch (direction) {
610
+ case top:
611
+ scaleY = topScale;
612
+ align = 'bottom';
613
+ break;
614
+ case right$1:
615
+ scaleX = rightScale;
616
+ align = 'left';
617
+ break;
618
+ case bottom:
619
+ scaleY = bottomScale;
620
+ align = 'top';
621
+ break;
622
+ case left$1:
623
+ scaleX = leftScale;
624
+ align = 'right';
625
+ break;
626
+ case topLeft:
627
+ scaleY = topScale;
628
+ scaleX = leftScale;
629
+ align = 'bottom-right';
630
+ break;
631
+ case topRight:
632
+ scaleY = topScale;
633
+ scaleX = rightScale;
634
+ align = 'bottom-left';
635
+ break;
636
+ case bottomRight:
637
+ scaleY = bottomScale;
638
+ scaleX = rightScale;
639
+ align = 'top-left';
640
+ break;
641
+ case bottomLeft:
642
+ scaleY = bottomScale;
643
+ scaleX = leftScale;
644
+ align = 'top-right';
645
+ }
646
+ if (lockRatio) {
647
+ const unlockSide = lockRatio === 'corner' && direction % 2;
648
+ if (!unlockSide) {
649
+ const scale = Math.sqrt(Math.abs(scaleX * scaleY));
650
+ scaleX = scaleX < 0 ? -scale : scale;
651
+ scaleY = scaleY < 0 ? -scale : scale;
652
+ }
653
+ }
654
+ toPoint(around || align, bounds, origin);
655
+ return { origin, scaleX, scaleY, direction, lockRatio, around };
656
+ },
657
+ getRotateData(bounds, direction, current, last, around) {
658
+ let align, origin = {};
659
+ switch (direction) {
660
+ case topLeft:
661
+ align = 'bottom-right';
662
+ break;
663
+ case topRight:
664
+ align = 'bottom-left';
665
+ break;
666
+ case bottomRight:
667
+ align = 'top-left';
668
+ break;
669
+ case bottomLeft:
670
+ align = 'top-right';
671
+ break;
672
+ default:
673
+ align = 'center';
674
+ }
675
+ toPoint(around || align, bounds, origin);
676
+ return { origin, rotation: draw.PointHelper.getRotation(last, origin, current) };
677
+ },
678
+ getSkewData(bounds, direction, move, around) {
679
+ let align, origin = {}, skewX = 0, skewY = 0;
680
+ let last;
681
+ switch (direction) {
682
+ case top:
683
+ last = { x: 0.5, y: 0 };
684
+ align = 'bottom';
685
+ skewX = 1;
686
+ break;
687
+ case bottom:
688
+ last = { x: 0.5, y: 1 };
689
+ align = 'top';
690
+ skewX = 1;
691
+ break;
692
+ case left$1:
693
+ last = { x: 0, y: 0.5 };
694
+ align = 'right';
695
+ skewY = 1;
696
+ break;
697
+ case right$1:
698
+ last = { x: 1, y: 0.5 };
699
+ align = 'left';
700
+ skewY = 1;
701
+ }
702
+ const { x, y, width, height } = bounds;
703
+ last.x = x + last.x * width;
704
+ last.y = y + last.y * height;
705
+ toPoint(around || align, bounds, origin);
706
+ const rotation = draw.PointHelper.getRotation(last, origin, { x: last.x + (skewX ? move.x : 0), y: last.y + (skewY ? move.y : 0) });
707
+ skewX ? skewX = -rotation : skewY = rotation;
708
+ return { origin, skewX, skewY };
709
+ },
710
+ getAround(around, altKey) {
711
+ return (altKey && !around) ? 'center' : around;
712
+ },
713
+ getRotateDirection(direction, rotation, totalDirection = 8) {
714
+ direction = (direction + Math.round(rotation / (360 / totalDirection))) % totalDirection;
715
+ if (direction < 0)
716
+ direction += totalDirection;
717
+ return direction;
718
+ },
719
+ getFlipDirection(direction, flipedX, flipedY) {
720
+ if (flipedX) {
721
+ switch (direction) {
722
+ case left$1:
723
+ direction = right$1;
724
+ break;
725
+ case topLeft:
726
+ direction = topRight;
727
+ break;
728
+ case bottomLeft:
729
+ direction = bottomRight;
730
+ break;
731
+ case right$1:
732
+ direction = left$1;
733
+ break;
734
+ case topRight:
735
+ direction = topLeft;
736
+ break;
737
+ case bottomRight:
738
+ direction = bottomLeft;
739
+ break;
740
+ }
741
+ }
742
+ if (flipedY) {
743
+ switch (direction) {
744
+ case top:
745
+ direction = bottom;
746
+ break;
747
+ case topLeft:
748
+ direction = bottomLeft;
749
+ break;
750
+ case topRight:
751
+ direction = bottomRight;
752
+ break;
753
+ case bottom:
754
+ direction = top;
755
+ break;
756
+ case bottomLeft:
757
+ direction = topLeft;
758
+ break;
759
+ case bottomRight:
760
+ direction = topRight;
761
+ break;
762
+ }
763
+ }
764
+ return direction;
765
+ }
766
+ };
767
+
768
+ const cacheCursors = {};
769
+ function updateCursor(editor, e) {
770
+ const { editBox } = editor, point = editBox.enterPoint;
771
+ if (!point || !editor.editing || !editBox.visible)
772
+ return;
773
+ if (point.name === 'circle')
774
+ return;
775
+ let { rotation } = editBox;
776
+ const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
777
+ const { pointType } = point, { flippedX, flippedY } = editBox;
778
+ let showResize = pointType === 'resize';
779
+ if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable))
780
+ showResize = false;
781
+ const showSkew = skewable && !showResize && point.name === 'resize-line';
782
+ const cursor = showSkew ? skewCursor : (showResize ? resizeCursor : rotateCursor);
783
+ rotation += (EditDataHelper.getFlipDirection(point.direction, flippedX, flippedY) + 1) * 45;
784
+ rotation = Math.round(draw.MathHelper.formatRotation(rotation, true) / 2) * 2;
785
+ const { url, x, y } = cursor;
786
+ const key = url + rotation;
787
+ if (cacheCursors[key]) {
788
+ point.cursor = cacheCursors[key];
789
+ }
790
+ else {
791
+ cacheCursors[key] = point.cursor = { url: toDataURL(url, rotation), x, y };
792
+ }
793
+ }
794
+ function updateMoveCursor(editor) {
795
+ editor.editBox.rect.cursor = editor.mergeConfig.moveCursor;
796
+ }
797
+ function toDataURL(svg, rotation) {
798
+ return '"data:image/svg+xml,' + encodeURIComponent(svg.replace('{{rotation}}', rotation.toString())) + '"';
799
+ }
800
+
801
+ class EditPoint extends draw.Box {
802
+ }
803
+
804
+ const fourDirection = ['top', 'right', 'bottom', 'left'];
805
+ class EditBox extends draw.Group {
806
+ get flipped() { return this.flippedX || this.flippedY; }
807
+ get flippedX() { return this.scaleX < 0; }
808
+ get flippedY() { return this.scaleY < 0; }
809
+ get flippedOne() { return this.scaleX * this.scaleY < 0; }
810
+ constructor(editor) {
811
+ super();
812
+ this.view = new draw.Group();
813
+ this.rect = new draw.Box({ name: 'rect', hitFill: 'all', hitStroke: 'none', strokeAlign: 'center', hitRadius: 5 });
814
+ this.circle = new EditPoint({ name: 'circle', strokeAlign: 'center', around: 'center', cursor: 'crosshair', hitRadius: 5 });
815
+ this.buttons = new draw.Group({ around: 'center', hitSelf: false });
816
+ this.resizePoints = [];
817
+ this.rotatePoints = [];
818
+ this.resizeLines = [];
819
+ this.__eventIds = [];
820
+ this.editor = editor;
821
+ this.visible = false;
822
+ this.create();
823
+ this.rect.syncEventer = editor;
824
+ this.__listenEvents();
825
+ }
826
+ create() {
827
+ let rotatePoint, resizeLine, resizePoint;
828
+ const { view, resizePoints, rotatePoints, resizeLines, rect, circle, buttons } = this;
829
+ const arounds = ['bottom-right', 'bottom', 'bottom-left', 'left', 'top-left', 'top', 'top-right', 'right'];
830
+ for (let i = 0; i < 8; i++) {
831
+ rotatePoint = new EditPoint({ name: 'rotate-point', around: arounds[i], width: 15, height: 15, hitFill: "all" });
832
+ rotatePoints.push(rotatePoint);
833
+ this.listenPointEvents(rotatePoint, 'rotate', i);
834
+ if (i % 2) {
835
+ resizeLine = new EditPoint({ name: 'resize-line', around: 'center', width: 10, height: 10, hitFill: "all" });
836
+ resizeLines.push(resizeLine);
837
+ this.listenPointEvents(resizeLine, 'resize', i);
838
+ }
839
+ resizePoint = new EditPoint({ name: 'resize-point', hitRadius: 5 });
840
+ resizePoints.push(resizePoint);
841
+ this.listenPointEvents(resizePoint, 'resize', i);
842
+ }
843
+ buttons.add(circle);
844
+ this.listenPointEvents(circle, 'rotate', 2);
845
+ view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
846
+ this.add(view);
847
+ }
848
+ load() {
849
+ const { mergeConfig, element, single } = this.editor;
850
+ const { rect, circle, resizePoints } = this;
851
+ const { stroke, strokeWidth, moveable } = mergeConfig;
852
+ const pointsStyle = this.getPointsStyle();
853
+ const middlePointsStyle = this.getMiddlePointsStyle();
854
+ let resizeP;
855
+ for (let i = 0; i < 8; i++) {
856
+ resizeP = resizePoints[i];
857
+ resizeP.set(this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]));
858
+ if (!(i % 2))
859
+ resizeP.rotation = (i / 2) * 90;
860
+ }
861
+ circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]));
862
+ rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
863
+ rect.hittable = !single && moveable;
864
+ element.syncEventer = (single && moveable) ? rect : null;
865
+ this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null;
866
+ }
867
+ update(bounds) {
868
+ this.visible = !this.editor.element.locked;
869
+ if (this.view.worldOpacity) {
870
+ const { mergeConfig } = this.editor;
871
+ const { width, height } = bounds;
872
+ const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
873
+ const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
874
+ const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
875
+ const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
876
+ let point = {}, rotateP, resizeP, resizeL;
877
+ for (let i = 0; i < 8; i++) {
878
+ draw.AroundHelper.toPoint(draw.AroundHelper.directionData[i], bounds, point);
879
+ resizeP = resizePoints[i];
880
+ rotateP = rotatePoints[i];
881
+ resizeL = resizeLines[Math.floor(i / 2)];
882
+ resizeP.set(point);
883
+ rotateP.set(point);
884
+ resizeL.set(point);
885
+ resizeP.visible = resizeL.visible = showPoints && !!(resizeable || rotateable);
886
+ rotateP.visible = showPoints && rotateable && resizeable && !mergeConfig.rotatePoint;
887
+ if (i % 2) {
888
+ resizeP.visible = rotateP.visible = showPoints && !!middlePoint;
889
+ if (((i + 1) / 2) % 2) {
890
+ resizeL.width = width;
891
+ if (resizeP.width > width - 30)
892
+ resizeP.visible = false;
893
+ }
894
+ else {
895
+ resizeL.height = height;
896
+ resizeP.rotation = 90;
897
+ if (resizeP.width > height - 30)
898
+ resizeP.visible = false;
899
+ }
900
+ }
901
+ }
902
+ circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint;
903
+ if (rect.path)
904
+ rect.path = null;
905
+ rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
906
+ const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1);
907
+ this.buttons.visible = buttonVisible;
908
+ if (buttonVisible)
909
+ this.layoutButtons();
910
+ }
911
+ }
912
+ layoutButtons() {
913
+ const { buttons, resizePoints } = this;
914
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig;
915
+ const { flippedX, flippedY } = this;
916
+ let index = fourDirection.indexOf(buttonsDirection);
917
+ if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
918
+ if (buttonsFixed)
919
+ index = (index + 2) % 4;
920
+ }
921
+ const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
922
+ const point = resizePoints[direction * 2 + 1];
923
+ const useX = direction % 2;
924
+ const sign = (!direction || direction === 3) ? -1 : 1;
925
+ const useWidth = index % 2;
926
+ const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
927
+ if (useX) {
928
+ buttons.x = point.x + margin;
929
+ buttons.y = point.y;
930
+ }
931
+ else {
932
+ buttons.x = point.x;
933
+ buttons.y = point.y + margin;
934
+ }
935
+ if (buttonsFixed) {
936
+ buttons.rotation = (direction - index) * 90;
937
+ buttons.scaleX = flippedX ? -1 : 1;
938
+ buttons.scaleY = flippedY ? -1 : 1;
939
+ }
940
+ }
941
+ unload() {
942
+ this.visible = false;
943
+ }
944
+ getPointStyle(userStyle) {
945
+ const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig;
946
+ const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius };
947
+ return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle;
948
+ }
949
+ getPointsStyle() {
950
+ const { point } = this.editor.mergeConfig;
951
+ return point instanceof Array ? point : [point];
952
+ }
953
+ getMiddlePointsStyle() {
954
+ const { middlePoint } = this.editor.mergeConfig;
955
+ return middlePoint instanceof Array ? middlePoint : (middlePoint ? [middlePoint] : this.getPointsStyle());
956
+ }
957
+ onSelect(e) {
958
+ if (e.oldList.length === 1) {
959
+ e.oldList[0].syncEventer = null;
960
+ if (this.app)
961
+ this.app.interaction.bottomList = null;
962
+ }
963
+ }
964
+ onDragStart(e) {
965
+ this.dragging = true;
966
+ if (e.current.name === 'rect') {
967
+ const { editor } = this;
968
+ this.moving = true;
969
+ editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
970
+ editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
971
+ }
972
+ }
973
+ onDragEnd(e) {
974
+ this.dragging = false;
975
+ this.moving = false;
976
+ if (e.current.name === 'rect')
977
+ this.editor.opacity = 1;
978
+ }
979
+ onDrag(e) {
980
+ const { editor } = this;
981
+ const point = this.enterPoint = e.current;
982
+ if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) {
983
+ if (editor.mergeConfig.rotateable)
984
+ editor.onRotate(e);
985
+ }
986
+ else {
987
+ editor.onScale(e);
988
+ }
989
+ updateCursor(editor, e);
990
+ }
991
+ onArrow(e) {
992
+ if (this.editor.editing && this.editor.mergeConfig.keyEvent) {
993
+ const move = { x: 0, y: 0 };
994
+ const distance = e.shiftKey ? 10 : 1;
995
+ switch (e.code) {
996
+ case 'ArrowDown':
997
+ move.y = distance;
998
+ break;
999
+ case 'ArrowUp':
1000
+ move.y = -distance;
1001
+ break;
1002
+ case 'ArrowLeft':
1003
+ move.x = -distance;
1004
+ break;
1005
+ case 'ArrowRight':
1006
+ move.x = distance;
1007
+ }
1008
+ this.editor.move(move);
1009
+ }
1010
+ }
1011
+ onDoubleTap(e) {
1012
+ if (this.editor.mergeConfig.openInner === 'double')
1013
+ this.openInner(e);
1014
+ }
1015
+ onLongPress(e) {
1016
+ if (this.editor.mergeConfig.openInner === 'long')
1017
+ this.openInner(e);
1018
+ }
1019
+ openInner(e) {
1020
+ const { editor } = this;
1021
+ if (editor.single) {
1022
+ const { element } = editor;
1023
+ if (element.isBranch) {
1024
+ editor.openGroup(element);
1025
+ editor.target = editor.selector.findDeepOne(e);
1026
+ }
1027
+ else {
1028
+ editor.openInnerEditor();
1029
+ }
1030
+ }
1031
+ }
1032
+ listenPointEvents(point, type, direction) {
1033
+ const { editor } = this;
1034
+ point.direction = direction;
1035
+ point.pointType = type;
1036
+ point.on_(core.DragEvent.START, this.onDragStart, this);
1037
+ point.on_(core.DragEvent.DRAG, this.onDrag, this);
1038
+ point.on_(core.DragEvent.END, this.onDragEnd, this);
1039
+ point.on_(core.PointerEvent.LEAVE, () => this.enterPoint = null);
1040
+ if (point.name !== 'circle')
1041
+ point.on_(core.PointerEvent.ENTER, (e) => { this.enterPoint = point, updateCursor(editor, e); });
1042
+ }
1043
+ __listenEvents() {
1044
+ const { rect, editor } = this;
1045
+ this.__eventIds = [
1046
+ editor.on_(EditorEvent.SELECT, this.onSelect, this),
1047
+ rect.on_(core.DragEvent.START, this.onDragStart, this),
1048
+ rect.on_(core.DragEvent.DRAG, editor.onMove, editor),
1049
+ rect.on_(core.DragEvent.END, this.onDragEnd, this),
1050
+ rect.on_(core.ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
1051
+ rect.on_(core.RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
1052
+ rect.on_(core.PointerEvent.ENTER, () => updateMoveCursor(editor)),
1053
+ rect.on_(core.PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
1054
+ rect.on_(core.PointerEvent.LONG_PRESS, this.onLongPress, this)
1055
+ ];
1056
+ }
1057
+ __removeListenEvents() {
1058
+ this.off_(this.__eventIds);
1059
+ this.__eventIds.length = 0;
1060
+ }
1061
+ destroy() {
1062
+ this.editor = null;
1063
+ this.__removeListenEvents();
1064
+ super.destroy();
1065
+ }
1066
+ }
1067
+
1068
+ class EditMask extends draw.UI {
1069
+ constructor(editor) {
1070
+ super();
1071
+ this.editor = editor;
1072
+ this.hittable = false;
1073
+ }
1074
+ __draw(canvas, options) {
1075
+ const { editor } = this;
1076
+ const { mask } = editor.mergeConfig;
1077
+ if (mask && editor.list.length) {
1078
+ const { rect } = editor.editBox;
1079
+ const { width, height } = rect.__;
1080
+ canvas.resetTransform();
1081
+ canvas.fillWorld(canvas.bounds, mask);
1082
+ canvas.setWorld(rect.__world, options.matrix);
1083
+ canvas.clearRect(0, 0, width, height);
1084
+ }
1085
+ }
1086
+ destroy() {
1087
+ this.editor = null;
1088
+ super.destroy();
1089
+ }
1090
+ }
1091
+
1092
+ const filterStyle = `
1093
+ <feOffset dy="1"/>
1094
+ <feGaussianBlur stdDeviation="1.5"/>
1095
+ <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"/>
1096
+ <feBlend mode="normal" in="SourceGraphic" result="shape"/>`;
1097
+ const resizeSVG = `
1098
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
1099
+ <g filter="url(#f)">
1100
+ <g transform="rotate({{rotation}},12,12)">
1101
+ <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"/>
1102
+ <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"/>
1103
+ </g>
1104
+ </g>
1105
+ <defs>
1106
+ <filter id="f" x="-1.6" y="3.9" width="27.2" height="16.9" filterUnits="userSpaceOnUse">
1107
+ ${filterStyle}
1108
+ </filter>
1109
+ </defs>
1110
+ </svg>
1111
+ `;
1112
+ const rotateSVG = `
1113
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
1114
+ <g filter="url(#f)">
1115
+ <g transform="rotate(135,12,12),rotate({{rotation}},12,12)">
1116
+ <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"/>
1117
+ <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"/>
1118
+ </g>
1119
+ </g>
1120
+ <defs>
1121
+ <filter id="f" x="-1.6" y="-0.6" width="27.1" height="27.1" filterUnits="userSpaceOnUse">
1122
+ ${filterStyle}
1123
+ </filter>
1124
+ </defs>
1125
+ </svg>
1126
+ `;
1127
+ const skewSVG = `
1128
+ <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
1129
+ <g filter="url(#f)">
1130
+ <g transform="rotate(90,12,12),rotate({{rotation}},12,12)">
1131
+ <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"/>
1132
+ <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"/>
1133
+ </g>
1134
+ </g>
1135
+ <defs>
1136
+ <filter x="-2.8" y="1.9" width="29.6" height="23.1" filterUnits="userSpaceOnUse" >
1137
+ ${filterStyle}
1138
+ </filter>
1139
+ </defs>
1140
+ </svg>
1141
+ `;
1142
+
1143
+ const config = {
1144
+ editSize: 'size',
1145
+ keyEvent: true,
1146
+ stroke: '#836DFF',
1147
+ strokeWidth: 2,
1148
+ pointFill: '#FFFFFF',
1149
+ pointSize: 10,
1150
+ pointRadius: 16,
1151
+ rotateGap: 45,
1152
+ buttonsDirection: 'bottom',
1153
+ buttonsMargin: 12,
1154
+ hideOnSmall: true,
1155
+ moveCursor: 'move',
1156
+ resizeCursor: { url: resizeSVG, x: 12, y: 12 },
1157
+ rotateCursor: { url: rotateSVG, x: 12, y: 12 },
1158
+ skewCursor: { url: skewSVG, x: 12, y: 12 },
1159
+ selector: true,
1160
+ hover: true,
1161
+ select: 'press',
1162
+ openInner: 'double',
1163
+ boxSelect: true,
1164
+ moveable: true,
1165
+ resizeable: true,
1166
+ rotateable: true,
1167
+ skewable: true
1168
+ };
1169
+
1170
+ function simulate(editor) {
1171
+ const { simulateTarget, leafList: targetList } = editor;
1172
+ const { x, y, width, height } = new draw.Bounds().setListWithFn(targetList.list, (leaf) => leaf.worldBoxBounds);
1173
+ const parent = simulateTarget.parent = targetList.list[0].leafer.zoomLayer;
1174
+ const { scaleX, scaleY, e: worldX, f: worldY } = parent.__world;
1175
+ simulateTarget.reset({ x: (x - worldX) / scaleX, y: (y - worldY) / scaleY, width: width / scaleX, height: height / scaleY });
1176
+ }
1177
+
1178
+ function onTarget(editor, oldValue) {
1179
+ const { target } = editor;
1180
+ if (target) {
1181
+ editor.leafList = target instanceof draw.LeafList ? target : new draw.LeafList(target instanceof Array ? target : target);
1182
+ }
1183
+ else {
1184
+ editor.leafList.reset();
1185
+ }
1186
+ editor.emitEvent(new EditorEvent(EditorEvent.SELECT, { editor, value: target, oldValue }));
1187
+ editor.checkOpenedGroups();
1188
+ if (editor.editing) {
1189
+ editor.waitLeafer(() => {
1190
+ if (editor.multiple)
1191
+ simulate(editor);
1192
+ updateMoveCursor(editor);
1193
+ editor.updateEditTool();
1194
+ editor.update();
1195
+ editor.listenTargetEvents();
1196
+ });
1197
+ }
1198
+ else {
1199
+ editor.updateEditTool();
1200
+ editor.removeTargetEvents();
1201
+ }
1202
+ }
1203
+ function onHover(editor, oldValue) {
1204
+ editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }));
1205
+ }
1206
+
1207
+ const order = (a, b) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b);
1208
+ const reverseOrder = (a, b) => b.parent.children.indexOf(b) - a.parent.children.indexOf(a);
1209
+ const EditorHelper = {
1210
+ group(list, element, userGroup) {
1211
+ list.sort(reverseOrder);
1212
+ const { app, parent } = list[0];
1213
+ let group;
1214
+ if (userGroup && userGroup.add) {
1215
+ group = userGroup;
1216
+ }
1217
+ else {
1218
+ group = new draw.Group(userGroup);
1219
+ }
1220
+ parent.addAt(group, parent.children.indexOf(list[0]));
1221
+ list.sort(order);
1222
+ const matrx = new draw.Matrix(element.worldTransform);
1223
+ matrx.divideParent(parent.worldTransform);
1224
+ group.setTransform(matrx);
1225
+ group.editable = true;
1226
+ group.hitChildren = false;
1227
+ app.lockLayout();
1228
+ list.forEach(child => child.dropTo(group));
1229
+ app.unlockLayout();
1230
+ return group;
1231
+ },
1232
+ ungroup(list) {
1233
+ const { app } = list[0];
1234
+ const ungroupList = [];
1235
+ app.lockLayout();
1236
+ list.forEach(leaf => {
1237
+ if (leaf.isBranch) {
1238
+ const { parent, children } = leaf;
1239
+ while (children.length) {
1240
+ ungroupList.push(children[0]);
1241
+ children[0].dropTo(parent, parent.children.indexOf(leaf));
1242
+ }
1243
+ leaf.remove();
1244
+ }
1245
+ else {
1246
+ ungroupList.push(leaf);
1247
+ }
1248
+ });
1249
+ app.unlockLayout();
1250
+ return ungroupList;
1251
+ },
1252
+ toTop(list) {
1253
+ list.sort(order);
1254
+ list.forEach(leaf => {
1255
+ if (leaf.parent)
1256
+ leaf.parent.add(leaf);
1257
+ });
1258
+ },
1259
+ toBottom(list) {
1260
+ list.sort(reverseOrder);
1261
+ list.forEach(leaf => {
1262
+ if (leaf.parent)
1263
+ leaf.parent.addAt(leaf, 0);
1264
+ });
1265
+ }
1266
+ };
1267
+
1268
+ const debug = draw.Debug.get('EditToolCreator');
1269
+ function registerEditTool() {
1270
+ return (target) => {
1271
+ EditToolCreator.register(target);
1272
+ };
1273
+ }
1274
+ const registerInnerEditor = registerEditTool;
1275
+ const EditToolCreator = {
1276
+ list: {},
1277
+ register(EditTool) {
1278
+ const { tag } = EditTool.prototype;
1279
+ list[tag] ? debug.repeat(tag) : (list[tag] = EditTool);
1280
+ },
1281
+ get(tag, editor) {
1282
+ return new list[tag](editor);
1283
+ }
1284
+ };
1285
+ const { list } = EditToolCreator;
1286
+
1287
+ class InnerEditorEvent extends EditorEvent {
1288
+ constructor(type, data) {
1289
+ super(type, data);
1290
+ }
1291
+ }
1292
+ InnerEditorEvent.BEFORE_OPEN = 'innerEditor.before_open';
1293
+ InnerEditorEvent.OPEN = 'innerEditor.open';
1294
+ InnerEditorEvent.BEFORE_CLOSE = 'innerEditor.before_close';
1295
+ InnerEditorEvent.CLOSE = 'innerEditor.close';
1296
+
1297
+ class EditorGroupEvent extends EditorEvent {
1298
+ constructor(type, data) {
1299
+ super(type, data);
1300
+ }
1301
+ }
1302
+ EditorGroupEvent.GROUP = 'editor.group';
1303
+ EditorGroupEvent.BEFORE_UNGROUP = 'editor.before_ungroup';
1304
+ EditorGroupEvent.UNGROUP = 'editor.ungroup';
1305
+ EditorGroupEvent.OPEN = 'editor.open_group';
1306
+ EditorGroupEvent.CLOSE = 'editor.close_group';
1307
+
1308
+ class Editor extends draw.Group {
1309
+ get mergeConfig() {
1310
+ const { element, config } = this;
1311
+ return this.single && element.editConfig ? Object.assign(Object.assign({}, config), element.editConfig) : config;
1312
+ }
1313
+ get list() { return this.leafList.list; }
1314
+ get editing() { return !!this.list.length; }
1315
+ get groupOpening() { return !!this.openedGroupList.length; }
1316
+ get multiple() { return this.list.length > 1; }
1317
+ get single() { return this.list.length === 1; }
1318
+ get dragging() { return this.editBox.dragging; }
1319
+ get element() { return this.multiple ? this.simulateTarget : this.list[0]; }
1320
+ get buttons() { return this.editBox.buttons; }
1321
+ constructor(userConfig, data) {
1322
+ super(data);
1323
+ this.config = config;
1324
+ this.leafList = new draw.LeafList();
1325
+ this.openedGroupList = new draw.LeafList();
1326
+ this.simulateTarget = new draw.Rect({ visible: false });
1327
+ this.editBox = new EditBox(this);
1328
+ this.editToolList = {};
1329
+ this.selector = new EditSelect(this);
1330
+ this.editMask = new EditMask(this);
1331
+ this.targetEventIds = [];
1332
+ if (userConfig)
1333
+ this.config = draw.DataHelper.default(userConfig, this.config);
1334
+ this.addMany(this.editMask, this.selector, this.editBox);
1335
+ }
1336
+ select(target) {
1337
+ this.target = target;
1338
+ }
1339
+ cancel() {
1340
+ this.target = null;
1341
+ }
1342
+ hasItem(item) {
1343
+ return this.leafList.has(item);
1344
+ }
1345
+ addItem(item) {
1346
+ if (!this.hasItem(item) && !item.locked)
1347
+ this.leafList.add(item), this.target = this.leafList.list;
1348
+ }
1349
+ removeItem(item) {
1350
+ if (this.hasItem(item))
1351
+ this.leafList.remove(item), this.target = this.leafList.list;
1352
+ }
1353
+ shiftItem(item) {
1354
+ this.hasItem(item) ? this.removeItem(item) : this.addItem(item);
1355
+ }
1356
+ update() {
1357
+ if (this.editing) {
1358
+ if (this.innerEditing)
1359
+ this.innerEditor.update();
1360
+ this.editTool.update();
1361
+ this.selector.update();
1362
+ }
1363
+ }
1364
+ updateEditBox() {
1365
+ if (this.multiple)
1366
+ simulate(this);
1367
+ this.update();
1368
+ }
1369
+ updateEditTool() {
1370
+ const tool = this.editTool;
1371
+ if (tool) {
1372
+ this.editBox.unload();
1373
+ tool.unload();
1374
+ this.editTool = null;
1375
+ }
1376
+ if (this.editing) {
1377
+ const tag = this.single ? this.list[0].editOuter : 'EditTool';
1378
+ this.editTool = this.editToolList[tag] = this.editToolList[tag] || EditToolCreator.get(tag, this);
1379
+ this.editBox.load();
1380
+ this.editTool.load();
1381
+ }
1382
+ }
1383
+ getEditSize(_ui) {
1384
+ return this.mergeConfig.editSize;
1385
+ }
1386
+ onMove(e) {
1387
+ const total = { x: e.totalX, y: e.totalY };
1388
+ if (e.shiftKey) {
1389
+ if (Math.abs(total.x) > Math.abs(total.y))
1390
+ total.y = 0;
1391
+ else
1392
+ total.x = 0;
1393
+ }
1394
+ this.move(core.DragEvent.getValidMove(this.element, this.dragStartPoint, total));
1395
+ }
1396
+ onScale(e) {
1397
+ const { element } = this;
1398
+ if (e instanceof core.ZoomEvent) {
1399
+ if (this.mergeConfig.resizeable === 'zoom') {
1400
+ e.stop();
1401
+ this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
1402
+ }
1403
+ }
1404
+ else {
1405
+ const { direction } = e.current;
1406
+ let { around, lockRatio } = this.mergeConfig;
1407
+ if (e.shiftKey || element.lockRatio)
1408
+ lockRatio = true;
1409
+ const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
1410
+ if (this.editTool.onScaleWithDrag) {
1411
+ data.drag = e;
1412
+ this.scaleWithDrag(data);
1413
+ }
1414
+ else {
1415
+ this.scaleOf(data.origin, data.scaleX, data.scaleY);
1416
+ }
1417
+ }
1418
+ }
1419
+ onRotate(e) {
1420
+ const { skewable, around, rotateGap } = this.mergeConfig;
1421
+ const { direction, name } = e.current;
1422
+ if (skewable && name === 'resize-line')
1423
+ return this.onSkew(e);
1424
+ const { element } = this;
1425
+ let origin, rotation;
1426
+ if (e instanceof core.RotateEvent) {
1427
+ if (this.mergeConfig.rotateable === 'rotate') {
1428
+ e.stop();
1429
+ rotation = e.rotation, origin = element.getInnerPoint(e);
1430
+ }
1431
+ else
1432
+ return;
1433
+ }
1434
+ else {
1435
+ const last = { x: e.x - e.moveX, y: e.y - e.moveY };
1436
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
1437
+ rotation = data.rotation;
1438
+ origin = data.origin;
1439
+ }
1440
+ rotation = draw.MathHelper.getGapRotation(rotation, rotateGap, element.rotation);
1441
+ if (!rotation)
1442
+ return;
1443
+ if (element.scaleX * element.scaleY < 0)
1444
+ rotation = -rotation;
1445
+ this.rotateOf(origin, draw.MathHelper.float(rotation, 2));
1446
+ }
1447
+ onSkew(e) {
1448
+ const { element } = this;
1449
+ const { around } = this.mergeConfig;
1450
+ const { origin, skewX, skewY } = EditDataHelper.getSkewData(element.boxBounds, e.current.direction, e.getInnerMove(element), EditDataHelper.getAround(around, e.altKey));
1451
+ if (!skewX && !skewY)
1452
+ return;
1453
+ this.skewOf(origin, skewX, skewY);
1454
+ }
1455
+ move(x, y = 0) {
1456
+ if (!this.mergeConfig.moveable || this.element.locked)
1457
+ return;
1458
+ const { element } = this;
1459
+ const world = element.getWorldPointByLocal(typeof x === 'object' ? Object.assign({}, x) : { x, y }, null, true);
1460
+ const event = new EditorMoveEvent(EditorMoveEvent.MOVE, { target: element, editor: this, moveX: world.x, moveY: world.y });
1461
+ this.editTool.onMove(event);
1462
+ this.emitEvent(event);
1463
+ if (this.multiple)
1464
+ element.move(x, y);
1465
+ }
1466
+ scaleWithDrag(data) {
1467
+ if (!this.mergeConfig.resizeable || this.element.locked)
1468
+ return;
1469
+ const { element } = this;
1470
+ const worldOrigin = element.getWorldPoint(data.origin);
1471
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
1472
+ this.editTool.onScaleWithDrag(event);
1473
+ this.emitEvent(event);
1474
+ }
1475
+ scaleOf(origin, scaleX, scaleY = scaleX, _resize) {
1476
+ if (!this.mergeConfig.resizeable || this.element.locked)
1477
+ return;
1478
+ const { element } = this;
1479
+ const worldOrigin = element.getWorldPoint(draw.LeafHelper.getInnerOrigin(element, origin));
1480
+ let transform;
1481
+ if (this.multiple) {
1482
+ const oldMatrix = new draw.Matrix(element.worldTransform);
1483
+ element.scaleOf(origin, scaleX, scaleY);
1484
+ transform = new draw.Matrix(element.worldTransform).divide(oldMatrix);
1485
+ }
1486
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
1487
+ this.editTool.onScale(event);
1488
+ this.emitEvent(event);
1489
+ }
1490
+ rotateOf(origin, rotation) {
1491
+ if (!this.mergeConfig.rotateable || this.element.locked)
1492
+ return;
1493
+ const { element } = this;
1494
+ const worldOrigin = element.getWorldPoint(draw.LeafHelper.getInnerOrigin(element, origin));
1495
+ let transform;
1496
+ if (this.multiple) {
1497
+ const oldMatrix = new draw.Matrix(element.worldTransform);
1498
+ element.rotateOf(origin, rotation);
1499
+ transform = new draw.Matrix(element.worldTransform).divide(oldMatrix);
1500
+ }
1501
+ const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
1502
+ this.editTool.onRotate(event);
1503
+ this.emitEvent(event);
1504
+ }
1505
+ skewOf(origin, skewX, skewY = 0, _resize) {
1506
+ if (!this.mergeConfig.skewable || this.element.locked)
1507
+ return;
1508
+ const { element } = this;
1509
+ const worldOrigin = element.getWorldPoint(draw.LeafHelper.getInnerOrigin(element, origin));
1510
+ let transform;
1511
+ if (this.multiple) {
1512
+ const oldMatrix = new draw.Matrix(element.worldTransform);
1513
+ element.skewOf(origin, skewX, skewY);
1514
+ transform = new draw.Matrix(element.worldTransform).divide(oldMatrix);
1515
+ }
1516
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
1517
+ target: element, editor: this, skewX, skewY, transform, worldOrigin
1518
+ });
1519
+ this.editTool.onSkew(event);
1520
+ this.emitEvent(event);
1521
+ }
1522
+ group(userGroup) {
1523
+ if (this.multiple) {
1524
+ this.target = EditorHelper.group(this.list, this.element, userGroup);
1525
+ this.emitGroupEvent(EditorGroupEvent.GROUP, this.target);
1526
+ }
1527
+ return this.target;
1528
+ }
1529
+ ungroup() {
1530
+ const { list } = this;
1531
+ if (list.length) {
1532
+ list.forEach(item => item.isBranch && this.emitGroupEvent(EditorGroupEvent.BEFORE_UNGROUP, item));
1533
+ this.target = EditorHelper.ungroup(list);
1534
+ list.forEach(item => item.isBranch && this.emitGroupEvent(EditorGroupEvent.UNGROUP, item));
1535
+ }
1536
+ return this.list;
1537
+ }
1538
+ openGroup(group) {
1539
+ this.openedGroupList.add(group);
1540
+ group.hitChildren = true;
1541
+ this.emitGroupEvent(EditorGroupEvent.OPEN, group);
1542
+ }
1543
+ closeGroup(group) {
1544
+ this.openedGroupList.remove(group);
1545
+ group.hitChildren = false;
1546
+ this.emitGroupEvent(EditorGroupEvent.CLOSE, group);
1547
+ }
1548
+ checkOpenedGroups() {
1549
+ const opened = this.openedGroupList;
1550
+ if (opened.length) {
1551
+ let { list } = opened;
1552
+ if (this.editing)
1553
+ list = [], opened.forEach(item => this.list.every(leaf => !draw.LeafHelper.hasParent(leaf, item)) && list.push(item));
1554
+ list.forEach(item => this.closeGroup(item));
1555
+ }
1556
+ if (this.editing && !this.selector.dragging)
1557
+ this.checkDeepSelect();
1558
+ }
1559
+ checkDeepSelect() {
1560
+ let parent, { list } = this;
1561
+ for (let i = 0; i < list.length; i++) {
1562
+ parent = list[i].parent;
1563
+ while (parent && !parent.hitChildren) {
1564
+ this.openGroup(parent);
1565
+ parent = parent.parent;
1566
+ }
1567
+ }
1568
+ }
1569
+ emitGroupEvent(type, group) {
1570
+ const event = new EditorGroupEvent(type, { editTarget: group });
1571
+ this.emitEvent(event);
1572
+ group.emitEvent(event);
1573
+ }
1574
+ openInnerEditor(target) {
1575
+ if (target)
1576
+ this.target = target;
1577
+ if (this.single) {
1578
+ const editTarget = this.element;
1579
+ const tag = editTarget.editInner;
1580
+ if (tag && EditToolCreator.list[tag]) {
1581
+ this.editTool.unload();
1582
+ this.innerEditing = true;
1583
+ this.innerEditor = this.editToolList[tag] || EditToolCreator.get(tag, this);
1584
+ this.innerEditor.editTarget = editTarget;
1585
+ this.emitInnerEvent(InnerEditorEvent.BEFORE_OPEN);
1586
+ this.innerEditor.load();
1587
+ this.emitInnerEvent(InnerEditorEvent.OPEN);
1588
+ }
1589
+ }
1590
+ }
1591
+ closeInnerEditor() {
1592
+ if (this.innerEditing) {
1593
+ this.innerEditing = false;
1594
+ this.emitInnerEvent(InnerEditorEvent.BEFORE_CLOSE);
1595
+ this.innerEditor.unload();
1596
+ this.emitInnerEvent(InnerEditorEvent.CLOSE);
1597
+ this.editTool.load();
1598
+ this.innerEditor = null;
1599
+ }
1600
+ }
1601
+ emitInnerEvent(type) {
1602
+ const { innerEditor } = this;
1603
+ const { editTarget } = innerEditor;
1604
+ const event = new InnerEditorEvent(type, { editTarget, innerEditor });
1605
+ this.emitEvent(event);
1606
+ editTarget.emitEvent(event);
1607
+ }
1608
+ lock() {
1609
+ this.list.forEach(leaf => leaf.locked = true);
1610
+ this.update();
1611
+ }
1612
+ unlock() {
1613
+ this.list.forEach(leaf => leaf.locked = false);
1614
+ this.update();
1615
+ }
1616
+ toTop() {
1617
+ if (this.list.length) {
1618
+ EditorHelper.toTop(this.list);
1619
+ this.leafList.update();
1620
+ }
1621
+ }
1622
+ toBottom() {
1623
+ if (this.list.length) {
1624
+ EditorHelper.toBottom(this.list);
1625
+ this.leafList.update();
1626
+ }
1627
+ }
1628
+ listenTargetEvents() {
1629
+ if (!this.targetEventIds.length) {
1630
+ const { leafer } = this.list[0];
1631
+ this.targetEventIds = [
1632
+ leafer.on_(draw.RenderEvent.START, this.update, this),
1633
+ leafer.on_([core.KeyEvent.HOLD, core.KeyEvent.UP], (e) => { updateCursor(this, e); }),
1634
+ leafer.on_(core.KeyEvent.DOWN, this.editBox.onArrow, this.editBox)
1635
+ ];
1636
+ }
1637
+ }
1638
+ removeTargetEvents() {
1639
+ const { targetEventIds } = this;
1640
+ if (targetEventIds.length) {
1641
+ this.off_(targetEventIds);
1642
+ targetEventIds.length = 0;
1643
+ }
1644
+ }
1645
+ destroy() {
1646
+ if (!this.destroyed) {
1647
+ this.simulateTarget.destroy();
1648
+ Object.values(this.editToolList).forEach(item => item.destroy());
1649
+ this.editToolList = {};
1650
+ this.target = this.hoverTarget = this.simulateTarget = this.editTool = this.innerEditor = null;
1651
+ super.destroy();
1652
+ }
1653
+ }
1654
+ }
1655
+ __decorate([
1656
+ targetAttr(onHover)
1657
+ ], Editor.prototype, "hoverTarget", void 0);
1658
+ __decorate([
1659
+ targetAttr(onTarget)
1660
+ ], Editor.prototype, "target", void 0);
1661
+
1662
+ class InnerEditor {
1663
+ static registerInnerEditor() {
1664
+ EditToolCreator.register(this);
1665
+ }
1666
+ get tag() { return 'InnerEditor'; }
1667
+ get editBox() { return this.editor.editBox; }
1668
+ constructor(editor) {
1669
+ this.editor = editor;
1670
+ this.create();
1671
+ }
1672
+ onCreate() { }
1673
+ create() {
1674
+ this.view = new draw.Group();
1675
+ this.onCreate();
1676
+ }
1677
+ onLoad() { }
1678
+ load() {
1679
+ this.editor.selector.hittable = this.editor.app.tree.hitChildren = false;
1680
+ this.onLoad();
1681
+ }
1682
+ onUpdate() { }
1683
+ update() { this.onUpdate(); }
1684
+ onUnload() { }
1685
+ unload() {
1686
+ this.editor.selector.hittable = this.editor.app.tree.hitChildren = true;
1687
+ this.onUnload();
1688
+ }
1689
+ onDestroy() { }
1690
+ destroy() {
1691
+ this.onDestroy();
1692
+ if (this.editor) {
1693
+ if (this.view)
1694
+ this.view.destroy();
1695
+ if (this.eventIds)
1696
+ this.editor.off_(this.eventIds);
1697
+ this.editor = this.view = this.eventIds = null;
1698
+ }
1699
+ }
1700
+ }
1701
+
1702
+ exports.EditTool = class EditTool extends InnerEditor {
1703
+ static registerEditTool() {
1704
+ EditToolCreator.register(this);
1705
+ }
1706
+ get tag() { return 'EditTool'; }
1707
+ onMove(e) {
1708
+ const { moveX, moveY, editor } = e;
1709
+ const { app, list } = editor;
1710
+ app.lockLayout();
1711
+ list.forEach(target => {
1712
+ target.moveWorld(moveX, moveY);
1713
+ });
1714
+ app.unlockLayout();
1715
+ }
1716
+ onScale(e) {
1717
+ const { scaleX, scaleY, transform, worldOrigin, editor } = e;
1718
+ const { app, list } = editor;
1719
+ app.lockLayout();
1720
+ list.forEach(target => {
1721
+ const resize = editor.getEditSize(target) !== 'scale';
1722
+ if (transform) {
1723
+ target.transformWorld(transform, resize);
1724
+ }
1725
+ else {
1726
+ target.scaleOfWorld(worldOrigin, scaleX, scaleY, resize);
1727
+ }
1728
+ });
1729
+ app.unlockLayout();
1730
+ }
1731
+ onRotate(e) {
1732
+ const { rotation, transform, worldOrigin, editor } = e;
1733
+ const { app, list } = editor;
1734
+ app.lockLayout();
1735
+ list.forEach(target => {
1736
+ const resize = editor.getEditSize(target) !== 'scale';
1737
+ if (transform) {
1738
+ target.transformWorld(transform, resize);
1739
+ }
1740
+ else {
1741
+ target.rotateOfWorld(worldOrigin, rotation);
1742
+ }
1743
+ });
1744
+ app.unlockLayout();
1745
+ }
1746
+ onSkew(e) {
1747
+ const { skewX, skewY, transform, worldOrigin, editor } = e;
1748
+ const { app, list } = editor;
1749
+ app.lockLayout();
1750
+ list.forEach(target => {
1751
+ const resize = editor.getEditSize(target) !== 'scale';
1752
+ if (transform) {
1753
+ target.transformWorld(transform, resize);
1754
+ }
1755
+ else {
1756
+ target.skewOfWorld(worldOrigin, skewX, skewY, resize);
1757
+ }
1758
+ });
1759
+ app.unlockLayout();
1760
+ }
1761
+ load() {
1762
+ this.editBox.view.visible = true;
1763
+ this.onLoad();
1764
+ }
1765
+ update() {
1766
+ const { editor, editBox } = this;
1767
+ const { simulateTarget, element } = editor;
1768
+ if (editor.multiple)
1769
+ simulateTarget.parent.updateLayout();
1770
+ const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = element.getLayoutBounds('box', editor, true);
1771
+ editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY });
1772
+ editBox.update({ x: 0, y: 0, width, height });
1773
+ this.onUpdate();
1774
+ }
1775
+ unload() {
1776
+ this.editBox.view.visible = false;
1777
+ this.onUnload();
1778
+ }
1779
+ };
1780
+ exports.EditTool = __decorate([
1781
+ registerEditTool()
1782
+ ], exports.EditTool);
1783
+
1784
+ const { left, right } = draw.Direction9;
1785
+ const { move, copy } = draw.PointHelper;
1786
+ exports.LineEditTool = class LineEditTool extends exports.EditTool {
1787
+ constructor() {
1788
+ super(...arguments);
1789
+ this.scaleOfEvent = true;
1790
+ }
1791
+ get tag() { return 'LineEditTool'; }
1792
+ onScaleWithDrag(e) {
1793
+ const { drag, direction, lockRatio, around } = e;
1794
+ const line = e.target;
1795
+ const isDragFrom = direction === left;
1796
+ if (line.pathInputed) {
1797
+ const { path } = line.__;
1798
+ const { from, to } = this.getFromToByPath(path);
1799
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio));
1800
+ path[1] = from.x, path[2] = from.y;
1801
+ path[4] = to.x, path[5] = to.y;
1802
+ line.path = path;
1803
+ }
1804
+ else if (line.points) {
1805
+ const { points } = line;
1806
+ const { from, to } = this.getFromToByPoints(points);
1807
+ this.dragPoint(from, to, isDragFrom, around, this.getInnerMove(line, drag, lockRatio));
1808
+ points[0] = from.x, points[1] = from.y;
1809
+ points[2] = to.x, points[3] = to.y;
1810
+ line.points = points;
1811
+ }
1812
+ else {
1813
+ const from = draw.getPointData();
1814
+ const { toPoint } = line;
1815
+ line.rotation = 0;
1816
+ this.dragPoint(from, toPoint, isDragFrom, around, this.getInnerMove(line, drag, lockRatio));
1817
+ line.getLocalPointByInner(from, null, null, true);
1818
+ line.getLocalPointByInner(toPoint, null, null, true);
1819
+ line.x = from.x;
1820
+ line.y = from.y;
1821
+ line.getInnerPointByLocal(toPoint, null, null, true);
1822
+ line.toPoint = toPoint;
1823
+ }
1824
+ }
1825
+ getInnerMove(ui, event, lockRatio) {
1826
+ const movePoint = event.getInnerMove(ui);
1827
+ if (lockRatio) {
1828
+ if (Math.abs(movePoint.x) > Math.abs(movePoint.y)) {
1829
+ movePoint.y = 0;
1830
+ }
1831
+ else {
1832
+ movePoint.x = 0;
1833
+ }
1834
+ }
1835
+ return movePoint;
1836
+ }
1837
+ getFromToByPath(path) {
1838
+ return {
1839
+ from: { x: path[1], y: path[2] },
1840
+ to: { x: path[4], y: path[5] }
1841
+ };
1842
+ }
1843
+ getFromToByPoints(points) {
1844
+ return {
1845
+ from: { x: points[0], y: points[1] },
1846
+ to: { x: points[2], y: points[3] }
1847
+ };
1848
+ }
1849
+ dragPoint(fromPoint, toPoint, isDragFrom, around, movePoint) {
1850
+ const { x, y } = movePoint;
1851
+ if (isDragFrom) {
1852
+ move(fromPoint, x, y);
1853
+ if (around)
1854
+ move(toPoint, -x, -y);
1855
+ }
1856
+ else {
1857
+ if (around)
1858
+ move(fromPoint, -x, -y);
1859
+ move(toPoint, x, y);
1860
+ }
1861
+ }
1862
+ onSkew(_e) {
1863
+ }
1864
+ onUpdate() {
1865
+ const { editBox } = this, { rotatePoints, resizeLines, resizePoints, rect } = editBox;
1866
+ const line = this.editor.element;
1867
+ let fromTo, leftOrRight;
1868
+ if (line.pathInputed)
1869
+ fromTo = this.getFromToByPath(line.__.path);
1870
+ else if (line.points)
1871
+ fromTo = this.getFromToByPoints(line.__.points);
1872
+ if (fromTo) {
1873
+ const { from, to } = fromTo;
1874
+ line.innerToWorld(from, from, false, editBox);
1875
+ line.innerToWorld(to, to, false, editBox);
1876
+ rect.pen.clearPath().moveTo(from.x, from.y).lineTo(to.x, to.y);
1877
+ copy(resizePoints[7], from);
1878
+ copy(rotatePoints[7], from);
1879
+ copy(resizePoints[3], to);
1880
+ copy(rotatePoints[3], to);
1881
+ }
1882
+ for (let i = 0; i < 8; i++) {
1883
+ if (i < 4)
1884
+ resizeLines[i].visible = false;
1885
+ leftOrRight = i === left || i === right;
1886
+ resizePoints[i].visible = leftOrRight;
1887
+ rotatePoints[i].visible = fromTo ? false : leftOrRight;
1888
+ }
1889
+ }
1890
+ };
1891
+ exports.LineEditTool = __decorate([
1892
+ registerEditTool()
1893
+ ], exports.LineEditTool);
1894
+
1895
+ draw.Creator.editor = function (options) { return new Editor(options); };
1896
+ draw.UI.setEditConfig = function (config) {
1897
+ draw.defineKey(this.prototype, 'editConfig', {
1898
+ get() { return typeof config === 'function' ? config(this) : config; }
1899
+ });
1900
+ };
1901
+ draw.UI.setEditOuter = function (toolName) {
1902
+ draw.defineKey(this.prototype, 'editOuter', {
1903
+ get() { return typeof toolName === 'string' ? toolName : toolName(this); }
1904
+ });
1905
+ };
1906
+ draw.UI.setEditInner = function (editorName) {
1907
+ draw.defineKey(this.prototype, 'editInner', {
1908
+ get() { return typeof editorName === 'string' ? editorName : editorName(this); }
1909
+ });
1910
+ };
1911
+
1912
+ exports.EditBox = EditBox;
1913
+ exports.EditDataHelper = EditDataHelper;
1914
+ exports.EditPoint = EditPoint;
1915
+ exports.EditSelect = EditSelect;
1916
+ exports.EditSelectHelper = EditSelectHelper;
1917
+ exports.EditToolCreator = EditToolCreator;
1918
+ exports.Editor = Editor;
1919
+ exports.EditorEvent = EditorEvent;
1920
+ exports.EditorGroupEvent = EditorGroupEvent;
1921
+ exports.EditorHelper = EditorHelper;
1922
+ exports.EditorMoveEvent = EditorMoveEvent;
1923
+ exports.EditorRotateEvent = EditorRotateEvent;
1924
+ exports.EditorScaleEvent = EditorScaleEvent;
1925
+ exports.EditorSkewEvent = EditorSkewEvent;
1926
+ exports.InnerEditor = InnerEditor;
1927
+ exports.InnerEditorEvent = InnerEditorEvent;
1928
+ exports.PathScaler = PathScaler;
1929
+ exports.SelectArea = SelectArea;
1930
+ exports.Stroker = Stroker;
1931
+ exports.registerEditTool = registerEditTool;
1932
+ exports.registerInnerEditor = registerInnerEditor;
1933
+ exports.scaleResize = scaleResize;
1934
+ exports.scaleResizeFontSize = scaleResizeFontSize;
1935
+ exports.scaleResizeGroup = scaleResizeGroup;
1936
+ exports.scaleResizePath = scaleResizePath;
1937
+ exports.scaleResizePoints = scaleResizePoints;