@leafer-in/editor 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { PathCommandMap, MatrixHelper, Leaf, Text, Path, Line, Polygon, Group, Box, Event, defineKey, UI, Paint, Rect, Answer, Bounds, LeafList, PointHelper, AroundHelper, Direction9, MathHelper, Matrix, Debug, DataHelper, LeafHelper, RenderEvent, getPointData, Creator } from '@leafer-ui/draw';
1
+ import { PathCommandMap, MatrixHelper, Leaf, Text, Path, Line, Polygon, Group, Box, Event, defineKey, UI, Paint, Rect, Answer, Bounds, LeafList, PointHelper, AroundHelper, MathHelper, Direction9, Matrix, Debug, DataHelper, LeafHelper, RenderEvent, getPointData, Creator } from '@leafer-ui/draw';
2
2
  import { PointerEvent, DragEvent, MoveEvent, ZoomEvent, RotateEvent, KeyEvent } from '@leafer-ui/core';
3
3
 
4
4
  const { M, L, C, Q, Z, N, D, X, G, F, O, P, U } = PathCommandMap;
@@ -433,7 +433,7 @@ class EditSelect extends Group {
433
433
  }
434
434
  onPointerMove(e) {
435
435
  const { app, editor } = this;
436
- if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
436
+ if (this.running && !this.isMoveMode && app.interaction.canHover && !app.interaction.dragging) {
437
437
  const find = this.findUI(e);
438
438
  editor.hoverTarget = editor.hasItem(find) ? null : find;
439
439
  }
@@ -442,15 +442,27 @@ class EditSelect extends Group {
442
442
  }
443
443
  }
444
444
  onBeforeDown(e) {
445
+ if (e.multiTouch)
446
+ return;
445
447
  const { select } = this.editor.mergeConfig;
446
- if (select === 'press')
447
- this.checkAndSelect(e);
448
+ if (select === 'press') {
449
+ if (this.app.config.mobile) {
450
+ this.waitSelect = () => this.checkAndSelect(e);
451
+ }
452
+ else {
453
+ this.checkAndSelect(e);
454
+ }
455
+ }
448
456
  }
449
457
  onTap(e) {
458
+ if (e.multiTouch)
459
+ return;
450
460
  const { editor } = this;
451
461
  const { select } = editor.mergeConfig;
452
462
  if (select === 'tap')
453
463
  this.checkAndSelect(e);
464
+ else if (this.waitSelect)
465
+ this.waitSelect();
454
466
  if (this.needRemoveItem) {
455
467
  editor.removeItem(this.needRemoveItem);
456
468
  }
@@ -481,6 +493,10 @@ class EditSelect extends Group {
481
493
  }
482
494
  }
483
495
  onDragStart(e) {
496
+ if (e.multiTouch)
497
+ return;
498
+ if (this.waitSelect)
499
+ this.waitSelect();
484
500
  if (this.allowDrag(e)) {
485
501
  const { editor } = this;
486
502
  const { stroke, area } = editor.mergeConfig;
@@ -492,10 +508,10 @@ class EditSelect extends Group {
492
508
  }
493
509
  }
494
510
  onDrag(e) {
495
- if (this.editor.dragging) {
496
- this.onDragEnd();
511
+ if (e.multiTouch)
497
512
  return;
498
- }
513
+ if (this.editor.dragging)
514
+ return this.onDragEnd(e);
499
515
  if (this.dragging) {
500
516
  const { editor } = this;
501
517
  const total = e.getInnerTotal(this);
@@ -519,7 +535,9 @@ class EditSelect extends Group {
519
535
  }
520
536
  }
521
537
  }
522
- onDragEnd() {
538
+ onDragEnd(e) {
539
+ if (e.multiTouch)
540
+ return;
523
541
  if (this.dragging)
524
542
  this.originList = null, this.selectArea.visible = false;
525
543
  }
@@ -565,7 +583,7 @@ class EditSelect extends Group {
565
583
  app.on_(PointerEvent.MOVE, this.onPointerMove, this),
566
584
  app.on_(PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
567
585
  app.on_(PointerEvent.TAP, this.onTap, this),
568
- app.on_(DragEvent.START, this.onDragStart, this),
586
+ app.on_(DragEvent.START, this.onDragStart, this, true),
569
587
  app.on_(DragEvent.DRAG, this.onDrag, this),
570
588
  app.on_(DragEvent.END, this.onDragEnd, this),
571
589
  app.on_(MoveEvent.MOVE, this.onAutoMove, this),
@@ -588,22 +606,32 @@ class EditSelect extends Group {
588
606
 
589
607
  const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = Direction9;
590
608
  const { toPoint } = AroundHelper;
609
+ const { within } = MathHelper;
591
610
  const EditDataHelper = {
592
- getScaleData(bounds, direction, pointMove, lockRatio, around) {
611
+ getScaleData(element, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
593
612
  let align, origin = {}, scaleX = 1, scaleY = 1;
594
- const { width, height } = bounds;
613
+ const { boxBounds, widthRange, heightRange } = element;
614
+ const { width, height } = startBounds;
595
615
  if (around) {
596
- pointMove.x *= 2;
597
- pointMove.y *= 2;
598
- }
599
- if (Math.abs(pointMove.x) === width)
600
- pointMove.x += 0.1;
601
- if (Math.abs(pointMove.y) === height)
602
- pointMove.y += 0.1;
603
- const topScale = (-pointMove.y + height) / height;
604
- const rightScale = (pointMove.x + width) / width;
605
- const bottomScale = (pointMove.y + height) / height;
606
- const leftScale = (-pointMove.x + width) / width;
616
+ totalMove.x *= 2;
617
+ totalMove.y *= 2;
618
+ }
619
+ const originChangedScaleX = element.scaleX / startBounds.scaleX;
620
+ const originChangedScaleY = element.scaleY / startBounds.scaleY;
621
+ const signX = originChangedScaleX < 0 ? -1 : 1;
622
+ const signY = originChangedScaleY < 0 ? -1 : 1;
623
+ const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width;
624
+ const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height;
625
+ totalMove.x *= scaleMode ? originChangedScaleX : signX;
626
+ totalMove.y *= scaleMode ? originChangedScaleY : signY;
627
+ if (Math.abs(totalMove.x) === width)
628
+ totalMove.x += 0.1;
629
+ if (Math.abs(totalMove.y) === height)
630
+ totalMove.y += 0.1;
631
+ const topScale = (-totalMove.y + height) / height;
632
+ const rightScale = (totalMove.x + width) / width;
633
+ const bottomScale = (totalMove.y + height) / height;
634
+ const leftScale = (-totalMove.x + width) / width;
607
635
  switch (direction) {
608
636
  case top:
609
637
  scaleY = topScale;
@@ -649,7 +677,24 @@ const EditDataHelper = {
649
677
  scaleY = scaleY < 0 ? -scale : scale;
650
678
  }
651
679
  }
652
- toPoint(around || align, bounds, origin);
680
+ scaleX /= changedScaleX;
681
+ scaleY /= changedScaleY;
682
+ if (!flipable) {
683
+ const { worldTransform } = element;
684
+ if (scaleX < 0)
685
+ scaleX = 1 / boxBounds.width / worldTransform.scaleX;
686
+ if (scaleY < 0)
687
+ scaleY = 1 / boxBounds.height / worldTransform.scaleY;
688
+ }
689
+ if (widthRange) {
690
+ const nowWidth = boxBounds.width * element.scaleX;
691
+ scaleX = within(nowWidth * scaleX, widthRange) / nowWidth;
692
+ }
693
+ if (heightRange) {
694
+ const nowHeight = boxBounds.height * element.scaleY;
695
+ scaleY = within(nowHeight * scaleY, heightRange) / nowHeight;
696
+ }
697
+ toPoint(around || align, boxBounds, origin);
653
698
  return { origin, scaleX, scaleY, direction, lockRatio, around };
654
699
  },
655
700
  getRotateData(bounds, direction, current, last, around) {
@@ -770,6 +815,11 @@ function updateCursor(editor, e) {
770
815
  return;
771
816
  if (point.name === 'circle')
772
817
  return;
818
+ if (point.pointType === 'button') {
819
+ if (!point.cursor)
820
+ point.cursor = 'pointer';
821
+ return;
822
+ }
773
823
  let { rotation } = editBox;
774
824
  const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
775
825
  const { pointType } = point, { flippedX, flippedY } = editBox;
@@ -838,9 +888,8 @@ class EditBox extends Group {
838
888
  resizePoints.push(resizePoint);
839
889
  this.listenPointEvents(resizePoint, 'resize', i);
840
890
  }
841
- buttons.add(circle);
842
891
  this.listenPointEvents(circle, 'rotate', 2);
843
- view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
892
+ view.addMany(...rotatePoints, rect, circle, buttons, ...resizeLines, ...resizePoints);
844
893
  this.add(view);
845
894
  }
846
895
  load() {
@@ -856,9 +905,9 @@ class EditBox extends Group {
856
905
  if (!(i % 2))
857
906
  resizeP.rotation = (i / 2) * 90;
858
907
  }
859
- circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]));
908
+ circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]));
860
909
  rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
861
- rect.hittable = !single && moveable;
910
+ rect.hittable = !single && !!moveable;
862
911
  element.syncEventer = (single && moveable) ? rect : null;
863
912
  this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null;
864
913
  }
@@ -867,7 +916,7 @@ class EditBox extends Group {
867
916
  if (this.view.worldOpacity) {
868
917
  const { mergeConfig } = this.editor;
869
918
  const { width, height } = bounds;
870
- const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
919
+ const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this;
871
920
  const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
872
921
  const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
873
922
  const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
@@ -897,19 +946,25 @@ class EditBox extends Group {
897
946
  }
898
947
  }
899
948
  }
900
- circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint;
949
+ circle.visible = showPoints && rotateable && !!(mergeConfig.circle || mergeConfig.rotatePoint);
950
+ if (circle.visible)
951
+ this.layoutCircle(mergeConfig);
901
952
  if (rect.path)
902
953
  rect.path = null;
903
954
  rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
904
- const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1);
905
- this.buttons.visible = buttonVisible;
906
- if (buttonVisible)
907
- this.layoutButtons();
955
+ buttons.visible = showPoints && buttons.children.length > 0;
956
+ if (buttons.visible)
957
+ this.layoutButtons(mergeConfig);
908
958
  }
909
959
  }
910
- layoutButtons() {
911
- const { buttons, resizePoints } = this;
912
- const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig;
960
+ layoutCircle(config) {
961
+ const { circleDirection, circleMargin, buttonsMargin, buttonsDirection, middlePoint } = config;
962
+ const direction = fourDirection.indexOf(circleDirection || ((this.buttons.children.length && buttonsDirection === 'bottom') ? 'top' : 'bottom'));
963
+ this.setButtonPosition(this.circle, direction, circleMargin || buttonsMargin, !!middlePoint);
964
+ }
965
+ layoutButtons(config) {
966
+ const { buttons } = this;
967
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = config;
913
968
  const { flippedX, flippedY } = this;
914
969
  let index = fourDirection.indexOf(buttonsDirection);
915
970
  if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
@@ -917,11 +972,18 @@ class EditBox extends Group {
917
972
  index = (index + 2) % 4;
918
973
  }
919
974
  const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
920
- const point = resizePoints[direction * 2 + 1];
975
+ this.setButtonPosition(buttons, direction, buttonsMargin, !!middlePoint);
976
+ if (buttonsFixed)
977
+ buttons.rotation = (direction - index) * 90;
978
+ buttons.scaleX = flippedX ? -1 : 1;
979
+ buttons.scaleY = flippedY ? -1 : 1;
980
+ }
981
+ setButtonPosition(buttons, direction, buttonsMargin, useMiddlePoint) {
982
+ const point = this.resizePoints[direction * 2 + 1];
921
983
  const useX = direction % 2;
922
984
  const sign = (!direction || direction === 3) ? -1 : 1;
923
- const useWidth = index % 2;
924
- const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
985
+ const useWidth = direction % 2;
986
+ const margin = (buttonsMargin + (useWidth ? ((useMiddlePoint ? point.width : 0) + buttons.boxBounds.width) : ((useMiddlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
925
987
  if (useX) {
926
988
  buttons.x = point.x + margin;
927
989
  buttons.y = point.y;
@@ -930,11 +992,6 @@ class EditBox extends Group {
930
992
  buttons.x = point.x;
931
993
  buttons.y = point.y + margin;
932
994
  }
933
- if (buttonsFixed) {
934
- buttons.rotation = (direction - index) * 90;
935
- buttons.scaleX = flippedX ? -1 : 1;
936
- buttons.scaleY = flippedY ? -1 : 1;
937
- }
938
995
  }
939
996
  unload() {
940
997
  this.visible = false;
@@ -961,12 +1018,15 @@ class EditBox extends Group {
961
1018
  }
962
1019
  onDragStart(e) {
963
1020
  this.dragging = true;
1021
+ const { editor } = this;
964
1022
  if (e.current.name === 'rect') {
965
- const { editor } = this;
966
1023
  this.moving = true;
967
1024
  editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
968
1025
  editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
969
1026
  }
1027
+ else if (e.current.pointType === 'resize') {
1028
+ editor.dragStartBounds = Object.assign({}, editor.element.getLayoutBounds('box', 'local'));
1029
+ }
970
1030
  }
971
1031
  onDragEnd(e) {
972
1032
  this.dragging = false;
@@ -981,7 +1041,7 @@ class EditBox extends Group {
981
1041
  if (editor.mergeConfig.rotateable)
982
1042
  editor.onRotate(e);
983
1043
  }
984
- else {
1044
+ else if (point.pointType === 'resize') {
985
1045
  editor.onScale(e);
986
1046
  }
987
1047
  updateCursor(editor, e);
@@ -1045,8 +1105,6 @@ class EditBox extends Group {
1045
1105
  rect.on_(DragEvent.START, this.onDragStart, this),
1046
1106
  rect.on_(DragEvent.DRAG, editor.onMove, editor),
1047
1107
  rect.on_(DragEvent.END, this.onDragEnd, this),
1048
- rect.on_(ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
1049
- rect.on_(RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
1050
1108
  rect.on_(PointerEvent.ENTER, () => updateMoveCursor(editor)),
1051
1109
  rect.on_(PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
1052
1110
  rect.on_(PointerEvent.LONG_PRESS, this.onLongPress, this)
@@ -1076,7 +1134,7 @@ class EditMask extends UI {
1076
1134
  const { rect } = editor.editBox;
1077
1135
  const { width, height } = rect.__;
1078
1136
  canvas.resetTransform();
1079
- canvas.fillWorld(canvas.bounds, mask);
1137
+ canvas.fillWorld(canvas.bounds, mask === true ? 'rgba(0,0,0,0.8)' : mask);
1080
1138
  canvas.setWorld(rect.__world, options.matrix);
1081
1139
  canvas.clearRect(0, 0, width, height);
1082
1140
  }
@@ -1161,6 +1219,7 @@ const config = {
1161
1219
  boxSelect: true,
1162
1220
  moveable: true,
1163
1221
  resizeable: true,
1222
+ flipable: true,
1164
1223
  rotateable: true,
1165
1224
  skewable: true
1166
1225
  };
@@ -1382,29 +1441,39 @@ class Editor extends Group {
1382
1441
  return this.mergeConfig.editSize;
1383
1442
  }
1384
1443
  onMove(e) {
1385
- const total = { x: e.totalX, y: e.totalY };
1386
- if (e.shiftKey) {
1387
- if (Math.abs(total.x) > Math.abs(total.y))
1388
- total.y = 0;
1389
- else
1390
- total.x = 0;
1444
+ if (e instanceof MoveEvent) {
1445
+ if (e.moveType !== 'drag') {
1446
+ const { moveable, resizeable } = this.mergeConfig;
1447
+ const move = e.getLocalMove(this.element);
1448
+ if (moveable === 'move')
1449
+ e.stop(), this.move(move.x, move.y);
1450
+ else if (resizeable === 'zoom')
1451
+ e.stop();
1452
+ }
1453
+ }
1454
+ else {
1455
+ const total = { x: e.totalX, y: e.totalY };
1456
+ if (e.shiftKey) {
1457
+ if (Math.abs(total.x) > Math.abs(total.y))
1458
+ total.y = 0;
1459
+ else
1460
+ total.x = 0;
1461
+ }
1462
+ this.move(DragEvent.getValidMove(this.element, this.dragStartPoint, total));
1391
1463
  }
1392
- this.move(DragEvent.getValidMove(this.element, this.dragStartPoint, total));
1393
1464
  }
1394
1465
  onScale(e) {
1395
1466
  const { element } = this;
1467
+ let { around, lockRatio, resizeable, flipable, editSize } = this.mergeConfig;
1396
1468
  if (e instanceof ZoomEvent) {
1397
- if (this.mergeConfig.resizeable === 'zoom') {
1398
- e.stop();
1399
- this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
1400
- }
1469
+ if (resizeable === 'zoom')
1470
+ e.stop(), this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
1401
1471
  }
1402
1472
  else {
1403
1473
  const { direction } = e.current;
1404
- let { around, lockRatio } = this.mergeConfig;
1405
1474
  if (e.shiftKey || element.lockRatio)
1406
1475
  lockRatio = true;
1407
- const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
1476
+ const data = EditDataHelper.getScaleData(element, this.dragStartBounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
1408
1477
  if (this.editTool.onScaleWithDrag) {
1409
1478
  data.drag = e;
1410
1479
  this.scaleWithDrag(data);
@@ -1415,23 +1484,21 @@ class Editor extends Group {
1415
1484
  }
1416
1485
  }
1417
1486
  onRotate(e) {
1418
- const { skewable, around, rotateGap } = this.mergeConfig;
1487
+ const { skewable, rotateable, around, rotateGap } = this.mergeConfig;
1419
1488
  const { direction, name } = e.current;
1420
1489
  if (skewable && name === 'resize-line')
1421
1490
  return this.onSkew(e);
1422
1491
  const { element } = this;
1423
1492
  let origin, rotation;
1424
1493
  if (e instanceof RotateEvent) {
1425
- if (this.mergeConfig.rotateable === 'rotate') {
1426
- e.stop();
1427
- rotation = e.rotation, origin = element.getInnerPoint(e);
1428
- }
1494
+ if (rotateable === 'rotate')
1495
+ e.stop(), rotation = e.rotation, origin = element.getInnerPoint(e);
1429
1496
  else
1430
1497
  return;
1431
1498
  }
1432
1499
  else {
1433
1500
  const last = { x: e.x - e.moveX, y: e.y - e.moveY };
1434
- const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
1501
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
1435
1502
  rotation = data.rotation;
1436
1503
  origin = data.origin;
1437
1504
  }
@@ -1465,8 +1532,7 @@ class Editor extends Group {
1465
1532
  if (!this.mergeConfig.resizeable || this.element.locked)
1466
1533
  return;
1467
1534
  const { element } = this;
1468
- const worldOrigin = element.getWorldPoint(data.origin);
1469
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
1535
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) }));
1470
1536
  this.editTool.onScaleWithDrag(event);
1471
1537
  this.emitEvent(event);
1472
1538
  }
@@ -1474,28 +1540,28 @@ class Editor extends Group {
1474
1540
  if (!this.mergeConfig.resizeable || this.element.locked)
1475
1541
  return;
1476
1542
  const { element } = this;
1477
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
1478
- let transform;
1479
- if (this.multiple) {
1480
- const oldMatrix = new Matrix(element.worldTransform);
1481
- element.scaleOf(origin, scaleX, scaleY);
1482
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
1483
- }
1543
+ const worldOrigin = this.getWorldOrigin(origin);
1544
+ const transform = this.multiple && this.getChangedTransform(() => element.scaleOf(origin, scaleX, scaleY));
1484
1545
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
1485
1546
  this.editTool.onScale(event);
1486
1547
  this.emitEvent(event);
1487
1548
  }
1549
+ flip(axis) {
1550
+ if (this.element.locked)
1551
+ return;
1552
+ const { element } = this;
1553
+ const worldOrigin = this.getWorldOrigin('center');
1554
+ const transform = this.multiple ? this.getChangedTransform(() => element.flip(axis)) : new Matrix(LeafHelper.getFlipTransform(element, axis));
1555
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform });
1556
+ this.editTool.onScale(event);
1557
+ this.emitEvent(event);
1558
+ }
1488
1559
  rotateOf(origin, rotation) {
1489
1560
  if (!this.mergeConfig.rotateable || this.element.locked)
1490
1561
  return;
1491
1562
  const { element } = this;
1492
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
1493
- let transform;
1494
- if (this.multiple) {
1495
- const oldMatrix = new Matrix(element.worldTransform);
1496
- element.rotateOf(origin, rotation);
1497
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
1498
- }
1563
+ const worldOrigin = this.getWorldOrigin(origin);
1564
+ const transform = this.multiple && this.getChangedTransform(() => element.rotateOf(origin, rotation));
1499
1565
  const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
1500
1566
  this.editTool.onRotate(event);
1501
1567
  this.emitEvent(event);
@@ -1504,19 +1570,21 @@ class Editor extends Group {
1504
1570
  if (!this.mergeConfig.skewable || this.element.locked)
1505
1571
  return;
1506
1572
  const { element } = this;
1507
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
1508
- let transform;
1509
- if (this.multiple) {
1510
- const oldMatrix = new Matrix(element.worldTransform);
1511
- element.skewOf(origin, skewX, skewY);
1512
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
1513
- }
1514
- const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
1515
- target: element, editor: this, skewX, skewY, transform, worldOrigin
1516
- });
1573
+ const worldOrigin = this.getWorldOrigin(origin);
1574
+ const transform = this.multiple && this.getChangedTransform(() => element.skewOf(origin, skewX, skewY));
1575
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, { target: element, editor: this, worldOrigin, skewX, skewY, transform });
1517
1576
  this.editTool.onSkew(event);
1518
1577
  this.emitEvent(event);
1519
1578
  }
1579
+ getWorldOrigin(origin) {
1580
+ return this.element.getWorldPoint(LeafHelper.getInnerOrigin(this.element, origin));
1581
+ }
1582
+ getChangedTransform(func) {
1583
+ const { element } = this;
1584
+ const oldMatrix = new Matrix(element.worldTransform);
1585
+ func();
1586
+ return new Matrix(element.worldTransform).divide(oldMatrix);
1587
+ }
1520
1588
  group(userGroup) {
1521
1589
  if (this.multiple) {
1522
1590
  this.target = EditorHelper.group(this.list, this.element, userGroup);
@@ -1627,6 +1695,9 @@ class Editor extends Group {
1627
1695
  if (!this.targetEventIds.length) {
1628
1696
  const { leafer } = this.list[0];
1629
1697
  this.targetEventIds = [
1698
+ this.app.on_(MoveEvent.BEFORE_MOVE, this.onMove, this, true),
1699
+ this.app.on_(ZoomEvent.BEFORE_ZOOM, this.onScale, this, true),
1700
+ this.app.on_(RotateEvent.BEFORE_ROTATE, this.onRotate, this, true),
1630
1701
  leafer.on_(RenderEvent.START, this.update, this),
1631
1702
  leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); }),
1632
1703
  leafer.on_(KeyEvent.DOWN, this.editBox.onArrow, this.editBox)