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