@leafer-in/editor 1.6.7 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/editor.js CHANGED
@@ -45,41 +45,10 @@ this.LeaferIN.editor = (function (exports, draw, core) {
45
45
  }
46
46
  EditorEvent.BEFORE_SELECT = 'editor.before_select';
47
47
  EditorEvent.SELECT = 'editor.select';
48
+ EditorEvent.AFTER_SELECT = 'editor.after_select';
48
49
  EditorEvent.BEFORE_HOVER = 'editor.before_hover';
49
50
  EditorEvent.HOVER = 'editor.hover';
50
51
 
51
- class EditorMoveEvent extends EditorEvent {
52
- constructor(type, data) {
53
- super(type, data);
54
- }
55
- }
56
- EditorMoveEvent.BEFORE_MOVE = 'editor.before_move';
57
- EditorMoveEvent.MOVE = 'editor.move';
58
-
59
- class EditorScaleEvent extends EditorEvent {
60
- constructor(type, data) {
61
- super(type, data);
62
- }
63
- }
64
- EditorScaleEvent.BEFORE_SCALE = 'editor.before_scale';
65
- EditorScaleEvent.SCALE = 'editor.scale';
66
-
67
- class EditorRotateEvent extends EditorEvent {
68
- constructor(type, data) {
69
- super(type, data);
70
- }
71
- }
72
- EditorRotateEvent.BEFORE_ROTATE = 'editor.before_rotate';
73
- EditorRotateEvent.ROTATE = 'editor.rotate';
74
-
75
- class EditorSkewEvent extends EditorEvent {
76
- constructor(type, data) {
77
- super(type, data);
78
- }
79
- }
80
- EditorSkewEvent.BEFORE_SKEW = 'editor.before_skew';
81
- EditorSkewEvent.SKEW = 'editor.skew';
82
-
83
52
  function targetAttr(fn) {
84
53
  return (target, key) => {
85
54
  const privateKey = '_' + key;
@@ -93,6 +62,8 @@ this.LeaferIN.editor = (function (exports, draw, core) {
93
62
  if (isSelect) {
94
63
  if (value instanceof Array && value.length > 1 && value[0].locked)
95
64
  value.splice(0, 1);
65
+ if (this.single)
66
+ this.element.syncEventer = null;
96
67
  const { beforeSelect } = this.config;
97
68
  if (beforeSelect) {
98
69
  const check = beforeSelect({ target: value });
@@ -116,9 +87,11 @@ this.LeaferIN.editor = (function (exports, draw, core) {
116
87
  return (target, key) => {
117
88
  draw.defineKey(target, key, {
118
89
  get() {
119
- const { config, element, dragPoint } = this, mergeConfig = Object.assign({}, config);
90
+ const { config, element, dragPoint, editBox } = this, mergeConfig = Object.assign({}, config);
120
91
  if (element && element.editConfig)
121
92
  Object.assign(mergeConfig, element.editConfig);
93
+ if (editBox.config)
94
+ Object.assign(mergeConfig, editBox.config);
122
95
  if (dragPoint) {
123
96
  if (dragPoint.editConfig)
124
97
  Object.assign(mergeConfig, dragPoint.editConfig);
@@ -150,14 +123,17 @@ this.LeaferIN.editor = (function (exports, draw, core) {
150
123
  this.strokeAlign = 'center';
151
124
  }
152
125
  setTarget(target, style) {
153
- this.set(style);
126
+ if (style)
127
+ this.set(style);
154
128
  this.target = target;
155
129
  this.update();
156
130
  }
157
- update() {
131
+ update(style) {
158
132
  const { list } = this;
159
133
  if (list.length) {
160
134
  setListWithFn(bounds$1, list, worldBounds);
135
+ if (style)
136
+ this.set(style);
161
137
  this.set(bounds$1);
162
138
  this.visible = true;
163
139
  }
@@ -300,15 +276,14 @@ this.LeaferIN.editor = (function (exports, draw, core) {
300
276
  }
301
277
  onSelect() {
302
278
  if (this.running) {
303
- const { mergeConfig, list } = this.editor;
304
- const { stroke, strokeWidth, selectedStyle } = mergeConfig;
305
- this.targetStroker.setTarget(list, Object.assign({ stroke, strokeWidth: Math.max(1, strokeWidth / 2) }, (selectedStyle || {})));
279
+ this.targetStroker.setTarget(this.editor.list);
306
280
  this.hoverStroker.target = null;
307
281
  }
308
282
  }
309
283
  update() {
310
284
  this.hoverStroker.update();
311
- this.targetStroker.update();
285
+ const { stroke, strokeWidth, selectedStyle } = this.editor.mergedConfig;
286
+ this.targetStroker.update(Object.assign({ stroke, strokeWidth: strokeWidth && Math.max(1, strokeWidth / 2) }, (selectedStyle || {})));
312
287
  }
313
288
  onPointerMove(e) {
314
289
  const { app, editor } = this;
@@ -490,16 +465,16 @@ this.LeaferIN.editor = (function (exports, draw, core) {
490
465
  const { toPoint } = draw.AroundHelper;
491
466
  const { within } = draw.MathHelper;
492
467
  const EditDataHelper = {
493
- getScaleData(element, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
468
+ getScaleData(target, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
494
469
  let align, origin = {}, scaleX = 1, scaleY = 1;
495
- const { boxBounds, widthRange, heightRange, dragBounds, worldBoxBounds } = element;
470
+ const { boxBounds, widthRange, heightRange, dragBounds, worldBoxBounds } = target;
496
471
  const { width, height } = startBounds;
497
472
  if (around) {
498
473
  totalMove.x *= 2;
499
474
  totalMove.y *= 2;
500
475
  }
501
- const originChangedScaleX = element.scaleX / startBounds.scaleX;
502
- const originChangedScaleY = element.scaleY / startBounds.scaleY;
476
+ const originChangedScaleX = target.scaleX / startBounds.scaleX;
477
+ const originChangedScaleY = target.scaleY / startBounds.scaleY;
503
478
  const signX = originChangedScaleX < 0 ? -1 : 1;
504
479
  const signY = originChangedScaleY < 0 ? -1 : 1;
505
480
  const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width;
@@ -575,7 +550,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
575
550
  if (useScaleY)
576
551
  scaleY /= changedScaleY;
577
552
  if (!flipable) {
578
- const { worldTransform } = element;
553
+ const { worldTransform } = target;
579
554
  if (scaleX < 0)
580
555
  scaleX = 1 / boxBounds.width / worldTransform.scaleX;
581
556
  if (scaleY < 0)
@@ -583,24 +558,26 @@ this.LeaferIN.editor = (function (exports, draw, core) {
583
558
  }
584
559
  toPoint(around || align, boxBounds, origin, true);
585
560
  if (dragBounds) {
586
- const allowBounds = dragBounds === 'parent' ? element.parent.boxBounds : dragBounds;
587
- const localBounds = new draw.Bounds(element.__localBoxBounds);
588
- localBounds.scaleOf(element.getLocalPointByInner(origin), scaleX, scaleY);
589
- if (!draw.BoundsHelper.includes(allowBounds, localBounds)) {
590
- const realBounds = localBounds.getIntersect(allowBounds);
591
- const fitScaleX = realBounds.width / localBounds.width, fitScaleY = realBounds.height / localBounds.height;
592
- if (useScaleX)
593
- scaleX *= fitScaleX;
594
- if (useScaleY)
595
- scaleY *= fitScaleY;
561
+ const allowBounds = dragBounds === 'parent' ? target.parent.boxBounds : dragBounds;
562
+ const childBounds = new draw.Bounds(target.__localBoxBounds);
563
+ if (draw.BoundsHelper.includes(new draw.Bounds(allowBounds).spread(0.1), childBounds)) {
564
+ childBounds.scaleOf(target.getLocalPointByInner(origin), scaleX, scaleY);
565
+ if (!draw.BoundsHelper.includes(allowBounds, childBounds)) {
566
+ const realBounds = childBounds.getIntersect(allowBounds);
567
+ const fitScaleX = realBounds.width / childBounds.width, fitScaleY = realBounds.height / childBounds.height;
568
+ if (useScaleX)
569
+ scaleX *= fitScaleX;
570
+ if (useScaleY)
571
+ scaleY *= fitScaleY;
572
+ }
596
573
  }
597
574
  }
598
575
  if (useScaleX && widthRange) {
599
- const nowWidth = boxBounds.width * element.scaleX;
576
+ const nowWidth = boxBounds.width * target.scaleX;
600
577
  scaleX = within(nowWidth * scaleX, widthRange) / nowWidth;
601
578
  }
602
579
  if (useScaleY && heightRange) {
603
- const nowHeight = boxBounds.height * element.scaleY;
580
+ const nowHeight = boxBounds.height * target.scaleY;
604
581
  scaleY = within(nowHeight * scaleY, heightRange) / nowHeight;
605
582
  }
606
583
  if (useScaleX && Math.abs(scaleX * worldBoxBounds.width) < 1)
@@ -611,7 +588,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
611
588
  scaleY = scaleX = Math.min(scaleX, scaleY);
612
589
  return { origin, scaleX, scaleY, direction, lockRatio, around };
613
590
  },
614
- getRotateData(bounds, direction, current, last, around) {
591
+ getRotateData(target, direction, current, last, around) {
615
592
  let align, origin = {};
616
593
  switch (direction) {
617
594
  case topLeft:
@@ -629,8 +606,8 @@ this.LeaferIN.editor = (function (exports, draw, core) {
629
606
  default:
630
607
  align = 'center';
631
608
  }
632
- toPoint(around || align, bounds, origin, true);
633
- return { origin, rotation: draw.PointHelper.getRotation(last, origin, current) };
609
+ toPoint(around || align, target.boxBounds, origin, true);
610
+ return { origin, rotation: draw.PointHelper.getRotation(last, target.getWorldPointByBox(origin), current) };
634
611
  },
635
612
  getSkewData(bounds, direction, move, around) {
636
613
  let align, origin = {}, skewX = 0, skewY = 0;
@@ -727,9 +704,9 @@ this.LeaferIN.editor = (function (exports, draw, core) {
727
704
  };
728
705
 
729
706
  const cacheCursors = {};
730
- function updateCursor(editor, e) {
731
- const { editBox } = editor, point = editBox.enterPoint;
732
- if (!point || !editor.editing || !editBox.visible)
707
+ function updatePointCursor(editBox, e) {
708
+ const { enterPoint: point, dragging, skewing, resizing, flippedX, flippedY } = editBox;
709
+ if (!point || !editBox.editor.editing || !editBox.canUse)
733
710
  return;
734
711
  if (point.name === 'circle')
735
712
  return;
@@ -739,13 +716,14 @@ this.LeaferIN.editor = (function (exports, draw, core) {
739
716
  return;
740
717
  }
741
718
  let { rotation } = editBox;
742
- const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
743
- const { pointType } = point, { flippedX, flippedY } = editBox;
719
+ const { pointType } = point, { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editBox.mergeConfig;
744
720
  let showResize = pointType.includes('resize');
745
721
  if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable))
746
722
  showResize = false;
747
723
  const showSkew = skewable && !showResize && (point.name === 'resize-line' || pointType === 'skew');
748
- const cursor = showSkew ? skewCursor : (showResize ? resizeCursor : rotateCursor);
724
+ const cursor = dragging
725
+ ? (skewing ? skewCursor : (resizing ? resizeCursor : rotateCursor))
726
+ : (showSkew ? skewCursor : (showResize ? resizeCursor : rotateCursor));
749
727
  rotation += (EditDataHelper.getFlipDirection(point.direction, flippedX, flippedY) + 1) * 45;
750
728
  rotation = Math.round(draw.MathHelper.formatRotation(rotation, true) / 2) * 2;
751
729
  const { url, x, y } = cursor;
@@ -757,9 +735,10 @@ this.LeaferIN.editor = (function (exports, draw, core) {
757
735
  cacheCursors[key] = point.cursor = { url: toDataURL(url, rotation), x, y };
758
736
  }
759
737
  }
760
- function updateMoveCursor(editor) {
761
- const { moveCursor, moveable } = editor.mergeConfig;
762
- editor.editBox.rect.cursor = moveable ? moveCursor : undefined;
738
+ function updateMoveCursor(editBox) {
739
+ const { moveCursor, moveable } = editBox.mergeConfig;
740
+ if (editBox.canUse)
741
+ editBox.rect.cursor = moveable ? moveCursor : undefined;
763
742
  }
764
743
  function toDataURL(svg, rotation) {
765
744
  return '"data:image/svg+xml,' + encodeURIComponent(svg.replace('{{rotation}}', rotation.toString())) + '"';
@@ -774,10 +753,26 @@ this.LeaferIN.editor = (function (exports, draw, core) {
774
753
 
775
754
  const fourDirection = ['top', 'right', 'bottom', 'left'], editConfig = undefined;
776
755
  class EditBox extends draw.Group {
756
+ get mergeConfig() {
757
+ const { config } = this, { mergeConfig, editBox } = this.editor;
758
+ return this.mergedConfig = config && (editBox !== this) ? Object.assign(Object.assign({}, mergeConfig), config) : mergeConfig;
759
+ }
760
+ get target() { return this._target || this.editor.element; }
761
+ set target(target) { this._target = target; }
762
+ get single() { return !!this._target || this.editor.single; }
763
+ get transformTool() { return this._transformTool || this.editor; }
764
+ set transformTool(tool) { this._transformTool = tool; }
777
765
  get flipped() { return this.flippedX || this.flippedY; }
778
766
  get flippedX() { return this.scaleX < 0; }
779
767
  get flippedY() { return this.scaleY < 0; }
780
768
  get flippedOne() { return this.scaleX * this.scaleY < 0; }
769
+ get canUse() { return (this.visible && this.view.visible); }
770
+ get canGesture() {
771
+ if (!this.canUse)
772
+ return false;
773
+ const { moveable, resizeable, rotateable } = this.mergeConfig;
774
+ return typeof moveable === 'string' || typeof resizeable === 'string' || typeof rotateable === 'string';
775
+ }
781
776
  constructor(editor) {
782
777
  super();
783
778
  this.view = new draw.Group();
@@ -816,8 +811,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
816
811
  this.add(view);
817
812
  }
818
813
  load() {
819
- const { mergeConfig, element, single } = this.editor;
820
- const { rect, circle, resizePoints } = this;
814
+ const { target, mergeConfig, single, rect, circle, resizePoints } = this;
821
815
  const { stroke, strokeWidth } = mergeConfig;
822
816
  const pointsStyle = this.getPointsStyle();
823
817
  const middlePointsStyle = this.getMiddlePointsStyle();
@@ -825,24 +819,38 @@ this.LeaferIN.editor = (function (exports, draw, core) {
825
819
  for (let i = 0; i < 8; i++) {
826
820
  resizeP = resizePoints[i];
827
821
  resizeP.set(this.getPointStyle((i % 2) ? middlePointsStyle[((i - 1) / 2) % middlePointsStyle.length] : pointsStyle[(i / 2) % pointsStyle.length]));
828
- if (!(i % 2))
829
- resizeP.rotation = (i / 2) * 90;
822
+ resizeP.rotation = ((i - (i % 2 ? 1 : 0)) / 2) * 90;
830
823
  }
831
824
  circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]));
832
825
  rect.set(Object.assign({ stroke, strokeWidth, editConfig }, (mergeConfig.rect || {})));
833
- rect.hittable = !single;
834
- rect.syncEventer = single && this.editor;
835
- if (single) {
836
- element.syncEventer = rect;
837
- this.app.interaction.bottomList = [{ target: rect, proxy: element }];
838
- }
839
- }
840
- update(bounds) {
841
- const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines, editor } = this;
842
- const { mergeConfig, element, multiple, editMask } = editor;
843
- const { middlePoint, resizeable, rotateable, hideOnSmall, editBox, mask } = mergeConfig;
844
- this.visible = !element.locked;
826
+ const syncEventer = single && this.transformTool.editTool;
827
+ rect.hittable = !syncEventer;
828
+ rect.syncEventer = syncEventer && this.editor;
829
+ if (syncEventer) {
830
+ target.syncEventer = rect;
831
+ this.app.interaction.bottomList = [{ target: rect, proxy: target }];
832
+ }
833
+ updateMoveCursor(this);
834
+ }
835
+ update() {
836
+ const { editor } = this;
837
+ const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = this.target.getLayoutBounds('box', editor, true);
838
+ this.set({ x, y, scaleX, scaleY, rotation, skewX, skewY });
839
+ this.updateBounds({ x: 0, y: 0, width, height });
840
+ }
841
+ unload() {
842
+ this.visible = false;
843
+ if (this.app)
844
+ this.rect.syncEventer = this.app.interaction.bottomList = null;
845
+ }
846
+ updateBounds(bounds) {
847
+ const { editMask } = this.editor;
848
+ const { mergeConfig, single, rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this;
849
+ const { middlePoint, resizeable, rotateable, hideOnSmall, editBox, mask, spread } = mergeConfig;
850
+ this.visible = !this.target.locked;
845
851
  editMask.visible = mask ? true : 0;
852
+ if (spread)
853
+ draw.BoundsHelper.spread(bounds, spread);
846
854
  if (this.view.worldOpacity) {
847
855
  const { width, height } = bounds;
848
856
  const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
@@ -867,7 +875,6 @@ this.LeaferIN.editor = (function (exports, draw, core) {
867
875
  }
868
876
  else {
869
877
  resizeL.height = height;
870
- resizeP.rotation = 90;
871
878
  if (hideOnSmall && resizeP.width * 2 > height)
872
879
  resizeP.visible = false;
873
880
  }
@@ -875,25 +882,25 @@ this.LeaferIN.editor = (function (exports, draw, core) {
875
882
  }
876
883
  circle.visible = showPoints && rotateable && !!(mergeConfig.circle || mergeConfig.rotatePoint);
877
884
  if (circle.visible)
878
- this.layoutCircle(mergeConfig);
885
+ this.layoutCircle();
879
886
  if (rect.path)
880
887
  rect.path = null;
881
- rect.set(Object.assign(Object.assign({}, bounds), { visible: multiple ? true : editBox }));
888
+ rect.set(Object.assign(Object.assign({}, bounds), { visible: single ? editBox : true }));
882
889
  buttons.visible = showPoints && buttons.children.length > 0 || 0;
883
890
  if (buttons.visible)
884
- this.layoutButtons(mergeConfig);
891
+ this.layoutButtons();
885
892
  }
886
893
  else
887
894
  rect.set(bounds);
888
895
  }
889
- layoutCircle(config) {
890
- const { circleDirection, circleMargin, buttonsMargin, buttonsDirection, middlePoint } = config;
896
+ layoutCircle() {
897
+ const { circleDirection, circleMargin, buttonsMargin, buttonsDirection, middlePoint } = this.mergedConfig;
891
898
  const direction = fourDirection.indexOf(circleDirection || ((this.buttons.children.length && buttonsDirection === 'bottom') ? 'top' : 'bottom'));
892
899
  this.setButtonPosition(this.circle, direction, circleMargin || buttonsMargin, !!middlePoint);
893
900
  }
894
- layoutButtons(config) {
901
+ layoutButtons() {
895
902
  const { buttons } = this;
896
- const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = config;
903
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.mergedConfig;
897
904
  const { flippedX, flippedY } = this;
898
905
  let index = fourDirection.indexOf(buttonsDirection);
899
906
  if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
@@ -922,49 +929,51 @@ this.LeaferIN.editor = (function (exports, draw, core) {
922
929
  buttons.y = point.y + margin;
923
930
  }
924
931
  }
925
- unload() {
926
- this.visible = false;
927
- }
928
932
  getPointStyle(userStyle) {
929
- const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig;
933
+ const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.mergedConfig;
930
934
  const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius, offsetX: 0, offsetY: 0, editConfig };
931
935
  return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle;
932
936
  }
933
937
  getPointsStyle() {
934
- const { point } = this.editor.mergeConfig;
938
+ const { point } = this.mergedConfig;
935
939
  return point instanceof Array ? point : [point];
936
940
  }
937
941
  getMiddlePointsStyle() {
938
- const { middlePoint } = this.editor.mergeConfig;
942
+ const { middlePoint } = this.mergedConfig;
939
943
  return middlePoint instanceof Array ? middlePoint : (middlePoint ? [middlePoint] : this.getPointsStyle());
940
944
  }
941
- onSelect(e) {
942
- if (e.oldList.length === 1) {
943
- e.oldList[0].syncEventer = null;
944
- if (this.app)
945
- this.app.interaction.bottomList = null;
946
- }
947
- }
948
945
  onDragStart(e) {
949
946
  this.dragging = true;
950
947
  const point = this.dragPoint = e.current, { pointType } = point;
951
- const { editor, dragStartData } = this, { element } = editor;
948
+ const { editor, dragStartData } = this, { target } = this, { moveable, resizeable, rotateable, skewable, hideOnMove } = this.mergeConfig;
952
949
  if (point.name === 'rect') {
953
- this.moving = true;
954
- editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
950
+ moveable && (this.moving = true);
951
+ editor.opacity = hideOnMove ? 0 : 1;
952
+ }
953
+ else {
954
+ if (pointType.includes('rotate') || e.metaKey || e.ctrlKey || !resizeable) {
955
+ rotateable && (this.rotating = true);
956
+ if (pointType === 'resize-rotate')
957
+ resizeable && (this.resizing = true);
958
+ else if (point.name === 'resize-line')
959
+ skewable && (this.skewing = true), this.rotating = false;
960
+ }
961
+ else if (pointType === 'resize')
962
+ resizeable && (this.resizing = true);
963
+ if (pointType === 'skew')
964
+ skewable && (this.skewing = true);
955
965
  }
956
966
  dragStartData.x = e.x;
957
967
  dragStartData.y = e.y;
958
- dragStartData.point = { x: element.x, y: element.y };
959
- dragStartData.bounds = Object.assign({}, element.getLayoutBounds('box', 'local'));
960
- dragStartData.rotation = element.rotation;
968
+ dragStartData.point = { x: target.x, y: target.y };
969
+ dragStartData.bounds = Object.assign({}, target.getLayoutBounds('box', 'local'));
970
+ dragStartData.rotation = target.rotation;
961
971
  if (pointType && pointType.includes('resize'))
962
972
  draw.ResizeEvent.resizingKeys = editor.leafList.keys;
963
973
  }
964
974
  onDragEnd(e) {
965
- this.dragging = false;
966
975
  this.dragPoint = null;
967
- this.moving = false;
976
+ this.resetDoing();
968
977
  const { name, pointType } = e.current;
969
978
  if (name === 'rect')
970
979
  this.editor.opacity = 1;
@@ -972,22 +981,61 @@ this.LeaferIN.editor = (function (exports, draw, core) {
972
981
  draw.ResizeEvent.resizingKeys = null;
973
982
  }
974
983
  onDrag(e) {
975
- const { editor } = this;
976
- const { pointType } = this.enterPoint = e.current;
977
- if (pointType.includes('rotate') || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) {
978
- editor.onRotate(e);
979
- if (pointType === 'resize-rotate')
980
- editor.onScale(e);
981
- }
982
- else if (pointType === 'resize')
983
- editor.onScale(e);
984
- if (pointType === 'skew')
985
- editor.onSkew(e);
986
- updateCursor(editor, e);
984
+ const { transformTool, moving, resizing, rotating, skewing } = this;
985
+ if (moving) {
986
+ transformTool.onMove(e);
987
+ updateMoveCursor(this);
988
+ }
989
+ else if (resizing || rotating || skewing) {
990
+ const point = e.current;
991
+ if (point.pointType)
992
+ this.enterPoint = point;
993
+ if (rotating)
994
+ transformTool.onRotate(e);
995
+ if (resizing)
996
+ transformTool.onScale(e);
997
+ if (skewing)
998
+ transformTool.onSkew(e);
999
+ updatePointCursor(this, e);
1000
+ }
1001
+ }
1002
+ resetDoing() {
1003
+ if (this.canUse)
1004
+ this.dragging = this.gesturing = this.moving = this.resizing = this.rotating = this.skewing = false;
1005
+ }
1006
+ onMove(e) {
1007
+ if (this.canGesture && e.moveType !== 'drag') {
1008
+ e.stop();
1009
+ if (typeof this.mergeConfig.moveable === 'string') {
1010
+ this.gesturing = this.moving = true;
1011
+ this.transformTool.onMove(e);
1012
+ }
1013
+ }
1014
+ }
1015
+ onScale(e) {
1016
+ if (this.canGesture) {
1017
+ e.stop();
1018
+ if (typeof this.mergeConfig.resizeable === 'string') {
1019
+ this.gesturing = this.resizing = true;
1020
+ this.transformTool.onScale(e);
1021
+ }
1022
+ }
1023
+ }
1024
+ onRotate(e) {
1025
+ if (this.canGesture) {
1026
+ e.stop();
1027
+ if (typeof this.mergeConfig.rotateable === 'string') {
1028
+ this.gesturing = this.rotating = true;
1029
+ this.transformTool.onRotate(e);
1030
+ }
1031
+ }
1032
+ }
1033
+ onKey(e) {
1034
+ updatePointCursor(this, e);
987
1035
  }
988
1036
  onArrow(e) {
989
- const { editor } = this;
990
- if (editor.editing && editor.mergeConfig.keyEvent) {
1037
+ const { editor, transformTool } = this;
1038
+ if (this.canUse && editor.editing && this.mergeConfig.keyEvent) {
991
1039
  let x = 0, y = 0;
992
1040
  const distance = e.shiftKey ? 10 : 1;
993
1041
  switch (e.code) {
@@ -1004,31 +1052,32 @@ this.LeaferIN.editor = (function (exports, draw, core) {
1004
1052
  x = distance;
1005
1053
  }
1006
1054
  if (x || y)
1007
- editor.move(x, y);
1055
+ transformTool.move(x, y);
1008
1056
  }
1009
1057
  }
1010
1058
  onDoubleTap(e) {
1011
- if (this.editor.mergeConfig.openInner === 'double')
1059
+ const { openInner, preventEditInner } = this.mergeConfig;
1060
+ if (openInner === 'double' && !preventEditInner)
1012
1061
  this.openInner(e);
1013
1062
  }
1014
1063
  onLongPress(e) {
1015
- if (this.editor.mergeConfig.openInner === 'long')
1064
+ const { openInner, preventEditInner } = this.mergeConfig;
1065
+ if (openInner === 'long' && preventEditInner)
1016
1066
  this.openInner(e);
1017
1067
  }
1018
1068
  openInner(e) {
1019
- const { editor } = this;
1020
- if (editor.single) {
1021
- const { element } = editor;
1022
- if (element.locked)
1069
+ const { editor, target } = this;
1070
+ if (this.single) {
1071
+ if (target.locked)
1023
1072
  return;
1024
- if (element.isBranch && !element.editInner) {
1025
- if (element.textBox) {
1026
- const { children } = element;
1073
+ if (target.isBranch && !target.editInner) {
1074
+ if (target.textBox) {
1075
+ const { children } = target;
1027
1076
  const find = children.find(item => item.editable && item instanceof draw.Text) || children.find(item => item instanceof draw.Text);
1028
1077
  if (find)
1029
1078
  return editor.openInnerEditor(find);
1030
1079
  }
1031
- editor.openGroup(element);
1080
+ editor.openGroup(target);
1032
1081
  editor.target = editor.selector.findDeepOne(e);
1033
1082
  }
1034
1083
  else {
@@ -1037,7 +1086,6 @@ this.LeaferIN.editor = (function (exports, draw, core) {
1037
1086
  }
1038
1087
  }
1039
1088
  listenPointEvents(point, type, direction) {
1040
- const { editor } = this;
1041
1089
  point.direction = direction;
1042
1090
  point.pointType = type;
1043
1091
  const events = [
@@ -1047,19 +1095,31 @@ this.LeaferIN.editor = (function (exports, draw, core) {
1047
1095
  [core.PointerEvent.LEAVE, () => { this.enterPoint = null; }],
1048
1096
  ];
1049
1097
  if (point.name !== 'circle')
1050
- events.push([core.PointerEvent.ENTER, (e) => { this.enterPoint = point, updateCursor(editor, e); }]);
1098
+ events.push([core.PointerEvent.ENTER, (e) => { this.enterPoint = point, updatePointCursor(this, e); }]);
1051
1099
  this.__eventIds.push(point.on_(events));
1052
1100
  }
1053
1101
  __listenEvents() {
1054
- const { rect, editor } = this;
1055
- this.__eventIds.push(editor.on_(EditorEvent.SELECT, this.onSelect, this), rect.on_([
1102
+ const { rect, editor, __eventIds: events } = this;
1103
+ events.push(rect.on_([
1056
1104
  [core.DragEvent.START, this.onDragStart, this],
1057
- [core.DragEvent.DRAG, editor.onMove, editor],
1105
+ [core.DragEvent.DRAG, this.onDrag, this],
1058
1106
  [core.DragEvent.END, this.onDragEnd, this],
1059
- [core.PointerEvent.ENTER, () => updateMoveCursor(editor)],
1107
+ [core.PointerEvent.ENTER, () => updateMoveCursor(this)],
1060
1108
  [core.PointerEvent.DOUBLE_TAP, this.onDoubleTap, this],
1061
1109
  [core.PointerEvent.LONG_PRESS, this.onLongPress, this]
1062
1110
  ]));
1111
+ this.waitLeafer(() => {
1112
+ events.push(editor.app.on_([
1113
+ [[core.KeyEvent.HOLD, core.KeyEvent.UP], this.onKey, this],
1114
+ [core.KeyEvent.DOWN, this.onArrow, this],
1115
+ [core.MoveEvent.BEFORE_MOVE, this.onMove, this, true],
1116
+ [core.ZoomEvent.BEFORE_ZOOM, this.onScale, this, true],
1117
+ [core.RotateEvent.BEFORE_ROTATE, this.onRotate, this, true],
1118
+ [core.MoveEvent.END, this.resetDoing, this],
1119
+ [core.ZoomEvent.END, this.resetDoing, this],
1120
+ [core.RotateEvent.END, this.resetDoing, this],
1121
+ ]));
1122
+ });
1063
1123
  }
1064
1124
  __removeListenEvents() {
1065
1125
  this.off_(this.__eventIds);
@@ -1090,11 +1150,12 @@ this.LeaferIN.editor = (function (exports, draw, core) {
1090
1150
  if (options.bounds && !options.bounds.hit(editor.editBox.rect.__world, options.matrix))
1091
1151
  return;
1092
1152
  canvas.saveBlendMode('destination-out');
1153
+ options = Object.assign(Object.assign({}, options), { shape: true });
1093
1154
  editor.list.forEach(item => {
1094
- item.__renderShape(canvas, options);
1095
- const { __box, parent } = item;
1096
- if ((item = __box) || ((item = parent) && parent.textBox))
1097
- item.__renderShape(canvas, options);
1155
+ item.__render(canvas, options);
1156
+ const { parent } = item;
1157
+ if (parent && parent.textBox)
1158
+ parent.__renderShape(canvas, options);
1098
1159
  });
1099
1160
  canvas.restoreBlendMode();
1100
1161
  }
@@ -1189,7 +1250,7 @@ ${filterStyle}
1189
1250
  const bounds = new draw.Bounds();
1190
1251
  function simulate(editor) {
1191
1252
  const { simulateTarget, list } = editor;
1192
- const { zoomLayer } = list[0].leafer.zoomLayer;
1253
+ const { zoomLayer } = list[0].leafer;
1193
1254
  simulateTarget.safeChange(() => {
1194
1255
  bounds.setListWithFn(list, (leaf) => leaf.getBounds('box', 'page'));
1195
1256
  if (bounds.width === 0)
@@ -1211,15 +1272,15 @@ ${filterStyle}
1211
1272
  else {
1212
1273
  editor.simulateTarget.remove();
1213
1274
  editor.leafList.reset();
1214
- editor.closeInnerEditor();
1215
1275
  }
1216
- editor.emitEvent(new EditorEvent(EditorEvent.SELECT, { editor, value: target, oldValue }));
1276
+ editor.closeInnerEditor(true);
1277
+ editor.unloadEditTool();
1278
+ const data = { editor, value: target, oldValue };
1279
+ editor.emitEvent(new EditorEvent(EditorEvent.SELECT, data));
1217
1280
  editor.checkOpenedGroups();
1218
1281
  if (editor.editing) {
1219
1282
  editor.waitLeafer(() => {
1220
- updateMoveCursor(editor);
1221
1283
  editor.updateEditTool();
1222
- editor.update();
1223
1284
  editor.listenTargetEvents();
1224
1285
  });
1225
1286
  }
@@ -1227,6 +1288,7 @@ ${filterStyle}
1227
1288
  editor.updateEditTool();
1228
1289
  editor.removeTargetEvents();
1229
1290
  }
1291
+ editor.emitEvent(new EditorEvent(EditorEvent.AFTER_SELECT, data));
1230
1292
  }
1231
1293
  function onHover(editor, oldValue) {
1232
1294
  editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }));
@@ -1398,98 +1460,44 @@ ${filterStyle}
1398
1460
  }
1399
1461
  }
1400
1462
 
1401
- class Editor extends draw.Group {
1402
- get list() { return this.leafList.list; }
1403
- get dragHoverExclude() { return [this.editBox.rect]; }
1404
- get editing() { return !!this.list.length; }
1405
- get groupOpening() { return !!this.openedGroupList.length; }
1406
- get multiple() { return this.list.length > 1; }
1407
- get single() { return this.list.length === 1; }
1408
- get dragging() { return this.editBox.dragging; }
1409
- get moving() { return this.editBox.moving; }
1410
- get dragPoint() { return this.editBox.dragPoint; }
1411
- get element() { return this.multiple ? this.simulateTarget : this.list[0]; }
1412
- get buttons() { return this.editBox.buttons; }
1413
- constructor(userConfig, data) {
1414
- super(data);
1415
- this.leafList = new draw.LeafList();
1416
- this.openedGroupList = new draw.LeafList();
1417
- this.simulateTarget = new SimulateElement(this);
1418
- this.editBox = new EditBox(this);
1419
- this.editToolList = {};
1420
- this.selector = new EditSelect(this);
1421
- this.editMask = new EditMask(this);
1422
- this.targetEventIds = [];
1423
- let mergedConfig = draw.DataHelper.clone(config);
1424
- if (userConfig)
1425
- mergedConfig = draw.DataHelper.default(userConfig, mergedConfig);
1426
- this.mergedConfig = this.config = mergedConfig;
1427
- this.addMany(this.editMask, this.selector, this.editBox);
1428
- if (!draw.Plugin.has('resize'))
1429
- this.config.editSize = 'scale';
1430
- }
1431
- select(target) {
1432
- this.target = target;
1433
- }
1434
- cancel() {
1435
- this.target = null;
1436
- }
1437
- hasItem(item) {
1438
- return this.leafList.has(item);
1439
- }
1440
- addItem(item) {
1441
- if (!this.hasItem(item) && !item.locked)
1442
- this.leafList.add(item), this.target = this.leafList.list;
1443
- }
1444
- removeItem(item) {
1445
- if (this.hasItem(item))
1446
- this.leafList.remove(item), this.target = this.leafList.list;
1447
- }
1448
- shiftItem(item) {
1449
- this.hasItem(item) ? this.removeItem(item) : this.addItem(item);
1450
- }
1451
- update() {
1452
- if (this.editing) {
1453
- if (!this.element.parent)
1454
- return this.cancel();
1455
- if (this.innerEditing)
1456
- this.innerEditor.update();
1457
- this.editTool.update();
1458
- this.selector.update();
1459
- }
1463
+ class EditorMoveEvent extends EditorEvent {
1464
+ constructor(type, data) {
1465
+ super(type, data);
1460
1466
  }
1461
- updateEditBox() {
1462
- if (this.multiple)
1463
- simulate(this);
1464
- this.update();
1467
+ }
1468
+ EditorMoveEvent.BEFORE_MOVE = 'editor.before_move';
1469
+ EditorMoveEvent.MOVE = 'editor.move';
1470
+
1471
+ class EditorScaleEvent extends EditorEvent {
1472
+ constructor(type, data) {
1473
+ super(type, data);
1465
1474
  }
1466
- updateEditTool() {
1467
- const tool = this.editTool;
1468
- if (tool) {
1469
- this.editBox.unload();
1470
- tool.unload();
1471
- this.editTool = null;
1472
- }
1473
- if (this.editing) {
1474
- const tag = this.single ? this.list[0].editOuter : 'EditTool';
1475
- this.editTool = this.editToolList[tag] = this.editToolList[tag] || EditToolCreator.get(tag, this);
1476
- this.editBox.load();
1477
- this.editTool.load();
1478
- }
1475
+ }
1476
+ EditorScaleEvent.BEFORE_SCALE = 'editor.before_scale';
1477
+ EditorScaleEvent.SCALE = 'editor.scale';
1478
+
1479
+ class EditorRotateEvent extends EditorEvent {
1480
+ constructor(type, data) {
1481
+ super(type, data);
1479
1482
  }
1480
- getEditSize(_ui) {
1481
- return this.mergeConfig.editSize;
1483
+ }
1484
+ EditorRotateEvent.BEFORE_ROTATE = 'editor.before_rotate';
1485
+ EditorRotateEvent.ROTATE = 'editor.rotate';
1486
+
1487
+ class EditorSkewEvent extends EditorEvent {
1488
+ constructor(type, data) {
1489
+ super(type, data);
1482
1490
  }
1491
+ }
1492
+ EditorSkewEvent.BEFORE_SKEW = 'editor.before_skew';
1493
+ EditorSkewEvent.SKEW = 'editor.skew';
1494
+
1495
+ class TransformTool {
1483
1496
  onMove(e) {
1497
+ const { target, dragStartData } = this.editBox;
1484
1498
  if (e instanceof core.MoveEvent) {
1485
- if (e.moveType !== 'drag') {
1486
- const { moveable, resizeable } = this.mergeConfig;
1487
- const move = e.getLocalMove(this.element);
1488
- if (moveable === 'move')
1489
- e.stop(), this.move(move.x, move.y);
1490
- else if (resizeable === 'zoom')
1491
- e.stop();
1492
- }
1499
+ const move = e.getLocalMove(target);
1500
+ this.move(move.x, move.y);
1493
1501
  }
1494
1502
  else {
1495
1503
  const total = { x: e.totalX, y: e.totalY };
@@ -1499,22 +1507,21 @@ ${filterStyle}
1499
1507
  else
1500
1508
  total.x = 0;
1501
1509
  }
1502
- this.move(core.DragEvent.getValidMove(this.element, this.editBox.dragStartData.point, total));
1510
+ this.move(core.DragEvent.getValidMove(target, dragStartData.point, total));
1503
1511
  }
1504
1512
  }
1505
1513
  onScale(e) {
1506
- const { element } = this;
1507
- let { around, lockRatio, resizeable, flipable, editSize } = this.mergeConfig;
1514
+ const { target, mergeConfig, single, dragStartData } = this.editBox;
1515
+ let { around, lockRatio, flipable, editSize } = mergeConfig;
1508
1516
  if (e instanceof core.ZoomEvent) {
1509
- if (resizeable === 'zoom')
1510
- e.stop(), this.scaleOf(element.getBoxPoint(e), e.scale, e.scale);
1517
+ this.scaleOf(target.getBoxPoint(e), e.scale, e.scale);
1511
1518
  }
1512
1519
  else {
1513
1520
  const { direction } = e.current;
1514
- if (e.shiftKey || element.lockRatio)
1521
+ if (e.shiftKey || target.lockRatio)
1515
1522
  lockRatio = true;
1516
- const data = EditDataHelper.getScaleData(element, this.editBox.dragStartData.bounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
1517
- if (this.editTool.onScaleWithDrag) {
1523
+ const data = EditDataHelper.getScaleData(target, dragStartData.bounds, direction, e.getInnerTotal(target), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, !single || editSize === 'scale');
1524
+ if (this.editTool && this.editTool.onScaleWithDrag) {
1518
1525
  data.drag = e;
1519
1526
  this.scaleWithDrag(data);
1520
1527
  }
@@ -1524,38 +1531,28 @@ ${filterStyle}
1524
1531
  }
1525
1532
  }
1526
1533
  onRotate(e) {
1527
- const { skewable, rotateable, around, rotateGap } = this.mergeConfig;
1528
- const { direction, name } = e.current;
1529
- if (skewable && name === 'resize-line')
1530
- return this.onSkew(e);
1531
- const { element } = this, { dragStartData } = this.editBox;
1534
+ const { target, mergeConfig, dragStartData } = this.editBox;
1535
+ const { around, rotateAround, rotateGap } = mergeConfig;
1536
+ const { direction } = e.current;
1532
1537
  let origin, rotation;
1533
1538
  if (e instanceof core.RotateEvent) {
1534
- if (rotateable === 'rotate')
1535
- e.stop(), rotation = e.rotation, origin = element.getBoxPoint(e);
1536
- else
1537
- return;
1538
- if (element.scaleX * element.scaleY < 0)
1539
- rotation = -rotation;
1539
+ rotation = e.rotation;
1540
+ origin = rotateAround ? draw.AroundHelper.getPoint(rotateAround, target.boxBounds) : target.getBoxPoint(e);
1540
1541
  }
1541
1542
  else {
1542
- const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getBoxPoint(element), element.getBoxPoint(dragStartData), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
1543
- rotation = data.rotation;
1543
+ const data = EditDataHelper.getRotateData(target, direction, e, dragStartData, e.shiftKey ? null : (rotateAround || target.around || target.origin || around || 'center'));
1544
+ rotation = dragStartData.rotation + data.rotation - target.rotation;
1544
1545
  origin = data.origin;
1545
1546
  }
1546
- if (element.scaleX * element.scaleY < 0)
1547
- rotation = -rotation;
1548
- if (e instanceof core.DragEvent)
1549
- rotation = dragStartData.rotation + rotation - element.rotation;
1550
- rotation = draw.MathHelper.float(draw.MathHelper.getGapRotation(rotation, rotateGap, element.rotation), 2);
1547
+ rotation = draw.MathHelper.float(draw.MathHelper.getGapRotation(rotation, rotateGap, target.rotation), 2);
1551
1548
  if (!rotation)
1552
1549
  return;
1553
1550
  this.rotateOf(origin, rotation);
1554
1551
  }
1555
1552
  onSkew(e) {
1556
- const { element } = this;
1557
- const { around } = this.mergeConfig;
1558
- const { origin, skewX, skewY } = EditDataHelper.getSkewData(element.boxBounds, e.current.direction, e.getInnerMove(element), EditDataHelper.getAround(around, e.altKey));
1553
+ const { target, mergeConfig } = this.editBox;
1554
+ const { around } = mergeConfig;
1555
+ const { origin, skewX, skewY } = EditDataHelper.getSkewData(target.boxBounds, e.current.direction, e.getInnerMove(target), EditDataHelper.getAround(around, e.altKey));
1559
1556
  if (!skewX && !skewY)
1560
1557
  return;
1561
1558
  this.skewOf(origin, skewX, skewY);
@@ -1565,7 +1562,8 @@ ${filterStyle}
1565
1562
  return;
1566
1563
  if (typeof x === 'object')
1567
1564
  y = x.y, x = x.x;
1568
- const { element: target } = this, { beforeMove } = this.mergeConfig;
1565
+ const { target, mergeConfig, single, editor } = this.editBox;
1566
+ const { beforeMove } = mergeConfig;
1569
1567
  if (beforeMove) {
1570
1568
  const check = beforeMove({ target, x, y });
1571
1569
  if (typeof check === 'object')
@@ -1574,25 +1572,26 @@ ${filterStyle}
1574
1572
  return;
1575
1573
  }
1576
1574
  const world = target.getWorldPointByLocal({ x, y }, null, true);
1577
- if (this.multiple)
1575
+ if (!single)
1578
1576
  target.safeChange(() => target.move(x, y));
1579
- const data = { target, editor: this, moveX: world.x, moveY: world.y };
1577
+ const data = { target, editor, moveX: world.x, moveY: world.y };
1580
1578
  this.emitEvent(new EditorMoveEvent(EditorMoveEvent.BEFORE_MOVE, data));
1581
1579
  const event = new EditorMoveEvent(EditorMoveEvent.MOVE, data);
1582
- this.editTool.onMove(event);
1580
+ this.doMove(event);
1583
1581
  this.emitEvent(event);
1584
1582
  }
1585
1583
  scaleWithDrag(data) {
1586
1584
  if (!this.checkTransform('resizeable'))
1587
1585
  return;
1588
- const { element: target } = this, { beforeScale } = this.mergeConfig;
1586
+ const { target, mergeConfig, editor } = this.editBox;
1587
+ const { beforeScale } = mergeConfig;
1589
1588
  if (beforeScale) {
1590
1589
  const { origin, scaleX, scaleY, drag } = data;
1591
1590
  const check = beforeScale({ target, drag, origin, scaleX, scaleY });
1592
1591
  if (check === false)
1593
1592
  return;
1594
1593
  }
1595
- data = Object.assign(Object.assign({}, data), { target, editor: this, worldOrigin: target.getWorldPoint(data.origin) });
1594
+ data = Object.assign(Object.assign({}, data), { target, editor, worldOrigin: target.getWorldPoint(data.origin) });
1596
1595
  this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data));
1597
1596
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data);
1598
1597
  this.editTool.onScaleWithDrag(event);
@@ -1601,7 +1600,8 @@ ${filterStyle}
1601
1600
  scaleOf(origin, scaleX, scaleY = scaleX, _resize) {
1602
1601
  if (!this.checkTransform('resizeable'))
1603
1602
  return;
1604
- const { element: target } = this, { beforeScale } = this.mergeConfig;
1603
+ const { target, mergeConfig, single, editor } = this.editBox;
1604
+ const { beforeScale } = mergeConfig;
1605
1605
  if (beforeScale) {
1606
1606
  const check = beforeScale({ target, origin, scaleX, scaleY });
1607
1607
  if (typeof check === 'object')
@@ -1610,29 +1610,30 @@ ${filterStyle}
1610
1610
  return;
1611
1611
  }
1612
1612
  const worldOrigin = this.getWorldOrigin(origin);
1613
- const transform = this.multiple && this.getChangedTransform(() => target.safeChange(() => target.scaleOf(origin, scaleX, scaleY)));
1614
- const data = { target, editor: this, worldOrigin, scaleX, scaleY, transform };
1613
+ const transform = !single && this.getChangedTransform(() => target.safeChange(() => target.scaleOf(origin, scaleX, scaleY)));
1614
+ const data = { target, editor, worldOrigin, scaleX, scaleY, transform };
1615
1615
  this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data));
1616
1616
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data);
1617
- this.editTool.onScale(event);
1617
+ this.doScale(event);
1618
1618
  this.emitEvent(event);
1619
1619
  }
1620
1620
  flip(axis) {
1621
1621
  if (!this.checkTransform('resizeable'))
1622
1622
  return;
1623
- const { element } = this;
1623
+ const { target, single, editor } = this.editBox;
1624
1624
  const worldOrigin = this.getWorldOrigin('center');
1625
- const transform = this.multiple ? this.getChangedTransform(() => element.safeChange(() => element.flip(axis))) : new draw.Matrix(draw.LeafHelper.getFlipTransform(element, axis));
1626
- const data = { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform };
1625
+ const transform = !single ? this.getChangedTransform(() => target.safeChange(() => target.flip(axis))) : new draw.Matrix(draw.LeafHelper.getFlipTransform(target, axis));
1626
+ const data = { target, editor, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform };
1627
1627
  this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data));
1628
1628
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data);
1629
- this.editTool.onScale(event);
1629
+ this.doScale(event);
1630
1630
  this.emitEvent(event);
1631
1631
  }
1632
1632
  rotateOf(origin, rotation) {
1633
1633
  if (!this.checkTransform('rotateable'))
1634
1634
  return;
1635
- const { element: target } = this, { beforeRotate } = this.mergeConfig;
1635
+ const { target, mergeConfig, single, editor } = this.editBox;
1636
+ const { beforeRotate } = mergeConfig;
1636
1637
  if (beforeRotate) {
1637
1638
  const check = beforeRotate({ target, origin, rotation });
1638
1639
  if (typeof check === 'number')
@@ -1641,17 +1642,18 @@ ${filterStyle}
1641
1642
  return;
1642
1643
  }
1643
1644
  const worldOrigin = this.getWorldOrigin(origin);
1644
- const transform = this.multiple && this.getChangedTransform(() => target.safeChange(() => target.rotateOf(origin, rotation)));
1645
- const data = { target, editor: this, worldOrigin, rotation, transform };
1645
+ const transform = !single && this.getChangedTransform(() => target.safeChange(() => target.rotateOf(origin, rotation)));
1646
+ const data = { target, editor, worldOrigin, rotation, transform };
1646
1647
  this.emitEvent(new EditorRotateEvent(EditorRotateEvent.BEFORE_ROTATE, data));
1647
1648
  const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, data);
1648
- this.editTool.onRotate(event);
1649
+ this.doRotate(event);
1649
1650
  this.emitEvent(event);
1650
1651
  }
1651
1652
  skewOf(origin, skewX, skewY = 0, _resize) {
1652
1653
  if (!this.checkTransform('skewable'))
1653
1654
  return;
1654
- const { element: target } = this, { beforeSkew } = this.mergeConfig;
1655
+ const { target, mergeConfig, single, editor } = this.editBox;
1656
+ const { beforeSkew } = mergeConfig;
1655
1657
  if (beforeSkew) {
1656
1658
  const check = beforeSkew({ target, origin, skewX, skewY });
1657
1659
  if (typeof check === 'object')
@@ -1660,25 +1662,149 @@ ${filterStyle}
1660
1662
  return;
1661
1663
  }
1662
1664
  const worldOrigin = this.getWorldOrigin(origin);
1663
- const transform = this.multiple && this.getChangedTransform(() => target.safeChange(() => target.skewOf(origin, skewX, skewY)));
1664
- const data = { target, editor: this, worldOrigin, skewX, skewY, transform };
1665
+ const transform = !single && this.getChangedTransform(() => target.safeChange(() => target.skewOf(origin, skewX, skewY)));
1666
+ const data = { target, editor, worldOrigin, skewX, skewY, transform };
1665
1667
  this.emitEvent(new EditorSkewEvent(EditorSkewEvent.BEFORE_SKEW, data));
1666
1668
  const event = new EditorSkewEvent(EditorSkewEvent.SKEW, data);
1667
- this.editTool.onSkew(event);
1669
+ this.doSkew(event);
1668
1670
  this.emitEvent(event);
1669
1671
  }
1670
- checkTransform(type) { return this.element && !this.element.locked && this.mergeConfig[type]; }
1672
+ doMove(event) {
1673
+ this.editTool.onMove(event);
1674
+ }
1675
+ doScale(event) {
1676
+ this.editTool.onScale(event);
1677
+ }
1678
+ doRotate(event) {
1679
+ this.editTool.onRotate(event);
1680
+ }
1681
+ doSkew(event) {
1682
+ this.editTool.onSkew(event);
1683
+ }
1684
+ checkTransform(type) {
1685
+ const { target, mergeConfig } = this.editBox;
1686
+ return target && !target.locked && mergeConfig[type];
1687
+ }
1671
1688
  getWorldOrigin(origin) {
1672
- return this.element.getWorldPoint(draw.LeafHelper.getInnerOrigin(this.element, origin));
1689
+ const { target } = this.editBox;
1690
+ return target.getWorldPoint(draw.LeafHelper.getInnerOrigin(target, origin));
1673
1691
  }
1674
1692
  getChangedTransform(func) {
1675
- const { element } = this;
1676
- if (this.multiple && !element.canChange)
1677
- return element.changedTransform;
1678
- const oldMatrix = new draw.Matrix(element.worldTransform);
1693
+ const { target, single } = this.editBox;
1694
+ if (!single && !target.canChange)
1695
+ return target.changedTransform;
1696
+ const oldMatrix = new draw.Matrix(target.worldTransform);
1679
1697
  func();
1680
- return new draw.Matrix(element.worldTransform).divide(oldMatrix);
1698
+ return new draw.Matrix(target.worldTransform).divide(oldMatrix);
1699
+ }
1700
+ emitEvent(event, capture) {
1701
+ this.editBox.editor.emitEvent(event, capture);
1702
+ }
1703
+ }
1704
+
1705
+ exports.Editor = class Editor extends draw.Group {
1706
+ get list() { return this.leafList.list; }
1707
+ get dragHoverExclude() { return [this.editBox.rect]; }
1708
+ get editing() { return !!this.list.length; }
1709
+ get groupOpening() { return !!this.openedGroupList.length; }
1710
+ get multiple() { return this.list.length > 1; }
1711
+ get single() { return this.list.length === 1; }
1712
+ get dragPoint() { return this.editBox.dragPoint; }
1713
+ get dragging() { return this.editBox.dragging; }
1714
+ get gesturing() { return this.editBox.gesturing; }
1715
+ get moving() { return this.editBox.moving; }
1716
+ get resizing() { return this.editBox.resizing; }
1717
+ get rotating() { return this.editBox.rotating; }
1718
+ get skewing() { return this.editBox.skewing; }
1719
+ get element() { return this.multiple ? this.simulateTarget : this.list[0]; }
1720
+ get buttons() { return this.editBox.buttons; }
1721
+ constructor(userConfig, data) {
1722
+ super(data);
1723
+ this.leafList = new draw.LeafList();
1724
+ this.openedGroupList = new draw.LeafList();
1725
+ this.simulateTarget = new SimulateElement(this);
1726
+ this.editBox = new EditBox(this);
1727
+ this.editToolList = {};
1728
+ this.selector = new EditSelect(this);
1729
+ this.editMask = new EditMask(this);
1730
+ this.targetEventIds = [];
1731
+ let mergedConfig = draw.DataHelper.clone(config);
1732
+ if (userConfig)
1733
+ mergedConfig = draw.DataHelper.default(userConfig, mergedConfig);
1734
+ this.mergedConfig = this.config = mergedConfig;
1735
+ this.addMany(this.editMask, this.selector, this.editBox);
1736
+ if (!draw.Plugin.has('resize'))
1737
+ this.config.editSize = 'scale';
1738
+ }
1739
+ select(target) {
1740
+ this.target = target;
1741
+ }
1742
+ cancel() {
1743
+ this.target = null;
1744
+ }
1745
+ hasItem(item) {
1746
+ return this.leafList.has(item);
1747
+ }
1748
+ addItem(item) {
1749
+ if (!this.hasItem(item) && !item.locked)
1750
+ this.leafList.add(item), this.target = this.leafList.list;
1751
+ }
1752
+ removeItem(item) {
1753
+ if (this.hasItem(item))
1754
+ this.leafList.remove(item), this.target = this.leafList.list;
1755
+ }
1756
+ shiftItem(item) {
1757
+ this.hasItem(item) ? this.removeItem(item) : this.addItem(item);
1758
+ }
1759
+ update() {
1760
+ if (this.editing) {
1761
+ if (!this.element.parent)
1762
+ return this.cancel();
1763
+ if (this.innerEditing)
1764
+ this.innerEditor.update();
1765
+ this.editTool.update();
1766
+ this.selector.update();
1767
+ }
1681
1768
  }
1769
+ updateEditBox() {
1770
+ if (this.multiple)
1771
+ simulate(this);
1772
+ this.update();
1773
+ }
1774
+ updateEditTool() {
1775
+ this.unloadEditTool();
1776
+ if (this.editing) {
1777
+ const name = this.element.editOuter || 'EditTool';
1778
+ const tool = this.editTool = this.editToolList[name] = this.editToolList[name] || EditToolCreator.get(name, this);
1779
+ this.editBox.load();
1780
+ tool.load();
1781
+ this.update();
1782
+ }
1783
+ }
1784
+ unloadEditTool() {
1785
+ let tool = this.editTool;
1786
+ if (tool) {
1787
+ this.editBox.unload();
1788
+ tool.unload();
1789
+ this.editTool = null;
1790
+ }
1791
+ }
1792
+ getEditSize(_ui) {
1793
+ return this.mergeConfig.editSize;
1794
+ }
1795
+ onMove(_e) { }
1796
+ onScale(_e) { }
1797
+ onRotate(_e) { }
1798
+ onSkew(_e) { }
1799
+ move(_x, _y = 0) { }
1800
+ scaleWithDrag(_data) { }
1801
+ scaleOf(_origin, scaleX, _scaleY = scaleX, _resize) { }
1802
+ flip(_axis) { }
1803
+ rotateOf(_origin, _rotation) { }
1804
+ skewOf(_origin, _skewX, _skewY = 0, _resize) { }
1805
+ checkTransform(_type) { return undefined; }
1806
+ getWorldOrigin(_origin) { return undefined; }
1807
+ getChangedTransform(_func) { return undefined; }
1682
1808
  group(userGroup) {
1683
1809
  if (this.multiple) {
1684
1810
  this.emitGroupEvent(EditorGroupEvent.BEFORE_GROUP);
@@ -1735,16 +1861,21 @@ ${filterStyle}
1735
1861
  if (group)
1736
1862
  group.emitEvent(event);
1737
1863
  }
1738
- openInnerEditor(target, select) {
1864
+ openInnerEditor(target, nameOrSelect, select) {
1865
+ let name;
1866
+ if (typeof nameOrSelect === 'string')
1867
+ name = nameOrSelect;
1868
+ else if (!select)
1869
+ select = nameOrSelect;
1739
1870
  if (target && select)
1740
1871
  this.target = target;
1741
1872
  if (this.single) {
1742
1873
  const editTarget = target || this.element;
1743
- const tag = editTarget.editInner;
1744
- if (tag && EditToolCreator.list[tag]) {
1874
+ name || (name = editTarget.editInner);
1875
+ if (name && EditToolCreator.list[name]) {
1745
1876
  this.editTool.unload();
1746
1877
  this.innerEditing = true;
1747
- this.innerEditor = this.editToolList[tag] || EditToolCreator.get(tag, this);
1878
+ this.innerEditor = this.editToolList[name] = this.editToolList[name] || EditToolCreator.get(name, this);
1748
1879
  this.innerEditor.editTarget = editTarget;
1749
1880
  this.emitInnerEvent(InnerEditorEvent.BEFORE_OPEN);
1750
1881
  this.innerEditor.load();
@@ -1752,13 +1883,14 @@ ${filterStyle}
1752
1883
  }
1753
1884
  }
1754
1885
  }
1755
- closeInnerEditor() {
1886
+ closeInnerEditor(onlyInnerEditor) {
1756
1887
  if (this.innerEditing) {
1757
1888
  this.innerEditing = false;
1758
1889
  this.emitInnerEvent(InnerEditorEvent.BEFORE_CLOSE);
1759
1890
  this.innerEditor.unload();
1760
1891
  this.emitInnerEvent(InnerEditorEvent.CLOSE);
1761
- this.editTool.load();
1892
+ if (!onlyInnerEditor)
1893
+ this.updateEditTool();
1762
1894
  this.innerEditor = null;
1763
1895
  }
1764
1896
  }
@@ -1796,22 +1928,12 @@ ${filterStyle}
1796
1928
  if (this.targetChanged)
1797
1929
  this.update();
1798
1930
  }
1799
- onKey(e) {
1800
- updateCursor(this, e);
1801
- }
1802
1931
  listenTargetEvents() {
1803
1932
  if (!this.targetEventIds.length) {
1804
- const { app, leafer, editBox, editMask } = this;
1933
+ const { app, leafer, editMask } = this;
1805
1934
  this.targetEventIds = [
1806
1935
  leafer.on_(draw.RenderEvent.START, this.onRenderStart, this),
1807
- app.on_([
1808
- [draw.RenderEvent.CHILD_START, this.onAppRenderStart, this],
1809
- [core.MoveEvent.BEFORE_MOVE, this.onMove, this, true],
1810
- [core.ZoomEvent.BEFORE_ZOOM, this.onScale, this, true],
1811
- [core.RotateEvent.BEFORE_ROTATE, this.onRotate, this, true],
1812
- [[core.KeyEvent.HOLD, core.KeyEvent.UP], this.onKey, this],
1813
- [core.KeyEvent.DOWN, editBox.onArrow, editBox]
1814
- ])
1936
+ app.on_(draw.RenderEvent.CHILD_START, this.onAppRenderStart, this)
1815
1937
  ];
1816
1938
  if (editMask.visible)
1817
1939
  editMask.forceRender();
@@ -1835,24 +1957,29 @@ ${filterStyle}
1835
1957
  super.destroy();
1836
1958
  }
1837
1959
  }
1838
- }
1960
+ };
1839
1961
  __decorate([
1840
1962
  mergeConfigAttr()
1841
- ], Editor.prototype, "mergeConfig", void 0);
1963
+ ], exports.Editor.prototype, "mergeConfig", void 0);
1842
1964
  __decorate([
1843
1965
  targetAttr(onHover)
1844
- ], Editor.prototype, "hoverTarget", void 0);
1966
+ ], exports.Editor.prototype, "hoverTarget", void 0);
1845
1967
  __decorate([
1846
1968
  targetAttr(onTarget)
1847
- ], Editor.prototype, "target", void 0);
1969
+ ], exports.Editor.prototype, "target", void 0);
1970
+ exports.Editor = __decorate([
1971
+ core.useModule(TransformTool, ['editBox', 'editTool', 'emitEvent'])
1972
+ ], exports.Editor);
1848
1973
 
1849
1974
  class InnerEditor {
1850
1975
  static registerInnerEditor() {
1851
1976
  EditToolCreator.register(this);
1852
1977
  }
1853
1978
  get tag() { return 'InnerEditor'; }
1979
+ get mode() { return 'focus'; }
1854
1980
  get editBox() { return this.editor.editBox; }
1855
1981
  constructor(editor) {
1982
+ this.eventIds = [];
1856
1983
  this.editor = editor;
1857
1984
  this.create();
1858
1985
  }
@@ -1865,7 +1992,7 @@ ${filterStyle}
1865
1992
  load() {
1866
1993
  const { editor } = this;
1867
1994
  if (editor) {
1868
- if (editor.app)
1995
+ if (editor.app && this.mode === 'focus')
1869
1996
  editor.selector.hittable = editor.app.tree.hitChildren = false;
1870
1997
  this.onLoad();
1871
1998
  }
@@ -1876,7 +2003,7 @@ ${filterStyle}
1876
2003
  unload() {
1877
2004
  const { editor } = this;
1878
2005
  if (editor) {
1879
- if (editor.app)
2006
+ if (editor.app && this.mode === 'focus')
1880
2007
  editor.selector.hittable = editor.app.tree.hitChildren = true;
1881
2008
  this.onUnload();
1882
2009
  }
@@ -1950,10 +2077,7 @@ ${filterStyle}
1950
2077
  this.onLoad();
1951
2078
  }
1952
2079
  update() {
1953
- const { editor, editBox } = this;
1954
- const { x, y, scaleX, scaleY, rotation, skewX, skewY, width, height } = editor.element.getLayoutBounds('box', editor, true);
1955
- editBox.set({ x, y, scaleX, scaleY, rotation, skewX, skewY });
1956
- editBox.update({ x: 0, y: 0, width, height });
2080
+ this.editBox.update();
1957
2081
  this.onUpdate();
1958
2082
  }
1959
2083
  unload() {
@@ -2073,14 +2197,14 @@ ${filterStyle}
2073
2197
 
2074
2198
  draw.Plugin.add('editor', 'resize');
2075
2199
  draw.Creator.editor = function (options, app) {
2076
- const editor = new Editor(options);
2200
+ const editor = new exports.Editor(options);
2077
2201
  if (app)
2078
2202
  app.sky.add(app.editor = editor);
2079
2203
  return editor;
2080
2204
  };
2081
2205
  draw.Box.addAttr('textBox', false, draw.dataType);
2082
2206
  draw.UI.addAttr('editConfig', undefined, draw.dataType);
2083
- draw.UI.addAttr('editOuter', (ui) => ui.__.__isLinePath ? 'LineEditTool' : 'EditTool', draw.dataType);
2207
+ draw.UI.addAttr('editOuter', (ui) => { ui.updateLayout(); return ui.__.__isLinePath ? 'LineEditTool' : 'EditTool'; }, draw.dataType);
2084
2208
  draw.UI.addAttr('editInner', 'PathEditor', draw.dataType);
2085
2209
  draw.Group.addAttr('editInner', '', draw.dataType);
2086
2210
  draw.Text.addAttr('editInner', 'TextEditor', draw.dataType);
@@ -2094,7 +2218,6 @@ ${filterStyle}
2094
2218
  exports.EditSelect = EditSelect;
2095
2219
  exports.EditSelectHelper = EditSelectHelper;
2096
2220
  exports.EditToolCreator = EditToolCreator;
2097
- exports.Editor = Editor;
2098
2221
  exports.EditorEvent = EditorEvent;
2099
2222
  exports.EditorGroupEvent = EditorGroupEvent;
2100
2223
  exports.EditorHelper = EditorHelper;
@@ -2106,6 +2229,7 @@ ${filterStyle}
2106
2229
  exports.InnerEditorEvent = InnerEditorEvent;
2107
2230
  exports.SelectArea = SelectArea;
2108
2231
  exports.Stroker = Stroker;
2232
+ exports.TransformTool = TransformTool;
2109
2233
  exports.registerEditTool = registerEditTool;
2110
2234
  exports.registerInnerEditor = registerInnerEditor;
2111
2235