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