@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.
package/dist/worker.js CHANGED
@@ -51,6 +51,8 @@ var LeaferUI = (function (exports) {
51
51
  const { round, pow: pow$1, PI: PI$4 } = Math;
52
52
  const MathHelper = {
53
53
  within(value, min, max) {
54
+ if (typeof min === 'object')
55
+ max = min.max, min = min.min;
54
56
  if (min !== undefined && value < min)
55
57
  value = min;
56
58
  if (max !== undefined && value > max)
@@ -153,10 +155,10 @@ var LeaferUI = (function (exports) {
153
155
  t.e += x;
154
156
  t.f += y;
155
157
  },
156
- translateInner(t, x, y, isMoveOrigin) {
158
+ translateInner(t, x, y, hasOrigin) {
157
159
  t.e += t.a * x + t.c * y;
158
160
  t.f += t.b * x + t.d * y;
159
- if (isMoveOrigin)
161
+ if (hasOrigin)
160
162
  t.e -= x, t.f -= y;
161
163
  },
162
164
  scale(t, scaleX, scaleY = scaleX) {
@@ -315,7 +317,7 @@ var LeaferUI = (function (exports) {
315
317
  to.y -= (f * a - e * b) * s;
316
318
  }
317
319
  },
318
- setLayout(t, layout, origin, bcChanged) {
320
+ setLayout(t, layout, origin, around, bcChanged) {
319
321
  const { x, y, scaleX, scaleY } = layout;
320
322
  if (bcChanged === undefined)
321
323
  bcChanged = layout.rotation || layout.skewX || layout.skewY;
@@ -347,10 +349,10 @@ var LeaferUI = (function (exports) {
347
349
  }
348
350
  t.e = x;
349
351
  t.f = y;
350
- if (origin)
351
- M$9.translateInner(t, -origin.x, -origin.y, true);
352
+ if (origin = origin || around)
353
+ M$9.translateInner(t, -origin.x, -origin.y, !around);
352
354
  },
353
- getLayout(t, origin, firstSkewY) {
355
+ getLayout(t, origin, around, firstSkewY) {
354
356
  const { a, b, c, d, e, f } = t;
355
357
  let x = e, y = f, scaleX, scaleY, rotation, skewX, skewY;
356
358
  if (b || c) {
@@ -379,9 +381,11 @@ var LeaferUI = (function (exports) {
379
381
  scaleY = d;
380
382
  rotation = skewX = skewY = 0;
381
383
  }
382
- if (origin) {
384
+ if (origin = around || origin) {
383
385
  x += origin.x * a + origin.y * c;
384
386
  y += origin.x * b + origin.y * d;
387
+ if (!around)
388
+ x -= origin.x, y -= origin.y;
385
389
  }
386
390
  return { x, y, scaleX, scaleY, rotation, skewX, skewY };
387
391
  },
@@ -709,12 +713,12 @@ var LeaferUI = (function (exports) {
709
713
  toInnerPoint(outer, to, distance) {
710
714
  MatrixHelper.toInnerPoint(this, outer, to, distance);
711
715
  }
712
- setLayout(data, origin) {
713
- MatrixHelper.setLayout(this, data, origin);
716
+ setLayout(data, origin, around) {
717
+ MatrixHelper.setLayout(this, data, origin, around);
714
718
  return this;
715
719
  }
716
- getLayout(origin, firstSkewY) {
717
- return MatrixHelper.getLayout(this, origin, firstSkewY);
720
+ getLayout(origin, around, firstSkewY) {
721
+ return MatrixHelper.getLayout(this, origin, around, firstSkewY);
718
722
  }
719
723
  withScale(scaleX, scaleY) {
720
724
  return MatrixHelper.withScale(this, scaleX, scaleY);
@@ -2002,7 +2006,7 @@ var LeaferUI = (function (exports) {
2002
2006
  DataHelper.copyAttrs(this.size, size, canvasSizeAttrs);
2003
2007
  this.size.pixelRatio || (this.size.pixelRatio = 1);
2004
2008
  this.bounds = new Bounds(0, 0, this.width, this.height);
2005
- if (!this.unreal) {
2009
+ if (this.context && !this.unreal) {
2006
2010
  this.updateViewSize();
2007
2011
  this.smooth = this.config.smooth;
2008
2012
  }
@@ -2175,7 +2179,7 @@ var LeaferUI = (function (exports) {
2175
2179
  this.manager ? this.manager.recycle(this) : this.destroy();
2176
2180
  }
2177
2181
  }
2178
- updateRender() { }
2182
+ updateRender(_bounds) { }
2179
2183
  unrealCanvas() { }
2180
2184
  destroy() {
2181
2185
  this.manager = this.view = this.parentView = null;
@@ -4069,8 +4073,13 @@ var LeaferUI = (function (exports) {
4069
4073
  zoomOfLocal(t, origin, scaleX, scaleY = scaleX, resize) {
4070
4074
  copy$a(matrix$3, t.__localMatrix);
4071
4075
  scaleOfOuter$2(matrix$3, origin, scaleX, scaleY);
4072
- moveByMatrix(t, matrix$3);
4073
- t.scaleResize(scaleX, scaleY, resize !== true);
4076
+ if (t.origin || t.around) {
4077
+ L$3.setTransform(t, matrix$3, resize);
4078
+ }
4079
+ else {
4080
+ moveByMatrix(t, matrix$3);
4081
+ t.scaleResize(scaleX, scaleY, resize !== true);
4082
+ }
4074
4083
  },
4075
4084
  rotateOfWorld(t, origin, angle) {
4076
4085
  L$3.rotateOfLocal(t, getTempLocal(t, origin), angle);
@@ -4078,8 +4087,13 @@ var LeaferUI = (function (exports) {
4078
4087
  rotateOfLocal(t, origin, angle) {
4079
4088
  copy$a(matrix$3, t.__localMatrix);
4080
4089
  rotateOfOuter$2(matrix$3, origin, angle);
4081
- moveByMatrix(t, matrix$3);
4082
- t.rotation = MathHelper.formatRotation(t.rotation + angle);
4090
+ if (t.origin || t.around) {
4091
+ L$3.setTransform(t, matrix$3);
4092
+ }
4093
+ else {
4094
+ moveByMatrix(t, matrix$3);
4095
+ t.rotation = MathHelper.formatRotation(t.rotation + angle);
4096
+ }
4083
4097
  },
4084
4098
  skewOfWorld(t, origin, skewX, skewY, resize) {
4085
4099
  L$3.skewOfLocal(t, getTempLocal(t, origin), skewX, skewY, resize);
@@ -4102,7 +4116,7 @@ var LeaferUI = (function (exports) {
4102
4116
  L$3.setTransform(t, matrix$3, resize);
4103
4117
  },
4104
4118
  setTransform(t, transform, resize) {
4105
- const layout = getLayout(transform);
4119
+ const layout = getLayout(transform, t.origin && L$3.getInnerOrigin(t, t.origin), t.around && L$3.getInnerOrigin(t, t.around));
4106
4120
  if (resize) {
4107
4121
  const scaleX = layout.scaleX / t.scaleX;
4108
4122
  const scaleY = layout.scaleY / t.scaleY;
@@ -4115,13 +4129,19 @@ var LeaferUI = (function (exports) {
4115
4129
  t.set(layout);
4116
4130
  }
4117
4131
  },
4132
+ getFlipTransform(t, axis) {
4133
+ const m = getMatrixData();
4134
+ const sign = axis === 'x' ? 1 : -1;
4135
+ scaleOfOuter$2(m, L$3.getLocalOrigin(t, 'center'), -1 * sign, 1 * sign);
4136
+ return m;
4137
+ },
4118
4138
  getLocalOrigin(t, origin) {
4119
4139
  return PointHelper.tempToOuterOf(L$3.getInnerOrigin(t, origin), t.localTransform);
4120
4140
  },
4121
4141
  getInnerOrigin(t, origin) {
4122
- if (typeof origin === 'string')
4123
- AroundHelper.toPoint(origin, t.boxBounds, origin = {});
4124
- return origin;
4142
+ const innerOrigin = {};
4143
+ AroundHelper.toPoint(origin, t.boxBounds, innerOrigin);
4144
+ return innerOrigin;
4125
4145
  },
4126
4146
  getRelativeWorld(t, relative, temp) {
4127
4147
  copy$a(matrix$3, t.worldTransform);
@@ -4548,7 +4568,10 @@ var LeaferUI = (function (exports) {
4548
4568
  on(type, listener, options) {
4549
4569
  let capture, once;
4550
4570
  if (options) {
4551
- if (typeof options === 'boolean') {
4571
+ if (options === 'once') {
4572
+ once = true;
4573
+ }
4574
+ else if (typeof options === 'boolean') {
4552
4575
  capture = options;
4553
4576
  }
4554
4577
  else {
@@ -4579,7 +4602,7 @@ var LeaferUI = (function (exports) {
4579
4602
  if (listener) {
4580
4603
  let capture;
4581
4604
  if (options)
4582
- capture = typeof options === 'boolean' ? options : options.capture;
4605
+ capture = typeof options === 'boolean' ? options : (options === 'once' ? false : options.capture);
4583
4606
  let events, index;
4584
4607
  const map = __getListenerMap(this, capture);
4585
4608
  typeList.forEach(type => {
@@ -4881,7 +4904,7 @@ var LeaferUI = (function (exports) {
4881
4904
  const layout = this.__layout, local = this.__local, data = this.__;
4882
4905
  if (layout.affectScaleOrRotation) {
4883
4906
  if (layout.scaleChanged || layout.rotationChanged) {
4884
- setLayout(local, data, null, layout.affectRotation);
4907
+ setLayout(local, data, null, null, layout.affectRotation);
4885
4908
  layout.scaleChanged = layout.rotationChanged = false;
4886
4909
  }
4887
4910
  }
@@ -4889,7 +4912,7 @@ var LeaferUI = (function (exports) {
4889
4912
  local.f = data.y + data.offsetY;
4890
4913
  if (data.around || data.origin) {
4891
4914
  toPoint$4(data.around || data.origin, layout.boxBounds, tempPoint$1);
4892
- translateInner(local, -tempPoint$1.x, -tempPoint$1.y, data.origin);
4915
+ translateInner(local, -tempPoint$1.x, -tempPoint$1.y, !data.around);
4893
4916
  }
4894
4917
  }
4895
4918
  this.__layout.matrixChanged = false;
@@ -5118,7 +5141,7 @@ var LeaferUI = (function (exports) {
5118
5141
  const { toInnerPoint, toOuterPoint, multiplyParent } = MatrixHelper;
5119
5142
  const { toOuterOf } = BoundsHelper;
5120
5143
  const { copy: copy$7 } = PointHelper;
5121
- const { moveLocal, zoomOfLocal, rotateOfLocal, skewOfLocal, moveWorld, zoomOfWorld, rotateOfWorld, skewOfWorld, transform, transformWorld, setTransform, getLocalOrigin, getRelativeWorld, drop } = LeafHelper;
5144
+ const { moveLocal, zoomOfLocal, rotateOfLocal, skewOfLocal, moveWorld, zoomOfWorld, rotateOfWorld, skewOfWorld, transform, transformWorld, setTransform, getFlipTransform, getLocalOrigin, getRelativeWorld, drop } = LeafHelper;
5122
5145
  exports.Leaf = class Leaf {
5123
5146
  get tag() { return this.__tag; }
5124
5147
  set tag(_value) { }
@@ -5144,6 +5167,8 @@ var LeaferUI = (function (exports) {
5144
5167
  get __ignoreHitWorld() { return (this.__hasMask || this.__hasEraser) && this.__.hitChildren; }
5145
5168
  get __inLazyBounds() { const { leafer } = this; return leafer && leafer.created && leafer.lazyBounds.hit(this.__world); }
5146
5169
  get pathInputed() { return this.__.__pathInputed; }
5170
+ set event(map) { let event; for (let key in map)
5171
+ event = map[key], event instanceof Array ? this.on(key, event[0], event[1]) : this.on(key, event); }
5147
5172
  constructor(data) {
5148
5173
  this.innerId = create(LEAF);
5149
5174
  this.reset(data);
@@ -5403,6 +5428,9 @@ var LeaferUI = (function (exports) {
5403
5428
  skewOfWorld(worldOrigin, skewX, skewY, resize) {
5404
5429
  skewOfWorld(this, worldOrigin, skewX, skewY, resize);
5405
5430
  }
5431
+ flip(axis) {
5432
+ transform(this, getFlipTransform(this, axis));
5433
+ }
5406
5434
  scaleResize(scaleX, scaleY = scaleX, _noResize) {
5407
5435
  this.scaleX *= scaleX;
5408
5436
  this.scaleY *= scaleY;
@@ -5760,7 +5788,7 @@ var LeaferUI = (function (exports) {
5760
5788
  }
5761
5789
  }
5762
5790
 
5763
- const version = "1.0.0-rc.30";
5791
+ const version = "1.0.1";
5764
5792
  const inviteCode = {};
5765
5793
 
5766
5794
  class LeaferCanvas extends LeaferCanvasBase {
@@ -5830,7 +5858,7 @@ var LeaferUI = (function (exports) {
5830
5858
  Platform.name = 'web';
5831
5859
  Platform.isWorker = true;
5832
5860
  Platform.requestRender = function (render) { requestAnimationFrame(render); };
5833
- Platform.devicePixelRatio = 1;
5861
+ defineKey(Platform, 'devicePixelRatio', { get() { return 1; } });
5834
5862
  const { userAgent } = navigator;
5835
5863
  if (userAgent.indexOf("Firefox") > -1) {
5836
5864
  Platform.conicGradientRotate90 = true;
@@ -6326,14 +6354,14 @@ var LeaferUI = (function (exports) {
6326
6354
  if (Debug.showRepaint)
6327
6355
  this.canvas.strokeWorld(bounds, 'red');
6328
6356
  this.target.__render(this.canvas, options);
6329
- this.renderBounds = realBounds || bounds;
6357
+ this.renderBounds = realBounds = realBounds || bounds;
6330
6358
  this.renderOptions = options;
6331
- this.totalBounds.isEmpty() ? this.totalBounds = this.renderBounds : this.totalBounds.add(this.renderBounds);
6359
+ this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
6332
6360
  if (Debug.showHitView)
6333
6361
  this.renderHitView(options);
6334
6362
  if (Debug.showBoundsView)
6335
6363
  this.renderBoundsView(options);
6336
- this.canvas.updateRender();
6364
+ this.canvas.updateRender(realBounds);
6337
6365
  }
6338
6366
  renderHitView(_options) { }
6339
6367
  renderBoundsView(_options) { }
@@ -7655,7 +7683,7 @@ var LeaferUI = (function (exports) {
7655
7683
  this.__controllers.push(this.renderer = Creator.renderer(this, canvas, config), this.watcher = Creator.watcher(this, config), this.layouter = Creator.layouter(this, config));
7656
7684
  if (this.isApp)
7657
7685
  this.__setApp();
7658
- this.__checkAutoLayout(config);
7686
+ this.__checkAutoLayout(config, parentApp);
7659
7687
  this.view = canvas.view;
7660
7688
  if (parentApp) {
7661
7689
  this.__bindApp(parentApp);
@@ -7756,9 +7784,10 @@ var LeaferUI = (function (exports) {
7756
7784
  this.leafer = leafer;
7757
7785
  this.__level = 1;
7758
7786
  }
7759
- __checkAutoLayout(config) {
7760
- if (!config.width || !config.height) {
7761
- this.autoLayout = new AutoBounds(config);
7787
+ __checkAutoLayout(config, parentApp) {
7788
+ if (!parentApp) {
7789
+ if (!config.width || !config.height)
7790
+ this.autoLayout = new AutoBounds(config);
7762
7791
  this.canvas.startAutoLayout(this.autoLayout, this.__onResize.bind(this));
7763
7792
  }
7764
7793
  }
@@ -7893,7 +7922,9 @@ var LeaferUI = (function (exports) {
7893
7922
  list.push(item);
7894
7923
  }
7895
7924
  }
7896
- zoom(_zoomType, _padding, _fixedScale) { return undefined; }
7925
+ zoom(_zoomType, _padding, _fixedScale) {
7926
+ return debug$4.error('need @leafer-in/view');
7927
+ }
7897
7928
  getValidMove(moveX, moveY) { return { x: moveX, y: moveY }; }
7898
7929
  getValidScale(changeScale) { return changeScale; }
7899
7930
  getWorldPointByClient(clientPoint, updateClient) {
@@ -8420,8 +8451,7 @@ var LeaferUI = (function (exports) {
8420
8451
  destroy() {
8421
8452
  if (this.canvas) {
8422
8453
  this.canvas.destroy();
8423
- this.canvas = null;
8424
- this.context = null;
8454
+ this.canvas = this.context = null;
8425
8455
  }
8426
8456
  super.destroy();
8427
8457
  }
@@ -8774,11 +8804,13 @@ var LeaferUI = (function (exports) {
8774
8804
  this.renderer.update();
8775
8805
  }
8776
8806
  __render(canvas, options) {
8777
- if (options.matrix) {
8778
- const { a, b, c, d, e, f } = options.matrix;
8779
- canvas.setTransform(a, b, c, d, e, f);
8807
+ if (canvas.context) {
8808
+ if (options.matrix) {
8809
+ const { a, b, c, d, e, f } = options.matrix;
8810
+ canvas.setTransform(a, b, c, d, e, f);
8811
+ }
8812
+ this.children.forEach(leafer => canvas.copyWorld(leafer.canvas));
8780
8813
  }
8781
- this.children.forEach(leafer => canvas.copyWorld(leafer.canvas));
8782
8814
  }
8783
8815
  __onResize(event) {
8784
8816
  this.children.forEach(leafer => leafer.resize(event));
@@ -9145,11 +9177,14 @@ var LeaferUI = (function (exports) {
9145
9177
  };
9146
9178
 
9147
9179
  class Transformer {
9180
+ get transforming() { return !!(this.moveData || this.zoomData || this.rotateData); }
9148
9181
  constructor(interaction) {
9149
9182
  this.interaction = interaction;
9150
9183
  }
9151
9184
  move(data) {
9152
9185
  const { interaction } = this;
9186
+ if (!data.moveType)
9187
+ data.moveType = 'move';
9153
9188
  if (!this.moveData) {
9154
9189
  const { path } = interaction.selector.getByPoint(data, interaction.hitRadius);
9155
9190
  data.path = path;
@@ -9314,8 +9349,10 @@ var LeaferUI = (function (exports) {
9314
9349
  return;
9315
9350
  }
9316
9351
  if (!this.moving && canDrag) {
9317
- if (this.moving = interaction.canMove(this.downData) || interaction.isHoldRightKey || interaction.isMobileDragEmpty)
9352
+ if (this.moving = interaction.canMove(this.downData) || interaction.isHoldRightKey || interaction.isMobileDragEmpty) {
9353
+ this.dragData.moveType = 'drag';
9318
9354
  interaction.emit(exports.MoveEvent.START, this.dragData);
9355
+ }
9319
9356
  }
9320
9357
  if (!this.moving) {
9321
9358
  this.dragStart(data, canDrag);
@@ -9354,6 +9391,7 @@ var LeaferUI = (function (exports) {
9354
9391
  this.dragData.throughPath = throughPath;
9355
9392
  this.dragData.path = path;
9356
9393
  if (this.moving) {
9394
+ this.dragData.moveType = 'drag';
9357
9395
  interaction.emit(exports.MoveEvent.BEFORE_MOVE, this.dragData);
9358
9396
  interaction.emit(exports.MoveEvent.MOVE, this.dragData);
9359
9397
  }
@@ -9420,6 +9458,7 @@ var LeaferUI = (function (exports) {
9420
9458
  endDragData.path = path;
9421
9459
  if (this.moving) {
9422
9460
  this.moving = false;
9461
+ endDragData.moveType = 'drag';
9423
9462
  interaction.emit(exports.MoveEvent.END, endDragData);
9424
9463
  }
9425
9464
  if (this.dragging) {
@@ -9478,7 +9517,7 @@ var LeaferUI = (function (exports) {
9478
9517
  totalY += moveY;
9479
9518
  PointHelper.move(downData, moveX, moveY);
9480
9519
  PointHelper.move(this.dragData, moveX, moveY);
9481
- interaction.move(Object.assign(Object.assign({}, data), { moveX, moveY, totalX, totalY }));
9520
+ interaction.move(Object.assign(Object.assign({}, data), { moveX, moveY, totalX, totalY, moveType: 'drag' }));
9482
9521
  interaction.pointerMoveReal(data);
9483
9522
  }, 10);
9484
9523
  }
@@ -9598,9 +9637,11 @@ var LeaferUI = (function (exports) {
9598
9637
  const { pathHasEventType, getMoveEventData, getZoomEventData, getRotateEventData } = InteractionHelper;
9599
9638
  class InteractionBase {
9600
9639
  get dragging() { return this.dragger.dragging; }
9640
+ get transforming() { return this.transformer.transforming; }
9601
9641
  get moveMode() { return this.config.move.drag || this.isHoldSpaceKey || this.isHoldMiddleKey || (this.isHoldRightKey && this.dragger.moving) || this.isDragEmpty; }
9642
+ get canHover() { return this.config.pointer.hover && !this.config.mobile; }
9602
9643
  get isDragEmpty() { return this.config.move.dragEmpty && this.isRootPath(this.hoverData) && (!this.downData || this.isRootPath(this.downData)); }
9603
- get isMobileDragEmpty() { return this.config.move.dragEmpty && !this.config.pointer.hover && this.downData && this.isTreePath(this.downData); }
9644
+ get isMobileDragEmpty() { return this.config.move.dragEmpty && !this.canHover && this.downData && this.isTreePath(this.downData); }
9604
9645
  get isHoldMiddleKey() { return this.config.move.holdMiddleKey && this.downData && PointerButton.middle(this.downData); }
9605
9646
  get isHoldRightKey() { return this.config.move.holdRightKey && this.downData && PointerButton.right(this.downData); }
9606
9647
  get isHoldSpaceKey() { return this.config.move.holdSpaceKey && Keyboard.isHoldSpaceKey(); }
@@ -9693,6 +9734,7 @@ var LeaferUI = (function (exports) {
9693
9734
  if (!downData)
9694
9735
  return;
9695
9736
  PointerButton.defaultLeft(data);
9737
+ data.multiTouch = downData.multiTouch;
9696
9738
  this.findPath(data);
9697
9739
  const upData = Object.assign(Object.assign({}, data), { path: data.path.clone() });
9698
9740
  data.path.addList(downData.path.list);
@@ -9765,7 +9807,7 @@ var LeaferUI = (function (exports) {
9765
9807
  this.updateCursor();
9766
9808
  }
9767
9809
  pointerHover(data) {
9768
- if (this.config.pointer.hover) {
9810
+ if (this.canHover) {
9769
9811
  this.pointerOverOrOut(data);
9770
9812
  this.pointerEnterOrLeave(data);
9771
9813
  }
@@ -9902,7 +9944,7 @@ var LeaferUI = (function (exports) {
9902
9944
  this.hoverData = data;
9903
9945
  }
9904
9946
  updateCursor(data) {
9905
- if (!this.config.cursor || !this.config.pointer.hover)
9947
+ if (!this.config.cursor || !this.canHover)
9906
9948
  return;
9907
9949
  if (!data) {
9908
9950
  this.updateHoverData();
@@ -10790,7 +10832,7 @@ var LeaferUI = (function (exports) {
10790
10832
  const { abs: abs$1 } = Math;
10791
10833
  function checkImage(ui, canvas, paint, allowPaint) {
10792
10834
  const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
10793
- if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
10835
+ if (!paint.data || (paint.patternId === scaleX + '-' + scaleY && !Export.running)) {
10794
10836
  return false;
10795
10837
  }
10796
10838
  else {
@@ -11768,7 +11810,10 @@ var LeaferUI = (function (exports) {
11768
11810
  const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
11769
11811
  let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
11770
11812
  const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
11813
+ let sliceLeaf;
11771
11814
  if (slice) {
11815
+ sliceLeaf = leaf;
11816
+ sliceLeaf.__worldOpacity = 0;
11772
11817
  leaf = leafer;
11773
11818
  renderOptions.bounds = canvas.bounds;
11774
11819
  }
@@ -11783,6 +11828,8 @@ var LeaferUI = (function (exports) {
11783
11828
  leaf.__render(canvas, renderOptions);
11784
11829
  }
11785
11830
  canvas.restore();
11831
+ if (sliceLeaf)
11832
+ sliceLeaf.__updateWorldOpacity();
11786
11833
  if (trim) {
11787
11834
  trimBounds = getTrimBounds(canvas);
11788
11835
  const old = canvas, { width, height } = trimBounds;
@@ -12275,7 +12322,7 @@ var LeaferUI = (function (exports) {
12275
12322
  }
12276
12323
  onPointerMove(e) {
12277
12324
  const { app, editor } = this;
12278
- if (this.running && !this.isMoveMode && app.config.pointer.hover && !app.interaction.dragging) {
12325
+ if (this.running && !this.isMoveMode && app.interaction.canHover && !app.interaction.dragging) {
12279
12326
  const find = this.findUI(e);
12280
12327
  editor.hoverTarget = editor.hasItem(find) ? null : find;
12281
12328
  }
@@ -12284,15 +12331,27 @@ var LeaferUI = (function (exports) {
12284
12331
  }
12285
12332
  }
12286
12333
  onBeforeDown(e) {
12334
+ if (e.multiTouch)
12335
+ return;
12287
12336
  const { select } = this.editor.mergeConfig;
12288
- if (select === 'press')
12289
- this.checkAndSelect(e);
12337
+ if (select === 'press') {
12338
+ if (this.app.config.mobile) {
12339
+ this.waitSelect = () => this.checkAndSelect(e);
12340
+ }
12341
+ else {
12342
+ this.checkAndSelect(e);
12343
+ }
12344
+ }
12290
12345
  }
12291
12346
  onTap(e) {
12347
+ if (e.multiTouch)
12348
+ return;
12292
12349
  const { editor } = this;
12293
12350
  const { select } = editor.mergeConfig;
12294
12351
  if (select === 'tap')
12295
12352
  this.checkAndSelect(e);
12353
+ else if (this.waitSelect)
12354
+ this.waitSelect();
12296
12355
  if (this.needRemoveItem) {
12297
12356
  editor.removeItem(this.needRemoveItem);
12298
12357
  }
@@ -12323,6 +12382,10 @@ var LeaferUI = (function (exports) {
12323
12382
  }
12324
12383
  }
12325
12384
  onDragStart(e) {
12385
+ if (e.multiTouch)
12386
+ return;
12387
+ if (this.waitSelect)
12388
+ this.waitSelect();
12326
12389
  if (this.allowDrag(e)) {
12327
12390
  const { editor } = this;
12328
12391
  const { stroke, area } = editor.mergeConfig;
@@ -12334,10 +12397,10 @@ var LeaferUI = (function (exports) {
12334
12397
  }
12335
12398
  }
12336
12399
  onDrag(e) {
12337
- if (this.editor.dragging) {
12338
- this.onDragEnd();
12400
+ if (e.multiTouch)
12339
12401
  return;
12340
- }
12402
+ if (this.editor.dragging)
12403
+ return this.onDragEnd(e);
12341
12404
  if (this.dragging) {
12342
12405
  const { editor } = this;
12343
12406
  const total = e.getInnerTotal(this);
@@ -12361,7 +12424,9 @@ var LeaferUI = (function (exports) {
12361
12424
  }
12362
12425
  }
12363
12426
  }
12364
- onDragEnd() {
12427
+ onDragEnd(e) {
12428
+ if (e.multiTouch)
12429
+ return;
12365
12430
  if (this.dragging)
12366
12431
  this.originList = null, this.selectArea.visible = false;
12367
12432
  }
@@ -12407,7 +12472,7 @@ var LeaferUI = (function (exports) {
12407
12472
  app.on_(exports.PointerEvent.MOVE, this.onPointerMove, this),
12408
12473
  app.on_(exports.PointerEvent.BEFORE_DOWN, this.onBeforeDown, this),
12409
12474
  app.on_(exports.PointerEvent.TAP, this.onTap, this),
12410
- app.on_(exports.DragEvent.START, this.onDragStart, this),
12475
+ app.on_(exports.DragEvent.START, this.onDragStart, this, true),
12411
12476
  app.on_(exports.DragEvent.DRAG, this.onDrag, this),
12412
12477
  app.on_(exports.DragEvent.END, this.onDragEnd, this),
12413
12478
  app.on_(exports.MoveEvent.MOVE, this.onAutoMove, this),
@@ -12430,22 +12495,32 @@ var LeaferUI = (function (exports) {
12430
12495
 
12431
12496
  const { topLeft, top, topRight, right: right$1, bottomRight, bottom, bottomLeft, left: left$1 } = exports.Direction9;
12432
12497
  const { toPoint } = AroundHelper;
12498
+ const { within } = MathHelper;
12433
12499
  const EditDataHelper = {
12434
- getScaleData(bounds, direction, pointMove, lockRatio, around) {
12500
+ getScaleData(element, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
12435
12501
  let align, origin = {}, scaleX = 1, scaleY = 1;
12436
- const { width, height } = bounds;
12502
+ const { boxBounds, widthRange, heightRange } = element;
12503
+ const { width, height } = startBounds;
12437
12504
  if (around) {
12438
- pointMove.x *= 2;
12439
- pointMove.y *= 2;
12440
- }
12441
- if (Math.abs(pointMove.x) === width)
12442
- pointMove.x += 0.1;
12443
- if (Math.abs(pointMove.y) === height)
12444
- pointMove.y += 0.1;
12445
- const topScale = (-pointMove.y + height) / height;
12446
- const rightScale = (pointMove.x + width) / width;
12447
- const bottomScale = (pointMove.y + height) / height;
12448
- const leftScale = (-pointMove.x + width) / width;
12505
+ totalMove.x *= 2;
12506
+ totalMove.y *= 2;
12507
+ }
12508
+ const originChangedScaleX = element.scaleX / startBounds.scaleX;
12509
+ const originChangedScaleY = element.scaleY / startBounds.scaleY;
12510
+ const signX = originChangedScaleX < 0 ? -1 : 1;
12511
+ const signY = originChangedScaleY < 0 ? -1 : 1;
12512
+ const changedScaleX = scaleMode ? originChangedScaleX : signX * boxBounds.width / width;
12513
+ const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height;
12514
+ totalMove.x *= scaleMode ? originChangedScaleX : signX;
12515
+ totalMove.y *= scaleMode ? originChangedScaleY : signY;
12516
+ if (Math.abs(totalMove.x) === width)
12517
+ totalMove.x += 0.1;
12518
+ if (Math.abs(totalMove.y) === height)
12519
+ totalMove.y += 0.1;
12520
+ const topScale = (-totalMove.y + height) / height;
12521
+ const rightScale = (totalMove.x + width) / width;
12522
+ const bottomScale = (totalMove.y + height) / height;
12523
+ const leftScale = (-totalMove.x + width) / width;
12449
12524
  switch (direction) {
12450
12525
  case top:
12451
12526
  scaleY = topScale;
@@ -12491,7 +12566,24 @@ var LeaferUI = (function (exports) {
12491
12566
  scaleY = scaleY < 0 ? -scale : scale;
12492
12567
  }
12493
12568
  }
12494
- toPoint(around || align, bounds, origin);
12569
+ scaleX /= changedScaleX;
12570
+ scaleY /= changedScaleY;
12571
+ if (!flipable) {
12572
+ const { worldTransform } = element;
12573
+ if (scaleX < 0)
12574
+ scaleX = 1 / boxBounds.width / worldTransform.scaleX;
12575
+ if (scaleY < 0)
12576
+ scaleY = 1 / boxBounds.height / worldTransform.scaleY;
12577
+ }
12578
+ if (widthRange) {
12579
+ const nowWidth = boxBounds.width * element.scaleX;
12580
+ scaleX = within(nowWidth * scaleX, widthRange) / nowWidth;
12581
+ }
12582
+ if (heightRange) {
12583
+ const nowHeight = boxBounds.height * element.scaleY;
12584
+ scaleY = within(nowHeight * scaleY, heightRange) / nowHeight;
12585
+ }
12586
+ toPoint(around || align, boxBounds, origin);
12495
12587
  return { origin, scaleX, scaleY, direction, lockRatio, around };
12496
12588
  },
12497
12589
  getRotateData(bounds, direction, current, last, around) {
@@ -12612,6 +12704,11 @@ var LeaferUI = (function (exports) {
12612
12704
  return;
12613
12705
  if (point.name === 'circle')
12614
12706
  return;
12707
+ if (point.pointType === 'button') {
12708
+ if (!point.cursor)
12709
+ point.cursor = 'pointer';
12710
+ return;
12711
+ }
12615
12712
  let { rotation } = editBox;
12616
12713
  const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
12617
12714
  const { pointType } = point, { flippedX, flippedY } = editBox;
@@ -12680,9 +12777,8 @@ var LeaferUI = (function (exports) {
12680
12777
  resizePoints.push(resizePoint);
12681
12778
  this.listenPointEvents(resizePoint, 'resize', i);
12682
12779
  }
12683
- buttons.add(circle);
12684
12780
  this.listenPointEvents(circle, 'rotate', 2);
12685
- view.addMany(...rotatePoints, rect, buttons, ...resizeLines, ...resizePoints);
12781
+ view.addMany(...rotatePoints, rect, circle, buttons, ...resizeLines, ...resizePoints);
12686
12782
  this.add(view);
12687
12783
  }
12688
12784
  load() {
@@ -12698,9 +12794,9 @@ var LeaferUI = (function (exports) {
12698
12794
  if (!(i % 2))
12699
12795
  resizeP.rotation = (i / 2) * 90;
12700
12796
  }
12701
- circle.set(this.getPointStyle(mergeConfig.rotatePoint || pointsStyle[0]));
12797
+ circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]));
12702
12798
  rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
12703
- rect.hittable = !single && moveable;
12799
+ rect.hittable = !single && !!moveable;
12704
12800
  element.syncEventer = (single && moveable) ? rect : null;
12705
12801
  this.app.interaction.bottomList = (single && moveable) ? [{ target: rect, proxy: element }] : null;
12706
12802
  }
@@ -12709,7 +12805,7 @@ var LeaferUI = (function (exports) {
12709
12805
  if (this.view.worldOpacity) {
12710
12806
  const { mergeConfig } = this.editor;
12711
12807
  const { width, height } = bounds;
12712
- const { rect, circle, resizePoints, rotatePoints, resizeLines } = this;
12808
+ const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this;
12713
12809
  const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
12714
12810
  const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
12715
12811
  const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
@@ -12739,19 +12835,25 @@ var LeaferUI = (function (exports) {
12739
12835
  }
12740
12836
  }
12741
12837
  }
12742
- circle.visible = showPoints && rotateable && !!mergeConfig.rotatePoint;
12838
+ circle.visible = showPoints && rotateable && !!(mergeConfig.circle || mergeConfig.rotatePoint);
12839
+ if (circle.visible)
12840
+ this.layoutCircle(mergeConfig);
12743
12841
  if (rect.path)
12744
12842
  rect.path = null;
12745
12843
  rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
12746
- const buttonVisible = showPoints && (circle.visible || this.buttons.children.length > 1);
12747
- this.buttons.visible = buttonVisible;
12748
- if (buttonVisible)
12749
- this.layoutButtons();
12844
+ buttons.visible = showPoints && buttons.children.length > 0;
12845
+ if (buttons.visible)
12846
+ this.layoutButtons(mergeConfig);
12750
12847
  }
12751
12848
  }
12752
- layoutButtons() {
12753
- const { buttons, resizePoints } = this;
12754
- const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = this.editor.mergeConfig;
12849
+ layoutCircle(config) {
12850
+ const { circleDirection, circleMargin, buttonsMargin, buttonsDirection, middlePoint } = config;
12851
+ const direction = fourDirection.indexOf(circleDirection || ((this.buttons.children.length && buttonsDirection === 'bottom') ? 'top' : 'bottom'));
12852
+ this.setButtonPosition(this.circle, direction, circleMargin || buttonsMargin, !!middlePoint);
12853
+ }
12854
+ layoutButtons(config) {
12855
+ const { buttons } = this;
12856
+ const { buttonsDirection, buttonsFixed, buttonsMargin, middlePoint } = config;
12755
12857
  const { flippedX, flippedY } = this;
12756
12858
  let index = fourDirection.indexOf(buttonsDirection);
12757
12859
  if ((index % 2 && flippedX) || ((index + 1) % 2 && flippedY)) {
@@ -12759,11 +12861,18 @@ var LeaferUI = (function (exports) {
12759
12861
  index = (index + 2) % 4;
12760
12862
  }
12761
12863
  const direction = buttonsFixed ? EditDataHelper.getRotateDirection(index, this.flippedOne ? this.rotation : -this.rotation, 4) : index;
12762
- const point = resizePoints[direction * 2 + 1];
12864
+ this.setButtonPosition(buttons, direction, buttonsMargin, !!middlePoint);
12865
+ if (buttonsFixed)
12866
+ buttons.rotation = (direction - index) * 90;
12867
+ buttons.scaleX = flippedX ? -1 : 1;
12868
+ buttons.scaleY = flippedY ? -1 : 1;
12869
+ }
12870
+ setButtonPosition(buttons, direction, buttonsMargin, useMiddlePoint) {
12871
+ const point = this.resizePoints[direction * 2 + 1];
12763
12872
  const useX = direction % 2;
12764
12873
  const sign = (!direction || direction === 3) ? -1 : 1;
12765
- const useWidth = index % 2;
12766
- const margin = (buttonsMargin + (useWidth ? ((middlePoint ? point.width : 0) + buttons.boxBounds.width) : ((middlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
12874
+ const useWidth = direction % 2;
12875
+ const margin = (buttonsMargin + (useWidth ? ((useMiddlePoint ? point.width : 0) + buttons.boxBounds.width) : ((useMiddlePoint ? point.height : 0) + buttons.boxBounds.height)) / 2) * sign;
12767
12876
  if (useX) {
12768
12877
  buttons.x = point.x + margin;
12769
12878
  buttons.y = point.y;
@@ -12772,11 +12881,6 @@ var LeaferUI = (function (exports) {
12772
12881
  buttons.x = point.x;
12773
12882
  buttons.y = point.y + margin;
12774
12883
  }
12775
- if (buttonsFixed) {
12776
- buttons.rotation = (direction - index) * 90;
12777
- buttons.scaleX = flippedX ? -1 : 1;
12778
- buttons.scaleY = flippedY ? -1 : 1;
12779
- }
12780
12884
  }
12781
12885
  unload() {
12782
12886
  this.visible = false;
@@ -12803,12 +12907,15 @@ var LeaferUI = (function (exports) {
12803
12907
  }
12804
12908
  onDragStart(e) {
12805
12909
  this.dragging = true;
12910
+ const { editor } = this;
12806
12911
  if (e.current.name === 'rect') {
12807
- const { editor } = this;
12808
12912
  this.moving = true;
12809
12913
  editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
12810
12914
  editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
12811
12915
  }
12916
+ else if (e.current.pointType === 'resize') {
12917
+ editor.dragStartBounds = Object.assign({}, editor.element.getLayoutBounds('box', 'local'));
12918
+ }
12812
12919
  }
12813
12920
  onDragEnd(e) {
12814
12921
  this.dragging = false;
@@ -12823,7 +12930,7 @@ var LeaferUI = (function (exports) {
12823
12930
  if (editor.mergeConfig.rotateable)
12824
12931
  editor.onRotate(e);
12825
12932
  }
12826
- else {
12933
+ else if (point.pointType === 'resize') {
12827
12934
  editor.onScale(e);
12828
12935
  }
12829
12936
  updateCursor(editor, e);
@@ -12887,8 +12994,6 @@ var LeaferUI = (function (exports) {
12887
12994
  rect.on_(exports.DragEvent.START, this.onDragStart, this),
12888
12995
  rect.on_(exports.DragEvent.DRAG, editor.onMove, editor),
12889
12996
  rect.on_(exports.DragEvent.END, this.onDragEnd, this),
12890
- rect.on_(exports.ZoomEvent.BEFORE_ZOOM, editor.onScale, editor, true),
12891
- rect.on_(exports.RotateEvent.BEFORE_ROTATE, editor.onRotate, editor, true),
12892
12997
  rect.on_(exports.PointerEvent.ENTER, () => updateMoveCursor(editor)),
12893
12998
  rect.on_(exports.PointerEvent.DOUBLE_TAP, this.onDoubleTap, this),
12894
12999
  rect.on_(exports.PointerEvent.LONG_PRESS, this.onLongPress, this)
@@ -12918,7 +13023,7 @@ var LeaferUI = (function (exports) {
12918
13023
  const { rect } = editor.editBox;
12919
13024
  const { width, height } = rect.__;
12920
13025
  canvas.resetTransform();
12921
- canvas.fillWorld(canvas.bounds, mask);
13026
+ canvas.fillWorld(canvas.bounds, mask === true ? 'rgba(0,0,0,0.8)' : mask);
12922
13027
  canvas.setWorld(rect.__world, options.matrix);
12923
13028
  canvas.clearRect(0, 0, width, height);
12924
13029
  }
@@ -13003,6 +13108,7 @@ ${filterStyle}
13003
13108
  boxSelect: true,
13004
13109
  moveable: true,
13005
13110
  resizeable: true,
13111
+ flipable: true,
13006
13112
  rotateable: true,
13007
13113
  skewable: true
13008
13114
  };
@@ -13224,29 +13330,39 @@ ${filterStyle}
13224
13330
  return this.mergeConfig.editSize;
13225
13331
  }
13226
13332
  onMove(e) {
13227
- const total = { x: e.totalX, y: e.totalY };
13228
- if (e.shiftKey) {
13229
- if (Math.abs(total.x) > Math.abs(total.y))
13230
- total.y = 0;
13231
- else
13232
- total.x = 0;
13333
+ if (e instanceof exports.MoveEvent) {
13334
+ if (e.moveType !== 'drag') {
13335
+ const { moveable, resizeable } = this.mergeConfig;
13336
+ const move = e.getLocalMove(this.element);
13337
+ if (moveable === 'move')
13338
+ e.stop(), this.move(move.x, move.y);
13339
+ else if (resizeable === 'zoom')
13340
+ e.stop();
13341
+ }
13342
+ }
13343
+ else {
13344
+ const total = { x: e.totalX, y: e.totalY };
13345
+ if (e.shiftKey) {
13346
+ if (Math.abs(total.x) > Math.abs(total.y))
13347
+ total.y = 0;
13348
+ else
13349
+ total.x = 0;
13350
+ }
13351
+ this.move(exports.DragEvent.getValidMove(this.element, this.dragStartPoint, total));
13233
13352
  }
13234
- this.move(exports.DragEvent.getValidMove(this.element, this.dragStartPoint, total));
13235
13353
  }
13236
13354
  onScale(e) {
13237
13355
  const { element } = this;
13356
+ let { around, lockRatio, resizeable, flipable, editSize } = this.mergeConfig;
13238
13357
  if (e instanceof exports.ZoomEvent) {
13239
- if (this.mergeConfig.resizeable === 'zoom') {
13240
- e.stop();
13241
- this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
13242
- }
13358
+ if (resizeable === 'zoom')
13359
+ e.stop(), this.scaleOf(element.getInnerPoint(e), e.scale, e.scale);
13243
13360
  }
13244
13361
  else {
13245
13362
  const { direction } = e.current;
13246
- let { around, lockRatio } = this.mergeConfig;
13247
13363
  if (e.shiftKey || element.lockRatio)
13248
13364
  lockRatio = true;
13249
- const data = EditDataHelper.getScaleData(element.boxBounds, direction, e.getInnerMove(element), lockRatio, EditDataHelper.getAround(around, e.altKey));
13365
+ const data = EditDataHelper.getScaleData(element, this.dragStartBounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
13250
13366
  if (this.editTool.onScaleWithDrag) {
13251
13367
  data.drag = e;
13252
13368
  this.scaleWithDrag(data);
@@ -13257,23 +13373,21 @@ ${filterStyle}
13257
13373
  }
13258
13374
  }
13259
13375
  onRotate(e) {
13260
- const { skewable, around, rotateGap } = this.mergeConfig;
13376
+ const { skewable, rotateable, around, rotateGap } = this.mergeConfig;
13261
13377
  const { direction, name } = e.current;
13262
13378
  if (skewable && name === 'resize-line')
13263
13379
  return this.onSkew(e);
13264
13380
  const { element } = this;
13265
13381
  let origin, rotation;
13266
13382
  if (e instanceof exports.RotateEvent) {
13267
- if (this.mergeConfig.rotateable === 'rotate') {
13268
- e.stop();
13269
- rotation = e.rotation, origin = element.getInnerPoint(e);
13270
- }
13383
+ if (rotateable === 'rotate')
13384
+ e.stop(), rotation = e.rotation, origin = element.getInnerPoint(e);
13271
13385
  else
13272
13386
  return;
13273
13387
  }
13274
13388
  else {
13275
13389
  const last = { x: e.x - e.moveX, y: e.y - e.moveY };
13276
- const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (around || 'center'));
13390
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getInner(element), element.getInnerPoint(last), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
13277
13391
  rotation = data.rotation;
13278
13392
  origin = data.origin;
13279
13393
  }
@@ -13307,8 +13421,7 @@ ${filterStyle}
13307
13421
  if (!this.mergeConfig.resizeable || this.element.locked)
13308
13422
  return;
13309
13423
  const { element } = this;
13310
- const worldOrigin = element.getWorldPoint(data.origin);
13311
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin }));
13424
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) }));
13312
13425
  this.editTool.onScaleWithDrag(event);
13313
13426
  this.emitEvent(event);
13314
13427
  }
@@ -13316,28 +13429,28 @@ ${filterStyle}
13316
13429
  if (!this.mergeConfig.resizeable || this.element.locked)
13317
13430
  return;
13318
13431
  const { element } = this;
13319
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
13320
- let transform;
13321
- if (this.multiple) {
13322
- const oldMatrix = new Matrix(element.worldTransform);
13323
- element.scaleOf(origin, scaleX, scaleY);
13324
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
13325
- }
13432
+ const worldOrigin = this.getWorldOrigin(origin);
13433
+ const transform = this.multiple && this.getChangedTransform(() => element.scaleOf(origin, scaleX, scaleY));
13326
13434
  const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
13327
13435
  this.editTool.onScale(event);
13328
13436
  this.emitEvent(event);
13329
13437
  }
13438
+ flip(axis) {
13439
+ if (this.element.locked)
13440
+ return;
13441
+ const { element } = this;
13442
+ const worldOrigin = this.getWorldOrigin('center');
13443
+ const transform = this.multiple ? this.getChangedTransform(() => element.flip(axis)) : new Matrix(LeafHelper.getFlipTransform(element, axis));
13444
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform });
13445
+ this.editTool.onScale(event);
13446
+ this.emitEvent(event);
13447
+ }
13330
13448
  rotateOf(origin, rotation) {
13331
13449
  if (!this.mergeConfig.rotateable || this.element.locked)
13332
13450
  return;
13333
13451
  const { element } = this;
13334
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
13335
- let transform;
13336
- if (this.multiple) {
13337
- const oldMatrix = new Matrix(element.worldTransform);
13338
- element.rotateOf(origin, rotation);
13339
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
13340
- }
13452
+ const worldOrigin = this.getWorldOrigin(origin);
13453
+ const transform = this.multiple && this.getChangedTransform(() => element.rotateOf(origin, rotation));
13341
13454
  const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
13342
13455
  this.editTool.onRotate(event);
13343
13456
  this.emitEvent(event);
@@ -13346,19 +13459,21 @@ ${filterStyle}
13346
13459
  if (!this.mergeConfig.skewable || this.element.locked)
13347
13460
  return;
13348
13461
  const { element } = this;
13349
- const worldOrigin = element.getWorldPoint(LeafHelper.getInnerOrigin(element, origin));
13350
- let transform;
13351
- if (this.multiple) {
13352
- const oldMatrix = new Matrix(element.worldTransform);
13353
- element.skewOf(origin, skewX, skewY);
13354
- transform = new Matrix(element.worldTransform).divide(oldMatrix);
13355
- }
13356
- const event = new EditorSkewEvent(EditorSkewEvent.SKEW, {
13357
- target: element, editor: this, skewX, skewY, transform, worldOrigin
13358
- });
13462
+ const worldOrigin = this.getWorldOrigin(origin);
13463
+ const transform = this.multiple && this.getChangedTransform(() => element.skewOf(origin, skewX, skewY));
13464
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, { target: element, editor: this, worldOrigin, skewX, skewY, transform });
13359
13465
  this.editTool.onSkew(event);
13360
13466
  this.emitEvent(event);
13361
13467
  }
13468
+ getWorldOrigin(origin) {
13469
+ return this.element.getWorldPoint(LeafHelper.getInnerOrigin(this.element, origin));
13470
+ }
13471
+ getChangedTransform(func) {
13472
+ const { element } = this;
13473
+ const oldMatrix = new Matrix(element.worldTransform);
13474
+ func();
13475
+ return new Matrix(element.worldTransform).divide(oldMatrix);
13476
+ }
13362
13477
  group(userGroup) {
13363
13478
  if (this.multiple) {
13364
13479
  this.target = EditorHelper.group(this.list, this.element, userGroup);
@@ -13469,6 +13584,9 @@ ${filterStyle}
13469
13584
  if (!this.targetEventIds.length) {
13470
13585
  const { leafer } = this.list[0];
13471
13586
  this.targetEventIds = [
13587
+ this.app.on_(exports.MoveEvent.BEFORE_MOVE, this.onMove, this, true),
13588
+ this.app.on_(exports.ZoomEvent.BEFORE_ZOOM, this.onScale, this, true),
13589
+ this.app.on_(exports.RotateEvent.BEFORE_ROTATE, this.onRotate, this, true),
13472
13590
  leafer.on_(RenderEvent.START, this.update, this),
13473
13591
  leafer.on_([exports.KeyEvent.HOLD, exports.KeyEvent.UP], (e) => { updateCursor(this, e); }),
13474
13592
  leafer.on_(exports.KeyEvent.DOWN, this.editBox.onArrow, this.editBox)
@@ -14192,6 +14310,169 @@ ${filterStyle}
14192
14310
 
14193
14311
  Object.assign(PathArrow, PathArrowModule);
14194
14312
 
14313
+ const textCaseMap = {
14314
+ 'none': 'none',
14315
+ 'title': 'capitalize',
14316
+ 'upper': 'uppercase',
14317
+ 'lower': 'lowercase',
14318
+ 'small-caps': 'small-caps'
14319
+ };
14320
+ const verticalAlignMap = {
14321
+ 'top': 'flex-start',
14322
+ 'middle': 'center',
14323
+ 'bottom': 'flex-end'
14324
+ };
14325
+ function updateStyle(textDom, text, textScale) {
14326
+ const { style } = textDom;
14327
+ const { fill, padding, textWrap, textOverflow, textDecoration } = text;
14328
+ style.fontFamily = text.fontFamily;
14329
+ style.fontSize = text.fontSize * textScale + 'px';
14330
+ setFill(style, fill);
14331
+ style.fontStyle = text.italic ? 'italic' : 'normal';
14332
+ style.fontWeight = text.fontWeight;
14333
+ style.textDecoration = textDecoration === 'delete' ? 'line-through' : textDecoration;
14334
+ style.textTransform = textCaseMap[text.textCase];
14335
+ style.textAlign = text.textAlign;
14336
+ style.display = 'flex';
14337
+ style.flexDirection = 'column';
14338
+ style.justifyContent = verticalAlignMap[text.verticalAlign];
14339
+ style.lineHeight = (text.__.__lineHeight || 0) * textScale + 'px';
14340
+ style.letterSpacing = (text.__.__letterSpacing || 0) * textScale + 'px';
14341
+ if (textWrap === 'none') {
14342
+ style.whiteSpace = 'nowrap';
14343
+ }
14344
+ else if (textWrap === 'break') {
14345
+ style.wordBreak = 'break-all';
14346
+ }
14347
+ style.textIndent = (text.paraIndent || 0) * textScale + 'px';
14348
+ style.padding = padding instanceof Array ? padding.map(item => item * textScale + 'px').join(' ') : (padding || 0) * textScale + 'px';
14349
+ style.textOverflow = textOverflow === 'show' ? '' : (textOverflow === 'hide' ? 'clip' : textOverflow);
14350
+ }
14351
+ function setFill(style, fill) {
14352
+ let color = 'black';
14353
+ if (fill instanceof Array)
14354
+ fill = fill[0];
14355
+ if (typeof fill === 'object') {
14356
+ switch (fill.type) {
14357
+ case 'solid':
14358
+ color = ColorConvert.string(fill.color);
14359
+ break;
14360
+ case 'image':
14361
+ break;
14362
+ case 'linear':
14363
+ case 'radial':
14364
+ case 'angular':
14365
+ const stop = fill.stops[0];
14366
+ color = ColorConvert.string(typeof stop === 'string' ? stop : stop.color);
14367
+ break;
14368
+ default:
14369
+ if (fill.r !== undefined)
14370
+ color = ColorConvert.string(fill);
14371
+ }
14372
+ }
14373
+ else {
14374
+ color = fill;
14375
+ }
14376
+ style.color = color;
14377
+ }
14378
+
14379
+ exports.TextEditor = class TextEditor extends InnerEditor {
14380
+ constructor() {
14381
+ super(...arguments);
14382
+ this.config = {
14383
+ selectAll: true
14384
+ };
14385
+ this.eventIds = [];
14386
+ }
14387
+ get tag() { return 'TextEditor'; }
14388
+ onLoad() {
14389
+ const { editor } = this;
14390
+ const { config } = editor.app;
14391
+ this._keyEvent = config.keyEvent;
14392
+ config.keyEvent = false;
14393
+ const text = this.editTarget;
14394
+ text.visible = false;
14395
+ const div = this.editDom = document.createElement('div');
14396
+ const { style } = div;
14397
+ div.contentEditable = 'true';
14398
+ div.innerText = text.text;
14399
+ style.position = 'fixed';
14400
+ style.transformOrigin = 'left top';
14401
+ style.boxSizing = 'border-box';
14402
+ const { scaleX, scaleY } = text.worldTransform;
14403
+ this.textScale = Math.max(Math.abs(scaleX), Math.abs(scaleY));
14404
+ const fontSize = text.fontSize * this.textScale;
14405
+ if (fontSize < 12)
14406
+ this.textScale *= 12 / fontSize;
14407
+ editor.app.view.appendChild(div);
14408
+ this.eventIds = [
14409
+ editor.app.on_(exports.PointerEvent.DOWN, (e) => { if (e.origin.target !== div)
14410
+ editor.closeInnerEditor(); })
14411
+ ];
14412
+ this.onFocus = this.onFocus.bind(this);
14413
+ this.onInput = this.onInput.bind(this);
14414
+ this.onUpdate = this.onUpdate.bind(this);
14415
+ this.onEscape = this.onEscape.bind(this);
14416
+ div.addEventListener("focus", this.onFocus);
14417
+ div.addEventListener("input", this.onInput);
14418
+ window.addEventListener('keydown', this.onEscape);
14419
+ window.addEventListener('scroll', this.onUpdate);
14420
+ const selection = window.getSelection();
14421
+ const range = document.createRange();
14422
+ if (this.config.selectAll) {
14423
+ range.selectNodeContents(div);
14424
+ }
14425
+ else {
14426
+ const node = div.childNodes[0];
14427
+ range.setStartAfter(node);
14428
+ range.setEndAfter(node);
14429
+ range.collapse(true);
14430
+ }
14431
+ selection.removeAllRanges();
14432
+ selection.addRange(range);
14433
+ }
14434
+ onInput() {
14435
+ this.editTarget.text = this.editDom.innerText.replace(/\n\n/, '\n');
14436
+ }
14437
+ onFocus() {
14438
+ this.editDom.style.outline = 'none';
14439
+ }
14440
+ onEscape(e) {
14441
+ if (e.code === 'Escape')
14442
+ this.editor.closeInnerEditor();
14443
+ }
14444
+ onUpdate() {
14445
+ const { editTarget: text, textScale } = this;
14446
+ const { style } = this.editDom;
14447
+ const { x, y } = text.app.tree.clientBounds;
14448
+ const { a, b, c, d, e, f } = new Matrix(text.worldTransform).scale(1 / textScale);
14449
+ style.transform = `matrix(${a},${b},${c},${d},${e},${f})`;
14450
+ style.left = x - window.scrollX + 'px';
14451
+ style.top = y - window.scrollY + 'px';
14452
+ style.width = text.width * textScale + (text.__.__autoWidth ? 20 : 0) + 'px';
14453
+ style.height = text.height * textScale + (text.__.__autoHeight ? 20 : 0) + 'px';
14454
+ updateStyle(this.editDom, text, this.textScale);
14455
+ }
14456
+ onUnload() {
14457
+ const { editTarget: text, editor, editDom: dom } = this;
14458
+ if (text) {
14459
+ this.onInput();
14460
+ text.visible = true;
14461
+ editor.app.config.keyEvent = this._keyEvent;
14462
+ editor.off_(this.eventIds);
14463
+ dom.removeEventListener("focus", this.onFocus);
14464
+ dom.removeEventListener("input", this.onInput);
14465
+ window.removeEventListener('keydown', this.onEscape);
14466
+ window.removeEventListener('scroll', this.onUpdate);
14467
+ dom.remove();
14468
+ this.editDom = this.eventIds = undefined;
14469
+ }
14470
+ }
14471
+ };
14472
+ exports.TextEditor = __decorate([
14473
+ registerInnerEditor()
14474
+ ], exports.TextEditor);
14475
+
14195
14476
  class HTMLTextData extends ImageData {
14196
14477
  setText(value) {
14197
14478
  this._text = value;