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