@leafer-in/editor 1.0.0 → 1.0.2

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
@@ -82,6 +82,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
82
82
  const { scalePoints } = PathScaler;
83
83
 
84
84
  const matrix$1 = draw.MatrixHelper.get();
85
+ const { topLeft: topLeft$1, top: top$1, topRight: topRight$1, right: right$2, bottom: bottom$1, left: left$2 } = draw.Direction9;
85
86
  function scaleResize(leaf, scaleX, scaleY) {
86
87
  if (leaf.pathInputed) {
87
88
  scaleResizePath(leaf, scaleX, scaleY);
@@ -94,14 +95,35 @@ this.LeaferIN.editor = (function (exports, draw, core) {
94
95
  }
95
96
  }
96
97
  function scaleResizeFontSize(leaf, scaleX, scaleY) {
97
- const { width, height } = leaf.__localBoxBounds;
98
- if (scaleX !== 1) {
99
- leaf.fontSize *= scaleX;
100
- leaf.y -= height * (scaleX - scaleY) / 2;
98
+ const { app } = leaf;
99
+ const editor = app && app.editor;
100
+ if (editor.editing) {
101
+ const layout = leaf.__layout;
102
+ let { width, height } = layout.boxBounds;
103
+ width *= (scaleY - scaleX) * (leaf.scaleX < 0 ? -1 : 1);
104
+ height *= (scaleX - scaleY) * (leaf.scaleY < 0 ? -1 : 1);
105
+ switch (editor.resizeDirection) {
106
+ case top$1:
107
+ case bottom$1:
108
+ leaf.fontSize *= scaleY;
109
+ layout.affectScaleOrRotation ? leaf.moveInner(-width / 2, 0) : leaf.x -= width / 2;
110
+ break;
111
+ case left$2:
112
+ case right$2:
113
+ leaf.fontSize *= scaleX;
114
+ layout.affectScaleOrRotation ? leaf.moveInner(0, -height / 2) : leaf.y -= height / 2;
115
+ break;
116
+ case topLeft$1:
117
+ case topRight$1:
118
+ leaf.fontSize *= scaleX;
119
+ layout.affectScaleOrRotation ? leaf.moveInner(0, -height) : leaf.y -= height;
120
+ break;
121
+ default:
122
+ leaf.fontSize *= scaleX;
123
+ }
101
124
  }
102
- else if (scaleY !== 1) {
103
- leaf.fontSize *= scaleY;
104
- leaf.x -= width * (scaleY - scaleX) / 2;
125
+ else {
126
+ leaf.fontSize *= scaleX;
105
127
  }
106
128
  }
107
129
  function scaleResizePath(leaf, scaleX, scaleY) {
@@ -434,7 +456,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
434
456
  }
435
457
  onPointerMove(e) {
436
458
  const { app, editor } = this;
437
- if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
459
+ if (this.running && !this.isMoveMode && app.interaction.canHover && !app.interaction.dragging) {
438
460
  const find = this.findUI(e);
439
461
  editor.hoverTarget = editor.hasItem(find) ? null : find;
440
462
  }
@@ -443,15 +465,27 @@ this.LeaferIN.editor = (function (exports, draw, core) {
443
465
  }
444
466
  }
445
467
  onBeforeDown(e) {
468
+ if (e.multiTouch)
469
+ return;
446
470
  const { select } = this.editor.mergeConfig;
447
- if (select === 'press')
448
- this.checkAndSelect(e);
471
+ if (select === 'press') {
472
+ if (this.app.config.mobile) {
473
+ this.waitSelect = () => this.checkAndSelect(e);
474
+ }
475
+ else {
476
+ this.checkAndSelect(e);
477
+ }
478
+ }
449
479
  }
450
480
  onTap(e) {
481
+ if (e.multiTouch)
482
+ return;
451
483
  const { editor } = this;
452
484
  const { select } = editor.mergeConfig;
453
485
  if (select === 'tap')
454
486
  this.checkAndSelect(e);
487
+ else if (this.waitSelect)
488
+ this.waitSelect();
455
489
  if (this.needRemoveItem) {
456
490
  editor.removeItem(this.needRemoveItem);
457
491
  }
@@ -482,6 +516,10 @@ this.LeaferIN.editor = (function (exports, draw, core) {
482
516
  }
483
517
  }
484
518
  onDragStart(e) {
519
+ if (e.multiTouch)
520
+ return;
521
+ if (this.waitSelect)
522
+ this.waitSelect();
485
523
  if (this.allowDrag(e)) {
486
524
  const { editor } = this;
487
525
  const { stroke, area } = editor.mergeConfig;
@@ -493,10 +531,10 @@ this.LeaferIN.editor = (function (exports, draw, core) {
493
531
  }
494
532
  }
495
533
  onDrag(e) {
496
- if (this.editor.dragging) {
497
- this.onDragEnd();
534
+ if (e.multiTouch)
498
535
  return;
499
- }
536
+ if (this.editor.dragging)
537
+ return this.onDragEnd(e);
500
538
  if (this.dragging) {
501
539
  const { editor } = this;
502
540
  const total = e.getInnerTotal(this);
@@ -520,7 +558,9 @@ this.LeaferIN.editor = (function (exports, draw, core) {
520
558
  }
521
559
  }
522
560
  }
523
- onDragEnd() {
561
+ onDragEnd(e) {
562
+ if (e.multiTouch)
563
+ return;
524
564
  if (this.dragging)
525
565
  this.originList = null, this.selectArea.visible = false;
526
566
  }
@@ -566,7 +606,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
566
606
  app.on_(core.PointerEvent.MOVE, this.onPointerMove, this),
567
607
  app.on_(core.PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
568
608
  app.on_(core.PointerEvent.TAP, this.onTap, this),
569
- app.on_(core.DragEvent.START, this.onDragStart, this),
609
+ app.on_(core.DragEvent.START, this.onDragStart, this, true),
570
610
  app.on_(core.DragEvent.DRAG, this.onDrag, this),
571
611
  app.on_(core.DragEvent.END, this.onDragEnd, this),
572
612
  app.on_(core.MoveEvent.MOVE, this.onAutoMove, this),
@@ -589,22 +629,32 @@ this.LeaferIN.editor = (function (exports, draw, core) {
589
629
 
590
630
  const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = draw.Direction9;
591
631
  const { toPoint } = draw.AroundHelper;
632
+ const { within } = draw.MathHelper;
592
633
  const EditDataHelper = {
593
- getScaleData(bounds, direction, pointMove, lockRatio, around) {
634
+ getScaleData(element, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
594
635
  let align, origin = {}, scaleX = 1, scaleY = 1;
595
- const { width, height } = bounds;
636
+ const { boxBounds, widthRange, heightRange } = element;
637
+ const { width, height } = startBounds;
596
638
  if (around) {
597
- pointMove.x *= 2;
598
- pointMove.y *= 2;
599
- }
600
- if (Math.abs(pointMove.x) === width)
601
- pointMove.x += 0.1;
602
- if (Math.abs(pointMove.y) === height)
603
- pointMove.y += 0.1;
604
- const topScale = (-pointMove.y + height) / height;
605
- const rightScale = (pointMove.x + width) / width;
606
- const bottomScale = (pointMove.y + height) / height;
607
- const leftScale = (-pointMove.x + width) / width;
639
+ totalMove.x *= 2;
640
+ totalMove.y *= 2;
641
+ }
642
+ const originChangedScaleX = element.scaleX / startBounds.scaleX;
643
+ const originChangedScaleY = element.scaleY / startBounds.scaleY;
644
+ const signX = originChangedScaleX < 0 ? -1 : 1;
645
+ const signY = originChangedScaleY < 0 ? -1 : 1;
646
+ const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width;
647
+ const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height;
648
+ totalMove.x *= scaleMode ? originChangedScaleX : signX;
649
+ totalMove.y *= scaleMode ? originChangedScaleY : signY;
650
+ if (Math.abs(totalMove.x) === width)
651
+ totalMove.x += 0.1;
652
+ if (Math.abs(totalMove.y) === height)
653
+ totalMove.y += 0.1;
654
+ const topScale = (-totalMove.y + height) / height;
655
+ const rightScale = (totalMove.x + width) / width;
656
+ const bottomScale = (totalMove.y + height) / height;
657
+ const leftScale = (-totalMove.x + width) / width;
608
658
  switch (direction) {
609
659
  case top:
610
660
  scaleY = topScale;
@@ -645,12 +695,41 @@ this.LeaferIN.editor = (function (exports, draw, core) {
645
695
  if (lockRatio) {
646
696
  const unlockSide = lockRatio === 'corner' && direction % 2;
647
697
  if (!unlockSide) {
648
- const scale = Math.sqrt(Math.abs(scaleX * scaleY));
698
+ let scale;
699
+ switch (direction) {
700
+ case top:
701
+ case bottom:
702
+ scale = scaleY;
703
+ break;
704
+ case left$1:
705
+ case right$1:
706
+ scale = scaleX;
707
+ break;
708
+ default:
709
+ scale = Math.sqrt(Math.abs(scaleX * scaleY));
710
+ }
649
711
  scaleX = scaleX < 0 ? -scale : scale;
650
712
  scaleY = scaleY < 0 ? -scale : scale;
651
713
  }
652
714
  }
653
- toPoint(around || align, bounds, origin);
715
+ scaleX /= changedScaleX;
716
+ scaleY /= changedScaleY;
717
+ if (!flipable) {
718
+ const { worldTransform } = element;
719
+ if (scaleX < 0)
720
+ scaleX = 1 / boxBounds.width / worldTransform.scaleX;
721
+ if (scaleY < 0)
722
+ scaleY = 1 / boxBounds.height / worldTransform.scaleY;
723
+ }
724
+ if (widthRange) {
725
+ const nowWidth = boxBounds.width * element.scaleX;
726
+ scaleX = within(nowWidth * scaleX, widthRange) / nowWidth;
727
+ }
728
+ if (heightRange) {
729
+ const nowHeight = boxBounds.height * element.scaleY;
730
+ scaleY = within(nowHeight * scaleY, heightRange) / nowHeight;
731
+ }
732
+ toPoint(around || align, boxBounds, origin);
654
733
  return { origin, scaleX, scaleY, direction, lockRatio, around };
655
734
  },
656
735
  getRotateData(bounds, direction, current, last, around) {
@@ -771,6 +850,11 @@ this.LeaferIN.editor = (function (exports, draw, core) {
771
850
  return;
772
851
  if (point.name === 'circle')
773
852
  return;
853
+ if (point.pointType === 'button') {
854
+ if (!point.cursor)
855
+ point.cursor = 'pointer';
856
+ return;
857
+ }
774
858
  let { rotation } = editBox;
775
859
  const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
776
860
  const { pointType } = point, { flippedX, flippedY } = editBox;
@@ -839,9 +923,8 @@ this.LeaferIN.editor = (function (exports, draw, core) {
839
923
  resizePoints.push(resizePoint);
840
924
  this.listenPointEvents(resizePoint, 'resize', i);
841
925
  }
842
- buttons.add(circle);
843
926
  this.listenPointEvents(circle, 'rotate', 2);
844
- view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
927
+ view.addMany(...rotatePoints, rect, circle, buttons, ...resizeLines, ...resizePoints);
845
928
  this.add(view);
846
929
  }
847
930
  load() {
@@ -857,9 +940,9 @@ this.LeaferIN.editor = (function (exports, draw, core) {
857
940
  if (!(i % 2))
858
941
  resizeP.rotation = (i / 2) * 90;
859
942
  }
860
- circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]));
943
+ circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]));
861
944
  rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
862
- rect.hittable = !single && moveable;
945
+ rect.hittable = !single && !!moveable;
863
946
  element.syncEventer = (single && moveable) ? rect : null;
864
947
  this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null;
865
948
  }
@@ -868,7 +951,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
868
951
  if (this.view.worldOpacity) {
869
952
  const { mergeConfig } = this.editor;
870
953
  const { width, height } = bounds;
871
- const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
954
+ const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this;
872
955
  const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
873
956
  const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
874
957
  const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
@@ -898,19 +981,25 @@ this.LeaferIN.editor = (function (exports, draw, core) {
898
981
  }
899
982
  }
900
983
  }
901
- circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint;
984
+ circle.visible = showPoints && rotateable && !!(mergeConfig.circle || mergeConfig.rotatePoint);
985
+ if (circle.visible)
986
+ this.layoutCircle(mergeConfig);
902
987
  if (rect.path)
903
988
  rect.path = null;
904
989
  rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
905
- const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1);
906
- this.buttons.visible = buttonVisible;
907
- if (buttonVisible)
908
- this.layoutButtons();
990
+ buttons.visible = showPoints && buttons.children.length > 0;
991
+ if (buttons.visible)
992
+ this.layoutButtons(mergeConfig);
909
993
  }
910
994
  }
911
- layoutButtons() {
912
- const { buttons, resizePoints } = this;
913
- const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig;
995
+ layoutCircle(config) {
996
+ const { circleDirection, circleMargin, buttonsMargin, buttonsDirection, middlePoint } = config;
997
+ const direction = fourDirection.indexOf(circleDirection || ((this.buttons.children.length && buttonsDirection === 'bottom') ? 'top' : 'bottom'));
998
+ this.setButtonPosition(this.circle, direction, circleMargin || buttonsMargin, !!middlePoint);
999
+ }
1000
+ layoutButtons(config) {
1001
+ const { buttons } = this;
1002
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = config;
914
1003
  const { flippedX, flippedY } = this;
915
1004
  let index = fourDirection.indexOf(buttonsDirection);
916
1005
  if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
@@ -918,11 +1007,18 @@ this.LeaferIN.editor = (function (exports, draw, core) {
918
1007
  index = (index + 2) % 4;
919
1008
  }
920
1009
  const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
921
- const point = resizePoints[direction * 2 + 1];
1010
+ this.setButtonPosition(buttons, direction, buttonsMargin, !!middlePoint);
1011
+ if (buttonsFixed)
1012
+ buttons.rotation = (direction - index) * 90;
1013
+ buttons.scaleX = flippedX ? -1 : 1;
1014
+ buttons.scaleY = flippedY ? -1 : 1;
1015
+ }
1016
+ setButtonPosition(buttons, direction, buttonsMargin, useMiddlePoint) {
1017
+ const point = this.resizePoints[direction * 2 + 1];
922
1018
  const useX = direction % 2;
923
1019
  const sign = (!direction || direction === 3) ? -1 : 1;
924
- const useWidth = index % 2;
925
- const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
1020
+ const useWidth = direction % 2;
1021
+ const margin = (buttonsMargin + (useWidth ? ((useMiddlePoint ? point.width : 0) + buttons.boxBounds.width) : ((useMiddlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
926
1022
  if (useX) {
927
1023
  buttons.x = point.x + margin;
928
1024
  buttons.y = point.y;
@@ -931,11 +1027,6 @@ this.LeaferIN.editor = (function (exports, draw, core) {
931
1027
  buttons.x = point.x;
932
1028
  buttons.y = point.y + margin;
933
1029
  }
934
- if (buttonsFixed) {
935
- buttons.rotation = (direction - index) * 90;
936
- buttons.scaleX = flippedX ? -1 : 1;
937
- buttons.scaleY = flippedY ? -1 : 1;
938
- }
939
1030
  }
940
1031
  unload() {
941
1032
  this.visible = false;
@@ -962,18 +1053,23 @@ this.LeaferIN.editor = (function (exports, draw, core) {
962
1053
  }
963
1054
  onDragStart(e) {
964
1055
  this.dragging = true;
1056
+ const { editor } = this;
965
1057
  if (e.current.name === 'rect') {
966
- const { editor } = this;
967
1058
  this.moving = true;
968
1059
  editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
969
1060
  editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
970
1061
  }
1062
+ else if (e.current.pointType === 'resize') {
1063
+ editor.dragStartBounds = Object.assign({}, editor.element.getLayoutBounds('box', 'local'));
1064
+ editor.resizeDirection = e.current.direction;
1065
+ }
971
1066
  }
972
1067
  onDragEnd(e) {
973
1068
  this.dragging = false;
974
1069
  this.moving = false;
975
1070
  if (e.current.name === 'rect')
976
1071
  this.editor.opacity = 1;
1072
+ this.editor.resizeDirection = undefined;
977
1073
  }
978
1074
  onDrag(e) {
979
1075
  const { editor } = this;
@@ -982,7 +1078,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
982
1078
  if (editor.mergeConfig.rotateable)
983
1079
  editor.onRotate(e);
984
1080
  }
985
- else {
1081
+ else if (point.pointType === 'resize') {
986
1082
  editor.onScale(e);
987
1083
  }
988
1084
  updateCursor(editor, e);
@@ -1046,8 +1142,6 @@ this.LeaferIN.editor = (function (exports, draw, core) {
1046
1142
  rect.on_(core.DragEvent.START, this.onDragStart, this),
1047
1143
  rect.on_(core.DragEvent.DRAG, editor.onMove, editor),
1048
1144
  rect.on_(core.DragEvent.END, this.onDragEnd, this),
1049
- rect.on_(core.ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
1050
- rect.on_(core.RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
1051
1145
  rect.on_(core.PointerEvent.ENTER, () => updateMoveCursor(editor)),
1052
1146
  rect.on_(core.PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
1053
1147
  rect.on_(core.PointerEvent.LONG_PRESS, this.onLongPress, this)
@@ -1077,7 +1171,7 @@ this.LeaferIN.editor = (function (exports, draw, core) {
1077
1171
  const { rect } = editor.editBox;
1078
1172
  const { width, height } = rect.__;
1079
1173
  canvas.resetTransform();
1080
- canvas.fillWorld(canvas.bounds, mask);
1174
+ canvas.fillWorld(canvas.bounds, mask === true ? 'rgba(0,0,0,0.8)' : mask);
1081
1175
  canvas.setWorld(rect.__world, options.matrix);
1082
1176
  canvas.clearRect(0, 0, width, height);
1083
1177
  }
@@ -1162,6 +1256,7 @@ ${filterStyle}
1162
1256
  boxSelect: true,
1163
1257
  moveable: true,
1164
1258
  resizeable: true,
1259
+ flipable: true,
1165
1260
  rotateable: true,
1166
1261
  skewable: true
1167
1262
  };
@@ -1319,7 +1414,7 @@ ${filterStyle}
1319
1414
  get buttons() { return this.editBox.buttons; }
1320
1415
  constructor(userConfig, data) {
1321
1416
  super(data);
1322
- this.config = config;
1417
+ this.config = draw.DataHelper.clone(config);
1323
1418
  this.leafList = new draw.LeafList();
1324
1419
  this.openedGroupList = new draw.LeafList();
1325
1420
  this.simulateTarget = new draw.Rect({ visible: false });
@@ -1383,29 +1478,39 @@ ${filterStyle}
1383
1478
  return this.mergeConfig.editSize;
1384
1479
  }
1385
1480
  onMove(e) {
1386
- const total = { x: e.totalX, y: e.totalY };
1387
- if (e.shiftKey) {
1388
- if (Math.abs(total.x) > Math.abs(total.y))
1389
- total.y = 0;
1390
- else
1391
- total.x = 0;
1481
+ if (e instanceof core.MoveEvent) {
1482
+ if (e.moveType !== 'drag') {
1483
+ const { moveable, resizeable } = this.mergeConfig;
1484
+ const move = e.getLocalMove(this.element);
1485
+ if (moveable === 'move')
1486
+ e.stop(), this.move(move.x, move.y);
1487
+ else if (resizeable === 'zoom')
1488
+ e.stop();
1489
+ }
1490
+ }
1491
+ else {
1492
+ const total = { x: e.totalX, y: e.totalY };
1493
+ if (e.shiftKey) {
1494
+ if (Math.abs(total.x) > Math.abs(total.y))
1495
+ total.y = 0;
1496
+ else
1497
+ total.x = 0;
1498
+ }
1499
+ this.move(core.DragEvent.getValidMove(this.element, this.dragStartPoint, total));
1392
1500
  }
1393
- this.move(core.DragEvent.getValidMove(this.element, this.dragStartPoint, total));
1394
1501
  }
1395
1502
  onScale(e) {
1396
1503
  const { element } = this;
1504
+ let { around, lockRatio, resizeable, flipable, editSize } = this.mergeConfig;
1397
1505
  if (e instanceof core.ZoomEvent) {
1398
- if (this.mergeConfig.resizeable === 'zoom') {
1399
- e.stop();
1400
- this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
1401
- }
1506
+ if (resizeable === 'zoom')
1507
+ e.stop(), this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
1402
1508
  }
1403
1509
  else {
1404
1510
  const { direction } = e.current;
1405
- let { around, lockRatio } = this.mergeConfig;
1406
1511
  if (e.shiftKey || element.lockRatio)
1407
1512
  lockRatio = true;
1408
- const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
1513
+ const data = EditDataHelper.getScaleData(element, this.dragStartBounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
1409
1514
  if (this.editTool.onScaleWithDrag) {
1410
1515
  data.drag = e;
1411
1516
  this.scaleWithDrag(data);
@@ -1416,23 +1521,21 @@ ${filterStyle}
1416
1521
  }
1417
1522
  }
1418
1523
  onRotate(e) {
1419
- const { skewable, around, rotateGap } = this.mergeConfig;
1524
+ const { skewable, rotateable, around, rotateGap } = this.mergeConfig;
1420
1525
  const { direction, name } = e.current;
1421
1526
  if (skewable && name === 'resize-line')
1422
1527
  return this.onSkew(e);
1423
1528
  const { element } = this;
1424
1529
  let origin, rotation;
1425
1530
  if (e instanceof core.RotateEvent) {
1426
- if (this.mergeConfig.rotateable === 'rotate') {
1427
- e.stop();
1428
- rotation = e.rotation, origin = element.getInnerPoint(e);
1429
- }
1531
+ if (rotateable === 'rotate')
1532
+ e.stop(), rotation = e.rotation, origin = element.getInnerPoint(e);
1430
1533
  else
1431
1534
  return;
1432
1535
  }
1433
1536
  else {
1434
1537
  const last = { x: e.x - e.moveX, y: e.y - e.moveY };
1435
- const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
1538
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
1436
1539
  rotation = data.rotation;
1437
1540
  origin = data.origin;
1438
1541
  }
@@ -1466,8 +1569,7 @@ ${filterStyle}
1466
1569
  if (!this.mergeConfig.resizeable || this.element.locked)
1467
1570
  return;
1468
1571
  const { element } = this;
1469
- const worldOrigin = element.getWorldPoint(data.origin);
1470
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
1572
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) }));
1471
1573
  this.editTool.onScaleWithDrag(event);
1472
1574
  this.emitEvent(event);
1473
1575
  }
@@ -1475,28 +1577,28 @@ ${filterStyle}
1475
1577
  if (!this.mergeConfig.resizeable || this.element.locked)
1476
1578
  return;
1477
1579
  const { element } = this;
1478
- const worldOrigin = element.getWorldPoint(draw.LeafHelper.getInnerOrigin(element, origin));
1479
- let transform;
1480
- if (this.multiple) {
1481
- const oldMatrix = new draw.Matrix(element.worldTransform);
1482
- element.scaleOf(origin, scaleX, scaleY);
1483
- transform = new draw.Matrix(element.worldTransform).divide(oldMatrix);
1484
- }
1580
+ const worldOrigin = this.getWorldOrigin(origin);
1581
+ const transform = this.multiple && this.getChangedTransform(() => element.scaleOf(origin, scaleX, scaleY));
1485
1582
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
1486
1583
  this.editTool.onScale(event);
1487
1584
  this.emitEvent(event);
1488
1585
  }
1586
+ flip(axis) {
1587
+ if (this.element.locked)
1588
+ return;
1589
+ const { element } = this;
1590
+ const worldOrigin = this.getWorldOrigin('center');
1591
+ const transform = this.multiple ? this.getChangedTransform(() => element.flip(axis)) : new draw.Matrix(draw.LeafHelper.getFlipTransform(element, axis));
1592
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform });
1593
+ this.editTool.onScale(event);
1594
+ this.emitEvent(event);
1595
+ }
1489
1596
  rotateOf(origin, rotation) {
1490
1597
  if (!this.mergeConfig.rotateable || this.element.locked)
1491
1598
  return;
1492
1599
  const { element } = this;
1493
- const worldOrigin = element.getWorldPoint(draw.LeafHelper.getInnerOrigin(element, origin));
1494
- let transform;
1495
- if (this.multiple) {
1496
- const oldMatrix = new draw.Matrix(element.worldTransform);
1497
- element.rotateOf(origin, rotation);
1498
- transform = new draw.Matrix(element.worldTransform).divide(oldMatrix);
1499
- }
1600
+ const worldOrigin = this.getWorldOrigin(origin);
1601
+ const transform = this.multiple && this.getChangedTransform(() => element.rotateOf(origin, rotation));
1500
1602
  const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
1501
1603
  this.editTool.onRotate(event);
1502
1604
  this.emitEvent(event);
@@ -1505,19 +1607,21 @@ ${filterStyle}
1505
1607
  if (!this.mergeConfig.skewable || this.element.locked)
1506
1608
  return;
1507
1609
  const { element } = this;
1508
- const worldOrigin = element.getWorldPoint(draw.LeafHelper.getInnerOrigin(element, origin));
1509
- let transform;
1510
- if (this.multiple) {
1511
- const oldMatrix = new draw.Matrix(element.worldTransform);
1512
- element.skewOf(origin, skewX, skewY);
1513
- transform = new draw.Matrix(element.worldTransform).divide(oldMatrix);
1514
- }
1515
- const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
1516
- target: element, editor: this, skewX, skewY, transform, worldOrigin
1517
- });
1610
+ const worldOrigin = this.getWorldOrigin(origin);
1611
+ const transform = this.multiple && this.getChangedTransform(() => element.skewOf(origin, skewX, skewY));
1612
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, { target: element, editor: this, worldOrigin, skewX, skewY, transform });
1518
1613
  this.editTool.onSkew(event);
1519
1614
  this.emitEvent(event);
1520
1615
  }
1616
+ getWorldOrigin(origin) {
1617
+ return this.element.getWorldPoint(draw.LeafHelper.getInnerOrigin(this.element, origin));
1618
+ }
1619
+ getChangedTransform(func) {
1620
+ const { element } = this;
1621
+ const oldMatrix = new draw.Matrix(element.worldTransform);
1622
+ func();
1623
+ return new draw.Matrix(element.worldTransform).divide(oldMatrix);
1624
+ }
1521
1625
  group(userGroup) {
1522
1626
  if (this.multiple) {
1523
1627
  this.target = EditorHelper.group(this.list, this.element, userGroup);
@@ -1628,6 +1732,9 @@ ${filterStyle}
1628
1732
  if (!this.targetEventIds.length) {
1629
1733
  const { leafer } = this.list[0];
1630
1734
  this.targetEventIds = [
1735
+ this.app.on_(core.MoveEvent.BEFORE_MOVE, this.onMove, this, true),
1736
+ this.app.on_(core.ZoomEvent.BEFORE_ZOOM, this.onScale, this, true),
1737
+ this.app.on_(core.RotateEvent.BEFORE_ROTATE, this.onRotate, this, true),
1631
1738
  leafer.on_(draw.RenderEvent.START, this.update, this),
1632
1739
  leafer.on_([core.KeyEvent.HOLD, core.KeyEvent.UP], (e) => { updateCursor(this, e); }),
1633
1740
  leafer.on_(core.KeyEvent.DOWN, this.editBox.onArrow, this.editBox)