@leafer-editor/worker 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.
@@ -48,6 +48,8 @@ const I$2 = IncrementId;
48
48
  const { round, pow: pow$1, PI: PI$4 } = Math;
49
49
  const MathHelper = {
50
50
  within(value, min, max) {
51
+ if (typeof min === 'object')
52
+ max = min.max, min = min.min;
51
53
  if (min !== undefined && value < min)
52
54
  value = min;
53
55
  if (max !== undefined && value > max)
@@ -150,10 +152,10 @@ const MatrixHelper = {
150
152
  t.e += x;
151
153
  t.f += y;
152
154
  },
153
- translateInner(t, x, y, isMoveOrigin) {
155
+ translateInner(t, x, y, hasOrigin) {
154
156
  t.e += t.a * x + t.c * y;
155
157
  t.f += t.b * x + t.d * y;
156
- if (isMoveOrigin)
158
+ if (hasOrigin)
157
159
  t.e -= x, t.f -= y;
158
160
  },
159
161
  scale(t, scaleX, scaleY = scaleX) {
@@ -312,7 +314,7 @@ const MatrixHelper = {
312
314
  to.y -= (f * a - e * b) * s;
313
315
  }
314
316
  },
315
- setLayout(t, layout, origin, bcChanged) {
317
+ setLayout(t, layout, origin, around, bcChanged) {
316
318
  const { x, y, scaleX, scaleY } = layout;
317
319
  if (bcChanged === undefined)
318
320
  bcChanged = layout.rotation || layout.skewX || layout.skewY;
@@ -344,10 +346,10 @@ const MatrixHelper = {
344
346
  }
345
347
  t.e = x;
346
348
  t.f = y;
347
- if (origin)
348
- M$9.translateInner(t, -origin.x, -origin.y, true);
349
+ if (origin = origin || around)
350
+ M$9.translateInner(t, -origin.x, -origin.y, !around);
349
351
  },
350
- getLayout(t, origin, firstSkewY) {
352
+ getLayout(t, origin, around, firstSkewY) {
351
353
  const { a, b, c, d, e, f } = t;
352
354
  let x = e, y = f, scaleX, scaleY, rotation, skewX, skewY;
353
355
  if (b || c) {
@@ -376,9 +378,11 @@ const MatrixHelper = {
376
378
  scaleY = d;
377
379
  rotation = skewX = skewY = 0;
378
380
  }
379
- if (origin) {
381
+ if (origin = around || origin) {
380
382
  x += origin.x * a + origin.y * c;
381
383
  y += origin.x * b + origin.y * d;
384
+ if (!around)
385
+ x -= origin.x, y -= origin.y;
382
386
  }
383
387
  return { x, y, scaleX, scaleY, rotation, skewX, skewY };
384
388
  },
@@ -706,12 +710,12 @@ class Matrix {
706
710
  toInnerPoint(outer, to, distance) {
707
711
  MatrixHelper.toInnerPoint(this, outer, to, distance);
708
712
  }
709
- setLayout(data, origin) {
710
- MatrixHelper.setLayout(this, data, origin);
713
+ setLayout(data, origin, around) {
714
+ MatrixHelper.setLayout(this, data, origin, around);
711
715
  return this;
712
716
  }
713
- getLayout(origin, firstSkewY) {
714
- return MatrixHelper.getLayout(this, origin, firstSkewY);
717
+ getLayout(origin, around, firstSkewY) {
718
+ return MatrixHelper.getLayout(this, origin, around, firstSkewY);
715
719
  }
716
720
  withScale(scaleX, scaleY) {
717
721
  return MatrixHelper.withScale(this, scaleX, scaleY);
@@ -1999,7 +2003,7 @@ class LeaferCanvasBase extends Canvas$1 {
1999
2003
  DataHelper.copyAttrs(this.size, size, canvasSizeAttrs);
2000
2004
  this.size.pixelRatio || (this.size.pixelRatio = 1);
2001
2005
  this.bounds = new Bounds(0, 0, this.width, this.height);
2002
- if (!this.unreal) {
2006
+ if (this.context && !this.unreal) {
2003
2007
  this.updateViewSize();
2004
2008
  this.smooth = this.config.smooth;
2005
2009
  }
@@ -2172,7 +2176,7 @@ class LeaferCanvasBase extends Canvas$1 {
2172
2176
  this.manager ? this.manager.recycle(this) : this.destroy();
2173
2177
  }
2174
2178
  }
2175
- updateRender() { }
2179
+ updateRender(_bounds) { }
2176
2180
  unrealCanvas() { }
2177
2181
  destroy() {
2178
2182
  this.manager = this.view = this.parentView = null;
@@ -4066,8 +4070,13 @@ const LeafHelper = {
4066
4070
  zoomOfLocal(t, origin, scaleX, scaleY = scaleX, resize) {
4067
4071
  copy$a(matrix$3, t.__localMatrix);
4068
4072
  scaleOfOuter$2(matrix$3, origin, scaleX, scaleY);
4069
- moveByMatrix(t, matrix$3);
4070
- t.scaleResize(scaleX, scaleY, resize !== true);
4073
+ if (t.origin || t.around) {
4074
+ L$3.setTransform(t, matrix$3, resize);
4075
+ }
4076
+ else {
4077
+ moveByMatrix(t, matrix$3);
4078
+ t.scaleResize(scaleX, scaleY, resize !== true);
4079
+ }
4071
4080
  },
4072
4081
  rotateOfWorld(t, origin, angle) {
4073
4082
  L$3.rotateOfLocal(t, getTempLocal(t, origin), angle);
@@ -4075,8 +4084,13 @@ const LeafHelper = {
4075
4084
  rotateOfLocal(t, origin, angle) {
4076
4085
  copy$a(matrix$3, t.__localMatrix);
4077
4086
  rotateOfOuter$2(matrix$3, origin, angle);
4078
- moveByMatrix(t, matrix$3);
4079
- t.rotation = MathHelper.formatRotation(t.rotation + angle);
4087
+ if (t.origin || t.around) {
4088
+ L$3.setTransform(t, matrix$3);
4089
+ }
4090
+ else {
4091
+ moveByMatrix(t, matrix$3);
4092
+ t.rotation = MathHelper.formatRotation(t.rotation + angle);
4093
+ }
4080
4094
  },
4081
4095
  skewOfWorld(t, origin, skewX, skewY, resize) {
4082
4096
  L$3.skewOfLocal(t, getTempLocal(t, origin), skewX, skewY, resize);
@@ -4099,7 +4113,7 @@ const LeafHelper = {
4099
4113
  L$3.setTransform(t, matrix$3, resize);
4100
4114
  },
4101
4115
  setTransform(t, transform, resize) {
4102
- const layout = getLayout(transform);
4116
+ const layout = getLayout(transform, t.origin && L$3.getInnerOrigin(t, t.origin), t.around && L$3.getInnerOrigin(t, t.around));
4103
4117
  if (resize) {
4104
4118
  const scaleX = layout.scaleX / t.scaleX;
4105
4119
  const scaleY = layout.scaleY / t.scaleY;
@@ -4112,13 +4126,19 @@ const LeafHelper = {
4112
4126
  t.set(layout);
4113
4127
  }
4114
4128
  },
4129
+ getFlipTransform(t, axis) {
4130
+ const m = getMatrixData();
4131
+ const sign = axis === 'x' ? 1 : -1;
4132
+ scaleOfOuter$2(m, L$3.getLocalOrigin(t, 'center'), -1 * sign, 1 * sign);
4133
+ return m;
4134
+ },
4115
4135
  getLocalOrigin(t, origin) {
4116
4136
  return PointHelper.tempToOuterOf(L$3.getInnerOrigin(t, origin), t.localTransform);
4117
4137
  },
4118
4138
  getInnerOrigin(t, origin) {
4119
- if (typeof origin === 'string')
4120
- AroundHelper.toPoint(origin, t.boxBounds, origin = {});
4121
- return origin;
4139
+ const innerOrigin = {};
4140
+ AroundHelper.toPoint(origin, t.boxBounds, innerOrigin);
4141
+ return innerOrigin;
4122
4142
  },
4123
4143
  getRelativeWorld(t, relative, temp) {
4124
4144
  copy$a(matrix$3, t.worldTransform);
@@ -4545,7 +4565,10 @@ const LeafEventer = {
4545
4565
  on(type, listener, options) {
4546
4566
  let capture, once;
4547
4567
  if (options) {
4548
- if (typeof options === 'boolean') {
4568
+ if (options === 'once') {
4569
+ once = true;
4570
+ }
4571
+ else if (typeof options === 'boolean') {
4549
4572
  capture = options;
4550
4573
  }
4551
4574
  else {
@@ -4576,7 +4599,7 @@ const LeafEventer = {
4576
4599
  if (listener) {
4577
4600
  let capture;
4578
4601
  if (options)
4579
- capture = typeof options === 'boolean' ? options : options.capture;
4602
+ capture = typeof options === 'boolean' ? options : (options === 'once' ? false : options.capture);
4580
4603
  let events, index;
4581
4604
  const map = __getListenerMap(this, capture);
4582
4605
  typeList.forEach(type => {
@@ -4878,7 +4901,7 @@ const LeafMatrix = {
4878
4901
  const layout = this.__layout, local = this.__local, data = this.__;
4879
4902
  if (layout.affectScaleOrRotation) {
4880
4903
  if (layout.scaleChanged || layout.rotationChanged) {
4881
- setLayout(local, data, null, layout.affectRotation);
4904
+ setLayout(local, data, null, null, layout.affectRotation);
4882
4905
  layout.scaleChanged = layout.rotationChanged = false;
4883
4906
  }
4884
4907
  }
@@ -4886,7 +4909,7 @@ const LeafMatrix = {
4886
4909
  local.f = data.y + data.offsetY;
4887
4910
  if (data.around || data.origin) {
4888
4911
  toPoint$4(data.around || data.origin, layout.boxBounds, tempPoint$1);
4889
- translateInner(local, -tempPoint$1.x, -tempPoint$1.y, data.origin);
4912
+ translateInner(local, -tempPoint$1.x, -tempPoint$1.y, !data.around);
4890
4913
  }
4891
4914
  }
4892
4915
  this.__layout.matrixChanged = false;
@@ -5115,7 +5138,7 @@ const { LEAF, create } = IncrementId;
5115
5138
  const { toInnerPoint, toOuterPoint, multiplyParent } = MatrixHelper;
5116
5139
  const { toOuterOf } = BoundsHelper;
5117
5140
  const { copy: copy$7 } = PointHelper;
5118
- const { moveLocal, zoomOfLocal, rotateOfLocal, skewOfLocal, moveWorld, zoomOfWorld, rotateOfWorld, skewOfWorld, transform, transformWorld, setTransform, getLocalOrigin, getRelativeWorld, drop } = LeafHelper;
5141
+ const { moveLocal, zoomOfLocal, rotateOfLocal, skewOfLocal, moveWorld, zoomOfWorld, rotateOfWorld, skewOfWorld, transform, transformWorld, setTransform, getFlipTransform, getLocalOrigin, getRelativeWorld, drop } = LeafHelper;
5119
5142
  let Leaf = class Leaf {
5120
5143
  get tag() { return this.__tag; }
5121
5144
  set tag(_value) { }
@@ -5141,6 +5164,8 @@ let Leaf = class Leaf {
5141
5164
  get __ignoreHitWorld() { return (this.__hasMask || this.__hasEraser) && this.__.hitChildren; }
5142
5165
  get __inLazyBounds() { const { leafer } = this; return leafer && leafer.created && leafer.lazyBounds.hit(this.__world); }
5143
5166
  get pathInputed() { return this.__.__pathInputed; }
5167
+ set event(map) { let event; for (let key in map)
5168
+ event = map[key], event instanceof Array ? this.on(key, event[0], event[1]) : this.on(key, event); }
5144
5169
  constructor(data) {
5145
5170
  this.innerId = create(LEAF);
5146
5171
  this.reset(data);
@@ -5400,6 +5425,9 @@ let Leaf = class Leaf {
5400
5425
  skewOfWorld(worldOrigin, skewX, skewY, resize) {
5401
5426
  skewOfWorld(this, worldOrigin, skewX, skewY, resize);
5402
5427
  }
5428
+ flip(axis) {
5429
+ transform(this, getFlipTransform(this, axis));
5430
+ }
5403
5431
  scaleResize(scaleX, scaleY = scaleX, _noResize) {
5404
5432
  this.scaleX *= scaleX;
5405
5433
  this.scaleY *= scaleY;
@@ -5757,7 +5785,7 @@ class LeafLevelList {
5757
5785
  }
5758
5786
  }
5759
5787
 
5760
- const version = "1.0.0-rc.30";
5788
+ const version = "1.0.1";
5761
5789
  const inviteCode = {};
5762
5790
 
5763
5791
  class LeaferCanvas extends LeaferCanvasBase {
@@ -5827,7 +5855,7 @@ function useCanvas(_canvasType, _power) {
5827
5855
  Platform.name = 'web';
5828
5856
  Platform.isWorker = true;
5829
5857
  Platform.requestRender = function (render) { requestAnimationFrame(render); };
5830
- Platform.devicePixelRatio = 1;
5858
+ defineKey(Platform, 'devicePixelRatio', { get() { return 1; } });
5831
5859
  const { userAgent } = navigator;
5832
5860
  if (userAgent.indexOf("Firefox") > -1) {
5833
5861
  Platform.conicGradientRotate90 = true;
@@ -6323,14 +6351,14 @@ class Renderer {
6323
6351
  if (Debug.showRepaint)
6324
6352
  this.canvas.strokeWorld(bounds, 'red');
6325
6353
  this.target.__render(this.canvas, options);
6326
- this.renderBounds = realBounds || bounds;
6354
+ this.renderBounds = realBounds = realBounds || bounds;
6327
6355
  this.renderOptions = options;
6328
- this.totalBounds.isEmpty() ? this.totalBounds = this.renderBounds : this.totalBounds.add(this.renderBounds);
6356
+ this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
6329
6357
  if (Debug.showHitView)
6330
6358
  this.renderHitView(options);
6331
6359
  if (Debug.showBoundsView)
6332
6360
  this.renderBoundsView(options);
6333
- this.canvas.updateRender();
6361
+ this.canvas.updateRender(realBounds);
6334
6362
  }
6335
6363
  renderHitView(_options) { }
6336
6364
  renderBoundsView(_options) { }
@@ -7652,7 +7680,7 @@ let Leafer = Leafer_1 = class Leafer extends Group {
7652
7680
  this.__controllers.push(this.renderer = Creator.renderer(this, canvas, config), this.watcher = Creator.watcher(this, config), this.layouter = Creator.layouter(this, config));
7653
7681
  if (this.isApp)
7654
7682
  this.__setApp();
7655
- this.__checkAutoLayout(config);
7683
+ this.__checkAutoLayout(config, parentApp);
7656
7684
  this.view = canvas.view;
7657
7685
  if (parentApp) {
7658
7686
  this.__bindApp(parentApp);
@@ -7753,9 +7781,10 @@ let Leafer = Leafer_1 = class Leafer extends Group {
7753
7781
  this.leafer = leafer;
7754
7782
  this.__level = 1;
7755
7783
  }
7756
- __checkAutoLayout(config) {
7757
- if (!config.width || !config.height) {
7758
- this.autoLayout = new AutoBounds(config);
7784
+ __checkAutoLayout(config, parentApp) {
7785
+ if (!parentApp) {
7786
+ if (!config.width || !config.height)
7787
+ this.autoLayout = new AutoBounds(config);
7759
7788
  this.canvas.startAutoLayout(this.autoLayout, this.__onResize.bind(this));
7760
7789
  }
7761
7790
  }
@@ -7890,7 +7919,9 @@ let Leafer = Leafer_1 = class Leafer extends Group {
7890
7919
  list.push(item);
7891
7920
  }
7892
7921
  }
7893
- zoom(_zoomType, _padding, _fixedScale) { return undefined; }
7922
+ zoom(_zoomType, _padding, _fixedScale) {
7923
+ return debug$4.error('need @leafer-in/view');
7924
+ }
7894
7925
  getValidMove(moveX, moveY) { return { x: moveX, y: moveY }; }
7895
7926
  getValidScale(changeScale) { return changeScale; }
7896
7927
  getWorldPointByClient(clientPoint, updateClient) {
@@ -8417,8 +8448,7 @@ let Canvas = class Canvas extends Rect {
8417
8448
  destroy() {
8418
8449
  if (this.canvas) {
8419
8450
  this.canvas.destroy();
8420
- this.canvas = null;
8421
- this.context = null;
8451
+ this.canvas = this.context = null;
8422
8452
  }
8423
8453
  super.destroy();
8424
8454
  }
@@ -8771,11 +8801,13 @@ let App = class App extends Leafer {
8771
8801
  this.renderer.update();
8772
8802
  }
8773
8803
  __render(canvas, options) {
8774
- if (options.matrix) {
8775
- const { a, b, c, d, e, f } = options.matrix;
8776
- canvas.setTransform(a, b, c, d, e, f);
8804
+ if (canvas.context) {
8805
+ if (options.matrix) {
8806
+ const { a, b, c, d, e, f } = options.matrix;
8807
+ canvas.setTransform(a, b, c, d, e, f);
8808
+ }
8809
+ this.children.forEach(leafer => canvas.copyWorld(leafer.canvas));
8777
8810
  }
8778
- this.children.forEach(leafer => canvas.copyWorld(leafer.canvas));
8779
8811
  }
8780
8812
  __onResize(event) {
8781
8813
  this.children.forEach(leafer => leafer.resize(event));
@@ -9142,11 +9174,14 @@ leafer.getValidScale = function (changeScale) {
9142
9174
  };
9143
9175
 
9144
9176
  class Transformer {
9177
+ get transforming() { return !!(this.moveData || this.zoomData || this.rotateData); }
9145
9178
  constructor(interaction) {
9146
9179
  this.interaction = interaction;
9147
9180
  }
9148
9181
  move(data) {
9149
9182
  const { interaction } = this;
9183
+ if (!data.moveType)
9184
+ data.moveType = 'move';
9150
9185
  if (!this.moveData) {
9151
9186
  const { path } = interaction.selector.getByPoint(data, interaction.hitRadius);
9152
9187
  data.path = path;
@@ -9311,8 +9346,10 @@ class Dragger {
9311
9346
  return;
9312
9347
  }
9313
9348
  if (!this.moving && canDrag) {
9314
- if (this.moving = interaction.canMove(this.downData) || interaction.isHoldRightKey || interaction.isMobileDragEmpty)
9349
+ if (this.moving = interaction.canMove(this.downData) || interaction.isHoldRightKey || interaction.isMobileDragEmpty) {
9350
+ this.dragData.moveType = 'drag';
9315
9351
  interaction.emit(MoveEvent.START, this.dragData);
9352
+ }
9316
9353
  }
9317
9354
  if (!this.moving) {
9318
9355
  this.dragStart(data, canDrag);
@@ -9351,6 +9388,7 @@ class Dragger {
9351
9388
  this.dragData.throughPath = throughPath;
9352
9389
  this.dragData.path = path;
9353
9390
  if (this.moving) {
9391
+ this.dragData.moveType = 'drag';
9354
9392
  interaction.emit(MoveEvent.BEFORE_MOVE, this.dragData);
9355
9393
  interaction.emit(MoveEvent.MOVE, this.dragData);
9356
9394
  }
@@ -9417,6 +9455,7 @@ class Dragger {
9417
9455
  endDragData.path = path;
9418
9456
  if (this.moving) {
9419
9457
  this.moving = false;
9458
+ endDragData.moveType = 'drag';
9420
9459
  interaction.emit(MoveEvent.END, endDragData);
9421
9460
  }
9422
9461
  if (this.dragging) {
@@ -9475,7 +9514,7 @@ class Dragger {
9475
9514
  totalY += moveY;
9476
9515
  PointHelper.move(downData, moveX, moveY);
9477
9516
  PointHelper.move(this.dragData, moveX, moveY);
9478
- interaction.move(Object.assign(Object.assign({}, data), { moveX, moveY, totalX, totalY }));
9517
+ interaction.move(Object.assign(Object.assign({}, data), { moveX, moveY, totalX, totalY, moveType: 'drag' }));
9479
9518
  interaction.pointerMoveReal(data);
9480
9519
  }, 10);
9481
9520
  }
@@ -9595,9 +9634,11 @@ const config$1 = {
9595
9634
  const { pathHasEventType, getMoveEventData, getZoomEventData, getRotateEventData } = InteractionHelper;
9596
9635
  class InteractionBase {
9597
9636
  get dragging() { return this.dragger.dragging; }
9637
+ get transforming() { return this.transformer.transforming; }
9598
9638
  get moveMode() { return this.config.move.drag || this.isHoldSpaceKey || this.isHoldMiddleKey || (this.isHoldRightKey && this.dragger.moving) || this.isDragEmpty; }
9639
+ get canHover() { return this.config.pointer.hover && !this.config.mobile; }
9599
9640
  get isDragEmpty() { return this.config.move.dragEmpty && this.isRootPath(this.hoverData) && (!this.downData || this.isRootPath(this.downData)); }
9600
- get isMobileDragEmpty() { return this.config.move.dragEmpty && !this.config.pointer.hover && this.downData && this.isTreePath(this.downData); }
9641
+ get isMobileDragEmpty() { return this.config.move.dragEmpty && !this.canHover && this.downData && this.isTreePath(this.downData); }
9601
9642
  get isHoldMiddleKey() { return this.config.move.holdMiddleKey && this.downData && PointerButton.middle(this.downData); }
9602
9643
  get isHoldRightKey() { return this.config.move.holdRightKey && this.downData && PointerButton.right(this.downData); }
9603
9644
  get isHoldSpaceKey() { return this.config.move.holdSpaceKey && Keyboard.isHoldSpaceKey(); }
@@ -9690,6 +9731,7 @@ class InteractionBase {
9690
9731
  if (!downData)
9691
9732
  return;
9692
9733
  PointerButton.defaultLeft(data);
9734
+ data.multiTouch = downData.multiTouch;
9693
9735
  this.findPath(data);
9694
9736
  const upData = Object.assign(Object.assign({}, data), { path: data.path.clone() });
9695
9737
  data.path.addList(downData.path.list);
@@ -9762,7 +9804,7 @@ class InteractionBase {
9762
9804
  this.updateCursor();
9763
9805
  }
9764
9806
  pointerHover(data) {
9765
- if (this.config.pointer.hover) {
9807
+ if (this.canHover) {
9766
9808
  this.pointerOverOrOut(data);
9767
9809
  this.pointerEnterOrLeave(data);
9768
9810
  }
@@ -9899,7 +9941,7 @@ class InteractionBase {
9899
9941
  this.hoverData = data;
9900
9942
  }
9901
9943
  updateCursor(data) {
9902
- if (!this.config.cursor || !this.config.pointer.hover)
9944
+ if (!this.config.cursor || !this.canHover)
9903
9945
  return;
9904
9946
  if (!data) {
9905
9947
  this.updateHoverData();
@@ -10787,7 +10829,7 @@ function createPattern(ui, paint, pixelRatio) {
10787
10829
  const { abs: abs$1 } = Math;
10788
10830
  function checkImage(ui, canvas, paint, allowPaint) {
10789
10831
  const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
10790
- if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
10832
+ if (!paint.data || (paint.patternId === scaleX + '-' + scaleY && !Export.running)) {
10791
10833
  return false;
10792
10834
  }
10793
10835
  else {
@@ -11765,7 +11807,10 @@ const ExportModule = {
11765
11807
  const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
11766
11808
  let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
11767
11809
  const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
11810
+ let sliceLeaf;
11768
11811
  if (slice) {
11812
+ sliceLeaf = leaf;
11813
+ sliceLeaf.__worldOpacity = 0;
11769
11814
  leaf = leafer;
11770
11815
  renderOptions.bounds = canvas.bounds;
11771
11816
  }
@@ -11780,6 +11825,8 @@ const ExportModule = {
11780
11825
  leaf.__render(canvas, renderOptions);
11781
11826
  }
11782
11827
  canvas.restore();
11828
+ if (sliceLeaf)
11829
+ sliceLeaf.__updateWorldOpacity();
11783
11830
  if (trim) {
11784
11831
  trimBounds = getTrimBounds(canvas);
11785
11832
  const old = canvas, { width, height } = trimBounds;
@@ -12272,7 +12319,7 @@ class EditSelect extends Group {
12272
12319
  }
12273
12320
  onPointerMove(e) {
12274
12321
  const { app, editor } = this;
12275
- if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
12322
+ if (this.running && !this.isMoveMode && app.interaction.canHover && !app.interaction.dragging) {
12276
12323
  const find = this.findUI(e);
12277
12324
  editor.hoverTarget = editor.hasItem(find) ? null : find;
12278
12325
  }
@@ -12281,15 +12328,27 @@ class EditSelect extends Group {
12281
12328
  }
12282
12329
  }
12283
12330
  onBeforeDown(e) {
12331
+ if (e.multiTouch)
12332
+ return;
12284
12333
  const { select } = this.editor.mergeConfig;
12285
- if (select === 'press')
12286
- this.checkAndSelect(e);
12334
+ if (select === 'press') {
12335
+ if (this.app.config.mobile) {
12336
+ this.waitSelect = () => this.checkAndSelect(e);
12337
+ }
12338
+ else {
12339
+ this.checkAndSelect(e);
12340
+ }
12341
+ }
12287
12342
  }
12288
12343
  onTap(e) {
12344
+ if (e.multiTouch)
12345
+ return;
12289
12346
  const { editor } = this;
12290
12347
  const { select } = editor.mergeConfig;
12291
12348
  if (select === 'tap')
12292
12349
  this.checkAndSelect(e);
12350
+ else if (this.waitSelect)
12351
+ this.waitSelect();
12293
12352
  if (this.needRemoveItem) {
12294
12353
  editor.removeItem(this.needRemoveItem);
12295
12354
  }
@@ -12320,6 +12379,10 @@ class EditSelect extends Group {
12320
12379
  }
12321
12380
  }
12322
12381
  onDragStart(e) {
12382
+ if (e.multiTouch)
12383
+ return;
12384
+ if (this.waitSelect)
12385
+ this.waitSelect();
12323
12386
  if (this.allowDrag(e)) {
12324
12387
  const { editor } = this;
12325
12388
  const { stroke, area } = editor.mergeConfig;
@@ -12331,10 +12394,10 @@ class EditSelect extends Group {
12331
12394
  }
12332
12395
  }
12333
12396
  onDrag(e) {
12334
- if (this.editor.dragging) {
12335
- this.onDragEnd();
12397
+ if (e.multiTouch)
12336
12398
  return;
12337
- }
12399
+ if (this.editor.dragging)
12400
+ return this.onDragEnd(e);
12338
12401
  if (this.dragging) {
12339
12402
  const { editor } = this;
12340
12403
  const total = e.getInnerTotal(this);
@@ -12358,7 +12421,9 @@ class EditSelect extends Group {
12358
12421
  }
12359
12422
  }
12360
12423
  }
12361
- onDragEnd() {
12424
+ onDragEnd(e) {
12425
+ if (e.multiTouch)
12426
+ return;
12362
12427
  if (this.dragging)
12363
12428
  this.originList = null, this.selectArea.visible = false;
12364
12429
  }
@@ -12404,7 +12469,7 @@ class EditSelect extends Group {
12404
12469
  app.on_(PointerEvent.MOVE, this.onPointerMove, this),
12405
12470
  app.on_(PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
12406
12471
  app.on_(PointerEvent.TAP, this.onTap, this),
12407
- app.on_(DragEvent.START, this.onDragStart, this),
12472
+ app.on_(DragEvent.START, this.onDragStart, this, true),
12408
12473
  app.on_(DragEvent.DRAG, this.onDrag, this),
12409
12474
  app.on_(DragEvent.END, this.onDragEnd, this),
12410
12475
  app.on_(MoveEvent.MOVE, this.onAutoMove, this),
@@ -12427,22 +12492,32 @@ class EditSelect extends Group {
12427
12492
 
12428
12493
  const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = Direction9;
12429
12494
  const { toPoint } = AroundHelper;
12495
+ const { within } = MathHelper;
12430
12496
  const EditDataHelper = {
12431
- getScaleData(bounds, direction, pointMove, lockRatio, around) {
12497
+ getScaleData(element, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
12432
12498
  let align, origin = {}, scaleX = 1, scaleY = 1;
12433
- const { width, height } = bounds;
12499
+ const { boxBounds, widthRange, heightRange } = element;
12500
+ const { width, height } = startBounds;
12434
12501
  if (around) {
12435
- pointMove.x *= 2;
12436
- pointMove.y *= 2;
12437
- }
12438
- if (Math.abs(pointMove.x) === width)
12439
- pointMove.x += 0.1;
12440
- if (Math.abs(pointMove.y) === height)
12441
- pointMove.y += 0.1;
12442
- const topScale = (-pointMove.y + height) / height;
12443
- const rightScale = (pointMove.x + width) / width;
12444
- const bottomScale = (pointMove.y + height) / height;
12445
- const leftScale = (-pointMove.x + width) / width;
12502
+ totalMove.x *= 2;
12503
+ totalMove.y *= 2;
12504
+ }
12505
+ const originChangedScaleX = element.scaleX / startBounds.scaleX;
12506
+ const originChangedScaleY = element.scaleY / startBounds.scaleY;
12507
+ const signX = originChangedScaleX < 0 ? -1 : 1;
12508
+ const signY = originChangedScaleY < 0 ? -1 : 1;
12509
+ const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width;
12510
+ const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height;
12511
+ totalMove.x *= scaleMode ? originChangedScaleX : signX;
12512
+ totalMove.y *= scaleMode ? originChangedScaleY : signY;
12513
+ if (Math.abs(totalMove.x) === width)
12514
+ totalMove.x += 0.1;
12515
+ if (Math.abs(totalMove.y) === height)
12516
+ totalMove.y += 0.1;
12517
+ const topScale = (-totalMove.y + height) / height;
12518
+ const rightScale = (totalMove.x + width) / width;
12519
+ const bottomScale = (totalMove.y + height) / height;
12520
+ const leftScale = (-totalMove.x + width) / width;
12446
12521
  switch (direction) {
12447
12522
  case top:
12448
12523
  scaleY = topScale;
@@ -12488,7 +12563,24 @@ const EditDataHelper = {
12488
12563
  scaleY = scaleY < 0 ? -scale : scale;
12489
12564
  }
12490
12565
  }
12491
- toPoint(around || align, bounds, origin);
12566
+ scaleX /= changedScaleX;
12567
+ scaleY /= changedScaleY;
12568
+ if (!flipable) {
12569
+ const { worldTransform } = element;
12570
+ if (scaleX < 0)
12571
+ scaleX = 1 / boxBounds.width / worldTransform.scaleX;
12572
+ if (scaleY < 0)
12573
+ scaleY = 1 / boxBounds.height / worldTransform.scaleY;
12574
+ }
12575
+ if (widthRange) {
12576
+ const nowWidth = boxBounds.width * element.scaleX;
12577
+ scaleX = within(nowWidth * scaleX, widthRange) / nowWidth;
12578
+ }
12579
+ if (heightRange) {
12580
+ const nowHeight = boxBounds.height * element.scaleY;
12581
+ scaleY = within(nowHeight * scaleY, heightRange) / nowHeight;
12582
+ }
12583
+ toPoint(around || align, boxBounds, origin);
12492
12584
  return { origin, scaleX, scaleY, direction, lockRatio, around };
12493
12585
  },
12494
12586
  getRotateData(bounds, direction, current, last, around) {
@@ -12609,6 +12701,11 @@ function updateCursor(editor, e) {
12609
12701
  return;
12610
12702
  if (point.name === 'circle')
12611
12703
  return;
12704
+ if (point.pointType === 'button') {
12705
+ if (!point.cursor)
12706
+ point.cursor = 'pointer';
12707
+ return;
12708
+ }
12612
12709
  let { rotation } = editBox;
12613
12710
  const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
12614
12711
  const { pointType } = point, { flippedX, flippedY } = editBox;
@@ -12677,9 +12774,8 @@ class EditBox extends Group {
12677
12774
  resizePoints.push(resizePoint);
12678
12775
  this.listenPointEvents(resizePoint, 'resize', i);
12679
12776
  }
12680
- buttons.add(circle);
12681
12777
  this.listenPointEvents(circle, 'rotate', 2);
12682
- view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
12778
+ view.addMany(...rotatePoints, rect, circle, buttons, ...resizeLines, ...resizePoints);
12683
12779
  this.add(view);
12684
12780
  }
12685
12781
  load() {
@@ -12695,9 +12791,9 @@ class EditBox extends Group {
12695
12791
  if (!(i % 2))
12696
12792
  resizeP.rotation = (i / 2) * 90;
12697
12793
  }
12698
- circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]));
12794
+ circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]));
12699
12795
  rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
12700
- rect.hittable = !single && moveable;
12796
+ rect.hittable = !single && !!moveable;
12701
12797
  element.syncEventer = (single && moveable) ? rect : null;
12702
12798
  this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null;
12703
12799
  }
@@ -12706,7 +12802,7 @@ class EditBox extends Group {
12706
12802
  if (this.view.worldOpacity) {
12707
12803
  const { mergeConfig } = this.editor;
12708
12804
  const { width, height } = bounds;
12709
- const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
12805
+ const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this;
12710
12806
  const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
12711
12807
  const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
12712
12808
  const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
@@ -12736,19 +12832,25 @@ class EditBox extends Group {
12736
12832
  }
12737
12833
  }
12738
12834
  }
12739
- circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint;
12835
+ circle.visible = showPoints && rotateable && !!(mergeConfig.circle || mergeConfig.rotatePoint);
12836
+ if (circle.visible)
12837
+ this.layoutCircle(mergeConfig);
12740
12838
  if (rect.path)
12741
12839
  rect.path = null;
12742
12840
  rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
12743
- const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1);
12744
- this.buttons.visible = buttonVisible;
12745
- if (buttonVisible)
12746
- this.layoutButtons();
12841
+ buttons.visible = showPoints && buttons.children.length > 0;
12842
+ if (buttons.visible)
12843
+ this.layoutButtons(mergeConfig);
12747
12844
  }
12748
12845
  }
12749
- layoutButtons() {
12750
- const { buttons, resizePoints } = this;
12751
- const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig;
12846
+ layoutCircle(config) {
12847
+ const { circleDirection, circleMargin, buttonsMargin, buttonsDirection, middlePoint } = config;
12848
+ const direction = fourDirection.indexOf(circleDirection || ((this.buttons.children.length && buttonsDirection === 'bottom') ? 'top' : 'bottom'));
12849
+ this.setButtonPosition(this.circle, direction, circleMargin || buttonsMargin, !!middlePoint);
12850
+ }
12851
+ layoutButtons(config) {
12852
+ const { buttons } = this;
12853
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = config;
12752
12854
  const { flippedX, flippedY } = this;
12753
12855
  let index = fourDirection.indexOf(buttonsDirection);
12754
12856
  if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
@@ -12756,11 +12858,18 @@ class EditBox extends Group {
12756
12858
  index = (index + 2) % 4;
12757
12859
  }
12758
12860
  const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
12759
- const point = resizePoints[direction * 2 + 1];
12861
+ this.setButtonPosition(buttons, direction, buttonsMargin, !!middlePoint);
12862
+ if (buttonsFixed)
12863
+ buttons.rotation = (direction - index) * 90;
12864
+ buttons.scaleX = flippedX ? -1 : 1;
12865
+ buttons.scaleY = flippedY ? -1 : 1;
12866
+ }
12867
+ setButtonPosition(buttons, direction, buttonsMargin, useMiddlePoint) {
12868
+ const point = this.resizePoints[direction * 2 + 1];
12760
12869
  const useX = direction % 2;
12761
12870
  const sign = (!direction || direction === 3) ? -1 : 1;
12762
- const useWidth = index % 2;
12763
- const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
12871
+ const useWidth = direction % 2;
12872
+ const margin = (buttonsMargin + (useWidth ? ((useMiddlePoint ? point.width : 0) + buttons.boxBounds.width) : ((useMiddlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
12764
12873
  if (useX) {
12765
12874
  buttons.x = point.x + margin;
12766
12875
  buttons.y = point.y;
@@ -12769,11 +12878,6 @@ class EditBox extends Group {
12769
12878
  buttons.x = point.x;
12770
12879
  buttons.y = point.y + margin;
12771
12880
  }
12772
- if (buttonsFixed) {
12773
- buttons.rotation = (direction - index) * 90;
12774
- buttons.scaleX = flippedX ? -1 : 1;
12775
- buttons.scaleY = flippedY ? -1 : 1;
12776
- }
12777
12881
  }
12778
12882
  unload() {
12779
12883
  this.visible = false;
@@ -12800,12 +12904,15 @@ class EditBox extends Group {
12800
12904
  }
12801
12905
  onDragStart(e) {
12802
12906
  this.dragging = true;
12907
+ const { editor } = this;
12803
12908
  if (e.current.name === 'rect') {
12804
- const { editor } = this;
12805
12909
  this.moving = true;
12806
12910
  editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
12807
12911
  editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
12808
12912
  }
12913
+ else if (e.current.pointType === 'resize') {
12914
+ editor.dragStartBounds = Object.assign({}, editor.element.getLayoutBounds('box', 'local'));
12915
+ }
12809
12916
  }
12810
12917
  onDragEnd(e) {
12811
12918
  this.dragging = false;
@@ -12820,7 +12927,7 @@ class EditBox extends Group {
12820
12927
  if (editor.mergeConfig.rotateable)
12821
12928
  editor.onRotate(e);
12822
12929
  }
12823
- else {
12930
+ else if (point.pointType === 'resize') {
12824
12931
  editor.onScale(e);
12825
12932
  }
12826
12933
  updateCursor(editor, e);
@@ -12884,8 +12991,6 @@ class EditBox extends Group {
12884
12991
  rect.on_(DragEvent.START, this.onDragStart, this),
12885
12992
  rect.on_(DragEvent.DRAG, editor.onMove, editor),
12886
12993
  rect.on_(DragEvent.END, this.onDragEnd, this),
12887
- rect.on_(ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
12888
- rect.on_(RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
12889
12994
  rect.on_(PointerEvent.ENTER, () => updateMoveCursor(editor)),
12890
12995
  rect.on_(PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
12891
12996
  rect.on_(PointerEvent.LONG_PRESS, this.onLongPress, this)
@@ -12915,7 +13020,7 @@ class EditMask extends UI {
12915
13020
  const { rect } = editor.editBox;
12916
13021
  const { width, height } = rect.__;
12917
13022
  canvas.resetTransform();
12918
- canvas.fillWorld(canvas.bounds, mask);
13023
+ canvas.fillWorld(canvas.bounds, mask === true ? 'rgba(0,0,0,0.8)' : mask);
12919
13024
  canvas.setWorld(rect.__world, options.matrix);
12920
13025
  canvas.clearRect(0, 0, width, height);
12921
13026
  }
@@ -13000,6 +13105,7 @@ const config = {
13000
13105
  boxSelect: true,
13001
13106
  moveable: true,
13002
13107
  resizeable: true,
13108
+ flipable: true,
13003
13109
  rotateable: true,
13004
13110
  skewable: true
13005
13111
  };
@@ -13221,29 +13327,39 @@ class Editor extends Group {
13221
13327
  return this.mergeConfig.editSize;
13222
13328
  }
13223
13329
  onMove(e) {
13224
- const total = { x: e.totalX, y: e.totalY };
13225
- if (e.shiftKey) {
13226
- if (Math.abs(total.x) > Math.abs(total.y))
13227
- total.y = 0;
13228
- else
13229
- total.x = 0;
13330
+ if (e instanceof MoveEvent) {
13331
+ if (e.moveType !== 'drag') {
13332
+ const { moveable, resizeable } = this.mergeConfig;
13333
+ const move = e.getLocalMove(this.element);
13334
+ if (moveable === 'move')
13335
+ e.stop(), this.move(move.x, move.y);
13336
+ else if (resizeable === 'zoom')
13337
+ e.stop();
13338
+ }
13339
+ }
13340
+ else {
13341
+ const total = { x: e.totalX, y: e.totalY };
13342
+ if (e.shiftKey) {
13343
+ if (Math.abs(total.x) > Math.abs(total.y))
13344
+ total.y = 0;
13345
+ else
13346
+ total.x = 0;
13347
+ }
13348
+ this.move(DragEvent.getValidMove(this.element, this.dragStartPoint, total));
13230
13349
  }
13231
- this.move(DragEvent.getValidMove(this.element, this.dragStartPoint, total));
13232
13350
  }
13233
13351
  onScale(e) {
13234
13352
  const { element } = this;
13353
+ let { around, lockRatio, resizeable, flipable, editSize } = this.mergeConfig;
13235
13354
  if (e instanceof ZoomEvent) {
13236
- if (this.mergeConfig.resizeable === 'zoom') {
13237
- e.stop();
13238
- this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
13239
- }
13355
+ if (resizeable === 'zoom')
13356
+ e.stop(), this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
13240
13357
  }
13241
13358
  else {
13242
13359
  const { direction } = e.current;
13243
- let { around, lockRatio } = this.mergeConfig;
13244
13360
  if (e.shiftKey || element.lockRatio)
13245
13361
  lockRatio = true;
13246
- const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
13362
+ const data = EditDataHelper.getScaleData(element, this.dragStartBounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
13247
13363
  if (this.editTool.onScaleWithDrag) {
13248
13364
  data.drag = e;
13249
13365
  this.scaleWithDrag(data);
@@ -13254,23 +13370,21 @@ class Editor extends Group {
13254
13370
  }
13255
13371
  }
13256
13372
  onRotate(e) {
13257
- const { skewable, around, rotateGap } = this.mergeConfig;
13373
+ const { skewable, rotateable, around, rotateGap } = this.mergeConfig;
13258
13374
  const { direction, name } = e.current;
13259
13375
  if (skewable && name === 'resize-line')
13260
13376
  return this.onSkew(e);
13261
13377
  const { element } = this;
13262
13378
  let origin, rotation;
13263
13379
  if (e instanceof RotateEvent) {
13264
- if (this.mergeConfig.rotateable === 'rotate') {
13265
- e.stop();
13266
- rotation = e.rotation, origin = element.getInnerPoint(e);
13267
- }
13380
+ if (rotateable === 'rotate')
13381
+ e.stop(), rotation = e.rotation, origin = element.getInnerPoint(e);
13268
13382
  else
13269
13383
  return;
13270
13384
  }
13271
13385
  else {
13272
13386
  const last = { x: e.x - e.moveX, y: e.y - e.moveY };
13273
- const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
13387
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
13274
13388
  rotation = data.rotation;
13275
13389
  origin = data.origin;
13276
13390
  }
@@ -13304,8 +13418,7 @@ class Editor extends Group {
13304
13418
  if (!this.mergeConfig.resizeable || this.element.locked)
13305
13419
  return;
13306
13420
  const { element } = this;
13307
- const worldOrigin = element.getWorldPoint(data.origin);
13308
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
13421
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) }));
13309
13422
  this.editTool.onScaleWithDrag(event);
13310
13423
  this.emitEvent(event);
13311
13424
  }
@@ -13313,28 +13426,28 @@ class Editor extends Group {
13313
13426
  if (!this.mergeConfig.resizeable || this.element.locked)
13314
13427
  return;
13315
13428
  const { element } = this;
13316
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
13317
- let transform;
13318
- if (this.multiple) {
13319
- const oldMatrix = new Matrix(element.worldTransform);
13320
- element.scaleOf(origin, scaleX, scaleY);
13321
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
13322
- }
13429
+ const worldOrigin = this.getWorldOrigin(origin);
13430
+ const transform = this.multiple && this.getChangedTransform(() => element.scaleOf(origin, scaleX, scaleY));
13323
13431
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
13324
13432
  this.editTool.onScale(event);
13325
13433
  this.emitEvent(event);
13326
13434
  }
13435
+ flip(axis) {
13436
+ if (this.element.locked)
13437
+ return;
13438
+ const { element } = this;
13439
+ const worldOrigin = this.getWorldOrigin('center');
13440
+ const transform = this.multiple ? this.getChangedTransform(() => element.flip(axis)) : new Matrix(LeafHelper.getFlipTransform(element, axis));
13441
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform });
13442
+ this.editTool.onScale(event);
13443
+ this.emitEvent(event);
13444
+ }
13327
13445
  rotateOf(origin, rotation) {
13328
13446
  if (!this.mergeConfig.rotateable || this.element.locked)
13329
13447
  return;
13330
13448
  const { element } = this;
13331
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
13332
- let transform;
13333
- if (this.multiple) {
13334
- const oldMatrix = new Matrix(element.worldTransform);
13335
- element.rotateOf(origin, rotation);
13336
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
13337
- }
13449
+ const worldOrigin = this.getWorldOrigin(origin);
13450
+ const transform = this.multiple && this.getChangedTransform(() => element.rotateOf(origin, rotation));
13338
13451
  const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
13339
13452
  this.editTool.onRotate(event);
13340
13453
  this.emitEvent(event);
@@ -13343,19 +13456,21 @@ class Editor extends Group {
13343
13456
  if (!this.mergeConfig.skewable || this.element.locked)
13344
13457
  return;
13345
13458
  const { element } = this;
13346
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
13347
- let transform;
13348
- if (this.multiple) {
13349
- const oldMatrix = new Matrix(element.worldTransform);
13350
- element.skewOf(origin, skewX, skewY);
13351
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
13352
- }
13353
- const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
13354
- target: element, editor: this, skewX, skewY, transform, worldOrigin
13355
- });
13459
+ const worldOrigin = this.getWorldOrigin(origin);
13460
+ const transform = this.multiple && this.getChangedTransform(() => element.skewOf(origin, skewX, skewY));
13461
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, { target: element, editor: this, worldOrigin, skewX, skewY, transform });
13356
13462
  this.editTool.onSkew(event);
13357
13463
  this.emitEvent(event);
13358
13464
  }
13465
+ getWorldOrigin(origin) {
13466
+ return this.element.getWorldPoint(LeafHelper.getInnerOrigin(this.element, origin));
13467
+ }
13468
+ getChangedTransform(func) {
13469
+ const { element } = this;
13470
+ const oldMatrix = new Matrix(element.worldTransform);
13471
+ func();
13472
+ return new Matrix(element.worldTransform).divide(oldMatrix);
13473
+ }
13359
13474
  group(userGroup) {
13360
13475
  if (this.multiple) {
13361
13476
  this.target = EditorHelper.group(this.list, this.element, userGroup);
@@ -13466,6 +13581,9 @@ class Editor extends Group {
13466
13581
  if (!this.targetEventIds.length) {
13467
13582
  const { leafer } = this.list[0];
13468
13583
  this.targetEventIds = [
13584
+ this.app.on_(MoveEvent.BEFORE_MOVE, this.onMove, this, true),
13585
+ this.app.on_(ZoomEvent.BEFORE_ZOOM, this.onScale, this, true),
13586
+ this.app.on_(RotateEvent.BEFORE_ROTATE, this.onRotate, this, true),
13469
13587
  leafer.on_(RenderEvent.START, this.update, this),
13470
13588
  leafer.on_([KeyEvent.HOLD, KeyEvent.UP], (e) => { updateCursor(this, e); }),
13471
13589
  leafer.on_(KeyEvent.DOWN, this.editBox.onArrow, this.editBox)
@@ -14189,6 +14307,169 @@ function setPoint(data, point, startIndex) {
14189
14307
 
14190
14308
  Object.assign(PathArrow, PathArrowModule);
14191
14309
 
14310
+ const textCaseMap = {
14311
+ 'none': 'none',
14312
+ 'title': 'capitalize',
14313
+ 'upper': 'uppercase',
14314
+ 'lower': 'lowercase',
14315
+ 'small-caps': 'small-caps'
14316
+ };
14317
+ const verticalAlignMap = {
14318
+ 'top': 'flex-start',
14319
+ 'middle': 'center',
14320
+ 'bottom': 'flex-end'
14321
+ };
14322
+ function updateStyle(textDom, text, textScale) {
14323
+ const { style } = textDom;
14324
+ const { fill, padding, textWrap, textOverflow, textDecoration } = text;
14325
+ style.fontFamily = text.fontFamily;
14326
+ style.fontSize = text.fontSize * textScale + 'px';
14327
+ setFill(style, fill);
14328
+ style.fontStyle = text.italic ? 'italic' : 'normal';
14329
+ style.fontWeight = text.fontWeight;
14330
+ style.textDecoration = textDecoration === 'delete' ? 'line-through' : textDecoration;
14331
+ style.textTransform = textCaseMap[text.textCase];
14332
+ style.textAlign = text.textAlign;
14333
+ style.display = 'flex';
14334
+ style.flexDirection = 'column';
14335
+ style.justifyContent = verticalAlignMap[text.verticalAlign];
14336
+ style.lineHeight = (text.__.__lineHeight || 0) * textScale + 'px';
14337
+ style.letterSpacing = (text.__.__letterSpacing || 0) * textScale + 'px';
14338
+ if (textWrap === 'none') {
14339
+ style.whiteSpace = 'nowrap';
14340
+ }
14341
+ else if (textWrap === 'break') {
14342
+ style.wordBreak = 'break-all';
14343
+ }
14344
+ style.textIndent = (text.paraIndent || 0) * textScale + 'px';
14345
+ style.padding = padding instanceof Array ? padding.map(item => item * textScale + 'px').join(' ') : (padding || 0) * textScale + 'px';
14346
+ style.textOverflow = textOverflow === 'show' ? '' : (textOverflow === 'hide' ? 'clip' : textOverflow);
14347
+ }
14348
+ function setFill(style, fill) {
14349
+ let color = 'black';
14350
+ if (fill instanceof Array)
14351
+ fill = fill[0];
14352
+ if (typeof fill === 'object') {
14353
+ switch (fill.type) {
14354
+ case 'solid':
14355
+ color = ColorConvert.string(fill.color);
14356
+ break;
14357
+ case 'image':
14358
+ break;
14359
+ case 'linear':
14360
+ case 'radial':
14361
+ case 'angular':
14362
+ const stop = fill.stops[0];
14363
+ color = ColorConvert.string(typeof stop === 'string' ? stop : stop.color);
14364
+ break;
14365
+ default:
14366
+ if (fill.r !== undefined)
14367
+ color = ColorConvert.string(fill);
14368
+ }
14369
+ }
14370
+ else {
14371
+ color = fill;
14372
+ }
14373
+ style.color = color;
14374
+ }
14375
+
14376
+ let TextEditor = class TextEditor extends InnerEditor {
14377
+ constructor() {
14378
+ super(...arguments);
14379
+ this.config = {
14380
+ selectAll: true
14381
+ };
14382
+ this.eventIds = [];
14383
+ }
14384
+ get tag() { return 'TextEditor'; }
14385
+ onLoad() {
14386
+ const { editor } = this;
14387
+ const { config } = editor.app;
14388
+ this._keyEvent = config.keyEvent;
14389
+ config.keyEvent = false;
14390
+ const text = this.editTarget;
14391
+ text.visible = false;
14392
+ const div = this.editDom = document.createElement('div');
14393
+ const { style } = div;
14394
+ div.contentEditable = 'true';
14395
+ div.innerText = text.text;
14396
+ style.position = 'fixed';
14397
+ style.transformOrigin = 'left top';
14398
+ style.boxSizing = 'border-box';
14399
+ const { scaleX, scaleY } = text.worldTransform;
14400
+ this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
14401
+ const fontSize = text.fontSize * this.textScale;
14402
+ if (fontSize < 12)
14403
+ this.textScale *= 12 / fontSize;
14404
+ editor.app.view.appendChild(div);
14405
+ this.eventIds = [
14406
+ editor.app.on_(PointerEvent.DOWN, (e) => { if (e.origin.target !== div)
14407
+ editor.closeInnerEditor(); })
14408
+ ];
14409
+ this.onFocus = this.onFocus.bind(this);
14410
+ this.onInput = this.onInput.bind(this);
14411
+ this.onUpdate = this.onUpdate.bind(this);
14412
+ this.onEscape = this.onEscape.bind(this);
14413
+ div.addEventListener("focus", this.onFocus);
14414
+ div.addEventListener("input", this.onInput);
14415
+ window.addEventListener('keydown', this.onEscape);
14416
+ window.addEventListener('scroll', this.onUpdate);
14417
+ const selection = window.getSelection();
14418
+ const range = document.createRange();
14419
+ if (this.config.selectAll) {
14420
+ range.selectNodeContents(div);
14421
+ }
14422
+ else {
14423
+ const node = div.childNodes[0];
14424
+ range.setStartAfter(node);
14425
+ range.setEndAfter(node);
14426
+ range.collapse(true);
14427
+ }
14428
+ selection.removeAllRanges();
14429
+ selection.addRange(range);
14430
+ }
14431
+ onInput() {
14432
+ this.editTarget.text = this.editDom.innerText.replace(/\n\n/, '\n');
14433
+ }
14434
+ onFocus() {
14435
+ this.editDom.style.outline = 'none';
14436
+ }
14437
+ onEscape(e) {
14438
+ if (e.code === 'Escape')
14439
+ this.editor.closeInnerEditor();
14440
+ }
14441
+ onUpdate() {
14442
+ const { editTarget: text, textScale } = this;
14443
+ const { style } = this.editDom;
14444
+ const { x, y } = text.app.tree.clientBounds;
14445
+ const { a, b, c, d, e, f } = new Matrix(text.worldTransform).scale(1 / textScale);
14446
+ style.transform = `matrix(${a},${b},${c},${d},${e},${f})`;
14447
+ style.left = x - window.scrollX + 'px';
14448
+ style.top = y - window.scrollY + 'px';
14449
+ style.width = text.width * textScale + (text.__.__autoWidth ? 20 : 0) + 'px';
14450
+ style.height = text.height * textScale + (text.__.__autoHeight ? 20 : 0) + 'px';
14451
+ updateStyle(this.editDom, text, this.textScale);
14452
+ }
14453
+ onUnload() {
14454
+ const { editTarget: text, editor, editDom: dom } = this;
14455
+ if (text) {
14456
+ this.onInput();
14457
+ text.visible = true;
14458
+ editor.app.config.keyEvent = this._keyEvent;
14459
+ editor.off_(this.eventIds);
14460
+ dom.removeEventListener("focus", this.onFocus);
14461
+ dom.removeEventListener("input", this.onInput);
14462
+ window.removeEventListener('keydown', this.onEscape);
14463
+ window.removeEventListener('scroll', this.onUpdate);
14464
+ dom.remove();
14465
+ this.editDom = this.eventIds = undefined;
14466
+ }
14467
+ }
14468
+ };
14469
+ TextEditor = __decorate([
14470
+ registerInnerEditor()
14471
+ ], TextEditor);
14472
+
14192
14473
  class HTMLTextData extends ImageData {
14193
14474
  setText(value) {
14194
14475
  this._text = value;
@@ -14243,4 +14524,4 @@ HTMLText = __decorate([
14243
14524
  registerUI()
14244
14525
  ], HTMLText);
14245
14526
 
14246
- export { AlignHelper, AnimateEvent, Answer, App, AroundHelper, Arrow, ArrowData, AutoBounds, BezierHelper, Bounds, BoundsHelper, Box, BoxData, Branch, BranchHelper, BranchRender, Canvas, CanvasData, CanvasManager, ChildEvent, ColorConvert, Creator, Cursor, DataHelper, Debug, Direction4, Direction9, DragEvent, DropEvent, EditBox, EditDataHelper, EditPoint, EditSelect, EditSelectHelper, EditTool, EditToolCreator, Editor, EditorEvent, EditorGroupEvent, EditorHelper, EditorMoveEvent, EditorRotateEvent, EditorScaleEvent, EditorSkewEvent, Effect, Ellipse, EllipseData, EllipseHelper, Event, EventCreator, Export, FileHelper, Frame, FrameData, Group, GroupData, HTMLText, HTMLTextData, HitCanvasManager, Image, ImageData, ImageEvent, ImageManager, IncrementId, InnerEditor, InnerEditorEvent, InteractionBase, InteractionHelper, KeyEvent, Keyboard, LayoutEvent, Layouter, Leaf, LeafBounds, LeafBoundsHelper, LeafData, LeafDataProxy, LeafEventer, LeafHelper, LeafLayout, LeafLevelList, LeafList, LeafMatrix, LeafRender, Leafer, LeaferCanvas, LeaferCanvasBase, LeaferData, LeaferEvent, LeaferImage, LeaferTypeCreator, Line, LineData, LineEditTool, MathHelper, Matrix, MatrixHelper, MoveEvent, MultiTouchHelper, NeedConvertToCanvasCommandMap, OneRadian, PI2, PI_2, Paint, PaintGradient, PaintImage, Path, PathArrow, PathArrowModule, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathData, PathDrawer, PathHelper, PathMatrixHelper, PathNumberCommandLengthMap, PathNumberCommandMap, PathScaler, Pen, PenData, Platform, Point, PointHelper, PointerButton, PointerEvent, Polygon, PolygonData, PropertyEvent, Rect, RectData, RectHelper, RectRender, RenderEvent, Renderer, ResizeEvent, RotateEvent, Run, ScrollBar, SelectArea, Selector, Star, StarData, State, StringNumberMap, Stroker, SwipeEvent, TaskItem, TaskProcessor, Text, TextConvert, TextData, TwoPointBoundsHelper, UI, UIBounds, UICreator, UIData, UIEvent, UIRender, UnitConvert, WaitHelper, WatchEvent, Watcher, ZoomEvent, addInteractionWindow, affectRenderBoundsType, affectStrokeBoundsType, arrowType, attr, autoLayoutType, boundsType, canvasPatch, canvasSizeAttrs, cursorType, dataProcessor, dataType, decorateLeafAttr, defineDataProcessor, defineKey, defineLeafAttr, doBoundsType, doStrokeType, effectType, emptyData, eraserType, getBoundsData, getDescriptor, getMatrixData, getPointData, hitType, inviteCode, layoutProcessor, maskType, naturalBoundsType, opacityType, pathInputType, pathType, pen, positionType, registerEditTool, registerInnerEditor, registerUI, registerUIEvent, resizeType, rewrite, rewriteAble, rotationType, scaleResize, scaleResizeFontSize, scaleResizeGroup, scaleResizePath, scaleResizePoints, scaleType, sortType, stateType, strokeType, surfaceType, tempBounds$1 as tempBounds, tempMatrix, tempPoint$3 as tempPoint, useCanvas, useModule, version, visibleType, zoomLayerType };
14527
+ export { AlignHelper, AnimateEvent, Answer, App, AroundHelper, Arrow, ArrowData, AutoBounds, BezierHelper, Bounds, BoundsHelper, Box, BoxData, Branch, BranchHelper, BranchRender, Canvas, CanvasData, CanvasManager, ChildEvent, ColorConvert, Creator, Cursor, DataHelper, Debug, Direction4, Direction9, DragEvent, DropEvent, EditBox, EditDataHelper, EditPoint, EditSelect, EditSelectHelper, EditTool, EditToolCreator, Editor, EditorEvent, EditorGroupEvent, EditorHelper, EditorMoveEvent, EditorRotateEvent, EditorScaleEvent, EditorSkewEvent, Effect, Ellipse, EllipseData, EllipseHelper, Event, EventCreator, Export, FileHelper, Frame, FrameData, Group, GroupData, HTMLText, HTMLTextData, HitCanvasManager, Image, ImageData, ImageEvent, ImageManager, IncrementId, InnerEditor, InnerEditorEvent, InteractionBase, InteractionHelper, KeyEvent, Keyboard, LayoutEvent, Layouter, Leaf, LeafBounds, LeafBoundsHelper, LeafData, LeafDataProxy, LeafEventer, LeafHelper, LeafLayout, LeafLevelList, LeafList, LeafMatrix, LeafRender, Leafer, LeaferCanvas, LeaferCanvasBase, LeaferData, LeaferEvent, LeaferImage, LeaferTypeCreator, Line, LineData, LineEditTool, MathHelper, Matrix, MatrixHelper, MoveEvent, MultiTouchHelper, NeedConvertToCanvasCommandMap, OneRadian, PI2, PI_2, Paint, PaintGradient, PaintImage, Path, PathArrow, PathArrowModule, PathBounds, PathCommandDataHelper, PathCommandMap, PathConvert, PathCorner, PathCreator, PathData, PathDrawer, PathHelper, PathMatrixHelper, PathNumberCommandLengthMap, PathNumberCommandMap, PathScaler, Pen, PenData, Platform, Point, PointHelper, PointerButton, PointerEvent, Polygon, PolygonData, PropertyEvent, Rect, RectData, RectHelper, RectRender, RenderEvent, Renderer, ResizeEvent, RotateEvent, Run, ScrollBar, SelectArea, Selector, Star, StarData, State, StringNumberMap, Stroker, SwipeEvent, TaskItem, TaskProcessor, Text, TextConvert, TextData, TextEditor, TwoPointBoundsHelper, UI, UIBounds, UICreator, UIData, UIEvent, UIRender, UnitConvert, WaitHelper, WatchEvent, Watcher, ZoomEvent, addInteractionWindow, affectRenderBoundsType, affectStrokeBoundsType, arrowType, attr, autoLayoutType, boundsType, canvasPatch, canvasSizeAttrs, cursorType, dataProcessor, dataType, decorateLeafAttr, defineDataProcessor, defineKey, defineLeafAttr, doBoundsType, doStrokeType, effectType, emptyData, eraserType, getBoundsData, getDescriptor, getMatrixData, getPointData, hitType, inviteCode, layoutProcessor, maskType, naturalBoundsType, opacityType, pathInputType, pathType, pen, positionType, registerEditTool, registerInnerEditor, registerUI, registerUIEvent, resizeType, rewrite, rewriteAble, rotationType, scaleResize, scaleResizeFontSize, scaleResizeGroup, scaleResizePath, scaleResizePoints, scaleType, sortType, stateType, strokeType, surfaceType, tempBounds$1 as tempBounds, tempMatrix, tempPoint$3 as tempPoint, useCanvas, useModule, version, visibleType, zoomLayerType };