@leafer-editor/worker 1.4.2 → 1.5.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.
@@ -2029,13 +2029,11 @@ class LeaferCanvasBase extends Canvas$1 {
2029
2029
  this.worldTransform = {};
2030
2030
  if (!config)
2031
2031
  config = minSize;
2032
- if (!config.pixelRatio)
2033
- config.pixelRatio = Platform.devicePixelRatio;
2034
2032
  this.manager = manager;
2035
2033
  this.innerId = IncrementId.create(IncrementId.CNAVAS);
2036
2034
  const { width, height, pixelRatio } = config;
2037
2035
  this.autoLayout = !width || !height;
2038
- this.size.pixelRatio = pixelRatio;
2036
+ this.size.pixelRatio = pixelRatio | Platform.devicePixelRatio;
2039
2037
  this.config = config;
2040
2038
  this.init();
2041
2039
  }
@@ -2232,7 +2230,7 @@ class LeaferCanvasBase extends Canvas$1 {
2232
2230
  tempBounds$1.ceil();
2233
2231
  }
2234
2232
  isSameSize(size) {
2235
- return this.width === size.width && this.height === size.height && this.pixelRatio === size.pixelRatio;
2233
+ return this.width === size.width && this.height === size.height && (!size.pixelRatio || this.pixelRatio === size.pixelRatio);
2236
2234
  }
2237
2235
  getSameCanvas(useSameWorldTransform, useSameSmooth) {
2238
2236
  const canvas = this.manager ? this.manager.get(this.size) : Creator.canvas(Object.assign({}, this.size));
@@ -4070,13 +4068,10 @@ function defineDataProcessor(target, key, defaultValue) {
4070
4068
  if (defaultValue === undefined) {
4071
4069
  property.get = function () { return this[computedKey]; };
4072
4070
  }
4073
- else if (typeof defaultValue === 'object') {
4074
- const { clone } = DataHelper;
4071
+ else if (typeof defaultValue === 'function') {
4075
4072
  property.get = function () {
4076
4073
  let v = this[computedKey];
4077
- if (v === undefined)
4078
- this[computedKey] = v = clone(defaultValue);
4079
- return v;
4074
+ return v === undefined ? defaultValue(this.__leaf) : v;
4080
4075
  };
4081
4076
  }
4082
4077
  if (key === 'width') {
@@ -5722,10 +5717,10 @@ let Leaf = class Leaf {
5722
5717
  static changeAttr(attrName, defaultValue, fn) {
5723
5718
  fn ? this.addAttr(attrName, defaultValue, fn) : defineDataProcessor(this.prototype, attrName, defaultValue);
5724
5719
  }
5725
- static addAttr(attrName, defaultValue, fn) {
5720
+ static addAttr(attrName, defaultValue, fn, helpValue) {
5726
5721
  if (!fn)
5727
5722
  fn = boundsType;
5728
- fn(defaultValue)(this.prototype, attrName);
5723
+ fn(defaultValue, helpValue)(this.prototype, attrName);
5729
5724
  }
5730
5725
  __emitLifeEvent(type) {
5731
5726
  if (this.hasEvent(type))
@@ -6052,7 +6047,7 @@ class LeafLevelList {
6052
6047
  }
6053
6048
  }
6054
6049
 
6055
- const version = "1.4.2";
6050
+ const version = "1.5.1";
6056
6051
 
6057
6052
  class LeaferCanvas extends LeaferCanvasBase {
6058
6053
  get allowBackgroundColor() { return true; }
@@ -6939,7 +6934,11 @@ const State = {
6939
6934
  setStyleName() { return Plugin.need('state'); },
6940
6935
  set() { return Plugin.need('state'); }
6941
6936
  };
6942
- const Transition = {};
6937
+ const Transition = {
6938
+ list: {},
6939
+ register(attrName, fn) { Transition.list[attrName] = fn; },
6940
+ get(attrName) { return Transition.list[attrName]; }
6941
+ };
6943
6942
 
6944
6943
  const { parse, objectToCanvasData } = PathConvert;
6945
6944
  const emptyPaint = {};
@@ -7363,9 +7362,6 @@ let UI = UI_1 = class UI extends Leaf {
7363
7362
  this.__drawPathByBox(pen);
7364
7363
  return pen;
7365
7364
  }
7366
- get editConfig() { return undefined; }
7367
- get editOuter() { return ''; }
7368
- get editInner() { return ''; }
7369
7365
  constructor(data) {
7370
7366
  super(data);
7371
7367
  }
@@ -7447,8 +7443,11 @@ let UI = UI_1 = class UI extends Leaf {
7447
7443
  export(_filename, _options) {
7448
7444
  return Plugin.need('export');
7449
7445
  }
7446
+ syncExport(_filename, _options) {
7447
+ return Plugin.need('export');
7448
+ }
7450
7449
  clone(data) {
7451
- const json = this.toJSON();
7450
+ const json = DataHelper.clone(this.toJSON());
7452
7451
  if (data)
7453
7452
  Object.assign(json, data);
7454
7453
  return UI_1.one(json);
@@ -7747,7 +7746,7 @@ let Leafer = Leafer_1 = class Leafer extends Group {
7747
7746
  get layoutLocked() { return !this.layouter.running; }
7748
7747
  get FPS() { return this.renderer ? this.renderer.FPS : 60; }
7749
7748
  get cursorPoint() { return (this.interaction && this.interaction.hoverData) || { x: this.width / 2, y: this.height / 2 }; }
7750
- get clientBounds() { return this.canvas && this.canvas.getClientBounds(); }
7749
+ get clientBounds() { return (this.canvas && this.canvas.getClientBounds(true)) || getBoundsData(); }
7751
7750
  constructor(userConfig, data) {
7752
7751
  super(data);
7753
7752
  this.config = {
@@ -8049,6 +8048,10 @@ let Leafer = Leafer_1 = class Leafer extends Group {
8049
8048
  getPagePointByClient(clientPoint, updateClient) {
8050
8049
  return this.getPagePoint(this.getWorldPointByClient(clientPoint, updateClient));
8051
8050
  }
8051
+ getClientPointByWorld(worldPoint) {
8052
+ const { x, y } = this.clientBounds;
8053
+ return { x: x + worldPoint.x, y: y + worldPoint.y };
8054
+ }
8052
8055
  updateClientBounds() {
8053
8056
  this.canvas && this.canvas.updateClientBounds();
8054
8057
  }
@@ -9988,8 +9991,8 @@ leaf$1.__drawHitPath = function (canvas) { if (canvas)
9988
9991
  this.__drawRenderPath(canvas); };
9989
9992
 
9990
9993
  const matrix$2 = new Matrix();
9991
- const ui$3 = UI.prototype;
9992
- ui$3.__updateHitCanvas = function () {
9994
+ const ui$2 = UI.prototype;
9995
+ ui$2.__updateHitCanvas = function () {
9993
9996
  const data = this.__, { hitCanvasManager } = this.leafer;
9994
9997
  const isHitPixelFill = (data.__pixelFill || data.__isCanvas) && data.hitFill === 'pixel';
9995
9998
  const isHitPixelStroke = data.__pixelStroke && data.hitStroke === 'pixel';
@@ -10016,9 +10019,7 @@ ui$3.__updateHitCanvas = function () {
10016
10019
  this.__drawHitPath(h);
10017
10020
  h.setStrokeOptions(data);
10018
10021
  };
10019
- ui$3.__hit = function (inner) {
10020
- if (Platform.name === 'miniapp')
10021
- this.__drawHitPath(this.__hitCanvas);
10022
+ ui$2.__hit = function (inner) {
10022
10023
  const data = this.__;
10023
10024
  if (data.__isHitPixel && this.__hitPixel(inner))
10024
10025
  return true;
@@ -10056,15 +10057,15 @@ ui$3.__hit = function (inner) {
10056
10057
  return hitWidth ? this.__hitStroke(inner, hitWidth) : false;
10057
10058
  };
10058
10059
 
10059
- const ui$2 = UI.prototype, rect = Rect.prototype, box$1 = Box.prototype;
10060
+ const ui$1 = UI.prototype, rect = Rect.prototype, box$1 = Box.prototype;
10060
10061
  rect.__updateHitCanvas = box$1.__updateHitCanvas = function () {
10061
10062
  if (this.stroke || this.cornerRadius || ((this.fill || this.__.__isCanvas) && this.hitFill === 'pixel') || this.hitStroke === 'all')
10062
- ui$2.__updateHitCanvas.call(this);
10063
+ ui$1.__updateHitCanvas.call(this);
10063
10064
  else if (this.__hitCanvas)
10064
10065
  this.__hitCanvas = null;
10065
10066
  };
10066
10067
  rect.__hitFill = box$1.__hitFill = function (inner) {
10067
- return this.__hitCanvas ? ui$2.__hitFill.call(this, inner) : BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner);
10068
+ return this.__hitCanvas ? ui$1.__hitFill.call(this, inner) : BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner);
10068
10069
  };
10069
10070
 
10070
10071
  function getSelector$1(ui) {
@@ -11373,13 +11374,14 @@ function toChar(data, charX, rowData, isOverflow) {
11373
11374
  }
11374
11375
 
11375
11376
  function layoutText(drawData, style) {
11376
- const { rows, bounds } = drawData;
11377
+ const { rows, bounds } = drawData, countRows = rows.length;
11377
11378
  const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing, autoSizeAlign } = style;
11378
- let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
11379
+ let { x, y, width, height } = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
11379
11380
  let starY = __baseLine;
11380
11381
  if (__clipText && realHeight > height) {
11381
11382
  realHeight = Math.max(height, __lineHeight);
11382
- drawData.overflow = rows.length;
11383
+ if (countRows > 1)
11384
+ drawData.overflow = countRows;
11383
11385
  }
11384
11386
  else if (height || autoSizeAlign) {
11385
11387
  switch (verticalAlign) {
@@ -11391,7 +11393,7 @@ function layoutText(drawData, style) {
11391
11393
  }
11392
11394
  starY += y;
11393
11395
  let row, rowX, rowWidth, layoutWidth = (width || autoSizeAlign) ? width : drawData.maxWidth;
11394
- for (let i = 0, len = rows.length; i < len; i++) {
11396
+ for (let i = 0, len = countRows; i < len; i++) {
11395
11397
  row = rows[i];
11396
11398
  row.x = x;
11397
11399
  if (row.width < width || (row.width > width && !__clipText)) {
@@ -11460,7 +11462,7 @@ function clipText(drawData, style, x, width) {
11460
11462
  if (i === end && charRight < right) {
11461
11463
  break;
11462
11464
  }
11463
- else if (charRight < right && char.char !== ' ') {
11465
+ else if ((charRight < right && char.char !== ' ') || !i) {
11464
11466
  row.data.splice(i + 1);
11465
11467
  row.width -= char.width;
11466
11468
  break;
@@ -11604,7 +11606,9 @@ class EditorEvent extends Event {
11604
11606
  Object.assign(this, data);
11605
11607
  }
11606
11608
  }
11609
+ EditorEvent.BEFORE_SELECT = 'editor.before_select';
11607
11610
  EditorEvent.SELECT = 'editor.select';
11611
+ EditorEvent.BEFORE_HOVER = 'editor.before_hover';
11608
11612
  EditorEvent.HOVER = 'editor.hover';
11609
11613
 
11610
11614
  class EditorMoveEvent extends EditorEvent {
@@ -11612,6 +11616,7 @@ class EditorMoveEvent extends EditorEvent {
11612
11616
  super(type, data);
11613
11617
  }
11614
11618
  }
11619
+ EditorMoveEvent.BEFORE_MOVE = 'editor.before_move';
11615
11620
  EditorMoveEvent.MOVE = 'editor.move';
11616
11621
 
11617
11622
  class EditorScaleEvent extends EditorEvent {
@@ -11619,6 +11624,7 @@ class EditorScaleEvent extends EditorEvent {
11619
11624
  super(type, data);
11620
11625
  }
11621
11626
  }
11627
+ EditorScaleEvent.BEFORE_SCALE = 'editor.before_scale';
11622
11628
  EditorScaleEvent.SCALE = 'editor.scale';
11623
11629
 
11624
11630
  class EditorRotateEvent extends EditorEvent {
@@ -11626,6 +11632,7 @@ class EditorRotateEvent extends EditorEvent {
11626
11632
  super(type, data);
11627
11633
  }
11628
11634
  }
11635
+ EditorRotateEvent.BEFORE_ROTATE = 'editor.before_rotate';
11629
11636
  EditorRotateEvent.ROTATE = 'editor.rotate';
11630
11637
 
11631
11638
  class EditorSkewEvent extends EditorEvent {
@@ -11633,6 +11640,7 @@ class EditorSkewEvent extends EditorEvent {
11633
11640
  super(type, data);
11634
11641
  }
11635
11642
  }
11643
+ EditorSkewEvent.BEFORE_SKEW = 'editor.before_skew';
11636
11644
  EditorSkewEvent.SKEW = 'editor.skew';
11637
11645
 
11638
11646
  function targetAttr(fn) {
@@ -11642,8 +11650,12 @@ function targetAttr(fn) {
11642
11650
  get() { return this[privateKey]; },
11643
11651
  set(value) {
11644
11652
  const old = this[privateKey];
11645
- if (old !== value)
11653
+ if (old !== value) {
11654
+ const type = key === 'target' ? EditorEvent.BEFORE_SELECT : EditorEvent.BEFORE_HOVER;
11655
+ if (this.hasEvent(type))
11656
+ this.emitEvent(new EditorEvent(type, { editor: this, value: value, oldValue: old }));
11646
11657
  this[privateKey] = value, fn(this, old);
11658
+ }
11647
11659
  }
11648
11660
  });
11649
11661
  };
@@ -11685,7 +11697,7 @@ class Stroker extends UI {
11685
11697
  for (let i = 0; i < list.length; i++) {
11686
11698
  leaf = list[i];
11687
11699
  const { worldTransform, worldRenderBounds } = leaf;
11688
- if (!bounds || bounds.hit(worldRenderBounds, options.matrix)) {
11700
+ if (worldRenderBounds.width && worldRenderBounds.height && (!bounds || bounds.hit(worldRenderBounds, options.matrix))) {
11689
11701
  const aScaleX = abs$1(worldTransform.scaleX), aScaleY = abs$1(worldTransform.scaleY);
11690
11702
  if (aScaleX !== aScaleY) {
11691
11703
  copy$2(matrix$1, worldTransform);
@@ -11811,9 +11823,9 @@ class EditSelect extends Group {
11811
11823
  }
11812
11824
  onSelect() {
11813
11825
  if (this.running) {
11814
- const { mergeConfig: config, list } = this.editor;
11815
- const { stroke, strokeWidth } = config;
11816
- this.targetStroker.setTarget(list, { stroke, strokeWidth: Math.max(1, strokeWidth / 2) });
11826
+ const { mergeConfig, list } = this.editor;
11827
+ const { stroke, strokeWidth, selectedStyle } = mergeConfig;
11828
+ this.targetStroker.setTarget(list, Object.assign({ stroke, strokeWidth: Math.max(1, strokeWidth / 2) }, (selectedStyle || {})));
11817
11829
  this.hoverStroker.target = null;
11818
11830
  }
11819
11831
  }
@@ -12000,7 +12012,7 @@ const { within } = MathHelper;
12000
12012
  const EditDataHelper = {
12001
12013
  getScaleData(element, startBounds, direction, totalMove, lockRatio, around, flipable, scaleMode) {
12002
12014
  let align, origin = {}, scaleX = 1, scaleY = 1;
12003
- const { boxBounds, widthRange, heightRange, dragBounds } = element;
12015
+ const { boxBounds, widthRange, heightRange, dragBounds, worldBoxBounds } = element;
12004
12016
  const { width, height } = startBounds;
12005
12017
  if (around) {
12006
12018
  totalMove.x *= 2;
@@ -12014,10 +12026,6 @@ const EditDataHelper = {
12014
12026
  const changedScaleY = scaleMode ? originChangedScaleY : signY * boxBounds.height / height;
12015
12027
  totalMove.x *= scaleMode ? originChangedScaleX : signX;
12016
12028
  totalMove.y *= scaleMode ? originChangedScaleY : signY;
12017
- if (Math.abs(totalMove.x) === width)
12018
- totalMove.x += 0.1;
12019
- if (Math.abs(totalMove.y) === height)
12020
- totalMove.y += 0.1;
12021
12029
  const topScale = (-totalMove.y + height) / height;
12022
12030
  const rightScale = (totalMove.x + width) / width;
12023
12031
  const bottomScale = (totalMove.y + height) / height;
@@ -12107,6 +12115,10 @@ const EditDataHelper = {
12107
12115
  const nowHeight = boxBounds.height * element.scaleY;
12108
12116
  scaleY = within(nowHeight * scaleY, heightRange) / nowHeight;
12109
12117
  }
12118
+ if (Math.abs(scaleX * worldBoxBounds.width) < 1)
12119
+ scaleX = (scaleX < 0 ? -1 : 1) / worldBoxBounds.width;
12120
+ if (Math.abs(scaleY * worldBoxBounds.height) < 1)
12121
+ scaleY = (scaleY < 0 ? -1 : 1) / worldBoxBounds.height;
12110
12122
  return { origin, scaleX, scaleY, direction, lockRatio, around };
12111
12123
  },
12112
12124
  getRotateData(bounds, direction, current, last, around) {
@@ -12235,7 +12247,7 @@ function updateCursor(editor, e) {
12235
12247
  let { rotation } = editBox;
12236
12248
  const { resizeCursor, rotateCursor, skewCursor, resizeable, rotateable, skewable } = editor.mergeConfig;
12237
12249
  const { pointType } = point, { flippedX, flippedY } = editBox;
12238
- let showResize = pointType === 'resize';
12250
+ let showResize = pointType.includes('resize');
12239
12251
  if (showResize && rotateable && (e.metaKey || e.ctrlKey || !resizeable))
12240
12252
  showResize = false;
12241
12253
  const showSkew = skewable && !showResize && point.name === 'resize-line';
@@ -12262,7 +12274,7 @@ function toDataURL(svg, rotation) {
12262
12274
  class EditPoint extends Box {
12263
12275
  }
12264
12276
 
12265
- const fourDirection = ['top', 'right', 'bottom', 'left'];
12277
+ const fourDirection = ['top', 'right', 'bottom', 'left'], editConfig = undefined;
12266
12278
  class EditBox extends Group {
12267
12279
  get flipped() { return this.flippedX || this.flippedY; }
12268
12280
  get flippedX() { return this.scaleX < 0; }
@@ -12277,6 +12289,7 @@ class EditBox extends Group {
12277
12289
  this.resizePoints = [];
12278
12290
  this.rotatePoints = [];
12279
12291
  this.resizeLines = [];
12292
+ this.dragStartData = {};
12280
12293
  this.__eventIds = [];
12281
12294
  this.editor = editor;
12282
12295
  this.visible = false;
@@ -12318,7 +12331,7 @@ class EditBox extends Group {
12318
12331
  resizeP.rotation = (i / 2) * 90;
12319
12332
  }
12320
12333
  circle.set(this.getPointStyle(mergeConfig.circle || mergeConfig.rotatePoint || pointsStyle[0]));
12321
- rect.set(Object.assign({ stroke, strokeWidth }, (mergeConfig.rect || {})));
12334
+ rect.set(Object.assign({ stroke, strokeWidth, editConfig }, (mergeConfig.rect || {})));
12322
12335
  rect.hittable = !single;
12323
12336
  rect.syncEventer = single && this.editor;
12324
12337
  if (single) {
@@ -12327,14 +12340,14 @@ class EditBox extends Group {
12327
12340
  }
12328
12341
  }
12329
12342
  update(bounds) {
12330
- this.visible = !this.editor.element.locked;
12343
+ const { mergeConfig, element, multiple } = this.editor;
12344
+ const { middlePoint, resizeable, rotateable, hideOnSmall, editBox } = mergeConfig;
12345
+ this.visible = !element.locked;
12331
12346
  if (this.view.worldOpacity) {
12332
- const { mergeConfig } = this.editor;
12333
12347
  const { width, height } = bounds;
12334
12348
  const { rect, circle, buttons, resizePoints, rotatePoints, resizeLines } = this;
12335
- const { middlePoint, resizeable, rotateable, hideOnSmall } = mergeConfig;
12336
12349
  const smallSize = typeof hideOnSmall === 'number' ? hideOnSmall : 10;
12337
- const showPoints = !(hideOnSmall && width < smallSize && height < smallSize);
12350
+ const showPoints = editBox && !(hideOnSmall && width < smallSize && height < smallSize);
12338
12351
  let point = {}, rotateP, resizeP, resizeL;
12339
12352
  for (let i = 0; i < 8; i++) {
12340
12353
  AroundHelper.toPoint(AroundHelper.directionData[i], bounds, point);
@@ -12350,13 +12363,13 @@ class EditBox extends Group {
12350
12363
  resizeP.visible = rotateP.visible = showPoints && !!middlePoint;
12351
12364
  if (((i + 1) / 2) % 2) {
12352
12365
  resizeL.width = width;
12353
- if (resizeP.width > width - 30)
12366
+ if (hideOnSmall && resizeP.width * 2 > width)
12354
12367
  resizeP.visible = false;
12355
12368
  }
12356
12369
  else {
12357
12370
  resizeL.height = height;
12358
12371
  resizeP.rotation = 90;
12359
- if (resizeP.width > height - 30)
12372
+ if (hideOnSmall && resizeP.width * 2 > height)
12360
12373
  resizeP.visible = false;
12361
12374
  }
12362
12375
  }
@@ -12366,7 +12379,7 @@ class EditBox extends Group {
12366
12379
  this.layoutCircle(mergeConfig);
12367
12380
  if (rect.path)
12368
12381
  rect.path = null;
12369
- rect.set(Object.assign(Object.assign({}, bounds), { visible: true }));
12382
+ rect.set(Object.assign(Object.assign({}, bounds), { visible: multiple ? true : editBox }));
12370
12383
  buttons.visible = showPoints && buttons.children.length > 0;
12371
12384
  if (buttons.visible)
12372
12385
  this.layoutButtons(mergeConfig);
@@ -12413,7 +12426,7 @@ class EditBox extends Group {
12413
12426
  }
12414
12427
  getPointStyle(userStyle) {
12415
12428
  const { stroke, strokeWidth, pointFill, pointSize, pointRadius } = this.editor.mergeConfig;
12416
- const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius, offsetX: 0, offsetY: 0 };
12429
+ const defaultStyle = { fill: pointFill, stroke, strokeWidth, around: 'center', strokeAlign: 'center', width: pointSize, height: pointSize, cornerRadius: pointRadius, offsetX: 0, offsetY: 0, editConfig };
12417
12430
  return userStyle ? Object.assign(defaultStyle, userStyle) : defaultStyle;
12418
12431
  }
12419
12432
  getPointsStyle() {
@@ -12433,34 +12446,32 @@ class EditBox extends Group {
12433
12446
  }
12434
12447
  onDragStart(e) {
12435
12448
  this.dragging = true;
12436
- const { editor } = this;
12437
- if (e.current.name === 'rect') {
12449
+ const point = this.dragPoint = e.current;
12450
+ const { editor, dragStartData } = this, { element } = editor;
12451
+ if (point.name === 'rect') {
12438
12452
  this.moving = true;
12439
- editor.dragStartPoint = { x: editor.element.x, y: editor.element.y };
12440
12453
  editor.opacity = editor.mergeConfig.hideOnMove ? 0 : 1;
12441
12454
  }
12442
- else if (e.current.pointType === 'resize') {
12443
- editor.dragStartBounds = Object.assign({}, editor.element.getLayoutBounds('box', 'local'));
12444
- editor.resizeDirection = e.current.direction;
12445
- }
12455
+ dragStartData.x = e.x;
12456
+ dragStartData.y = e.y;
12457
+ dragStartData.point = { x: element.x, y: element.y };
12458
+ dragStartData.bounds = Object.assign({}, element.getLayoutBounds('box', 'local'));
12459
+ dragStartData.rotation = element.rotation;
12446
12460
  }
12447
12461
  onDragEnd(e) {
12448
12462
  this.dragging = false;
12463
+ this.dragPoint = null;
12449
12464
  this.moving = false;
12450
12465
  if (e.current.name === 'rect')
12451
12466
  this.editor.opacity = 1;
12452
- this.editor.resizeDirection = undefined;
12453
12467
  }
12454
12468
  onDrag(e) {
12455
12469
  const { editor } = this;
12456
- const point = this.enterPoint = e.current;
12457
- if (point.pointType === 'rotate' || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable) {
12458
- if (editor.mergeConfig.rotateable)
12459
- editor.onRotate(e);
12460
- }
12461
- else if (point.pointType === 'resize') {
12470
+ const { pointType } = this.enterPoint = e.current;
12471
+ if (pointType.includes('rotate') || e.metaKey || e.ctrlKey || !editor.mergeConfig.resizeable)
12472
+ editor.onRotate(e);
12473
+ if (pointType.includes('resize'))
12462
12474
  editor.onScale(e);
12463
- }
12464
12475
  updateCursor(editor, e);
12465
12476
  }
12466
12477
  onArrow(e) {
@@ -12638,6 +12649,7 @@ const config = {
12638
12649
  rotateCursor: { url: rotateSVG, x: 12, y: 12 },
12639
12650
  skewCursor: { url: skewSVG, x: 12, y: 12 },
12640
12651
  selector: true,
12652
+ editBox: true,
12641
12653
  hover: true,
12642
12654
  select: 'press',
12643
12655
  openInner: 'double',
@@ -12667,7 +12679,11 @@ function simulate(editor) {
12667
12679
  function onTarget(editor, oldValue) {
12668
12680
  const { target } = editor;
12669
12681
  if (target) {
12670
- editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target);
12682
+ const { list } = editor.leafList = target instanceof LeafList ? target : new LeafList(target instanceof Array ? target : target);
12683
+ if (!list.every(checkEditable)) {
12684
+ editor.target = list.filter(checkEditable);
12685
+ return;
12686
+ }
12671
12687
  if (editor.multiple)
12672
12688
  simulate(editor);
12673
12689
  }
@@ -12694,6 +12710,9 @@ function onTarget(editor, oldValue) {
12694
12710
  function onHover(editor, oldValue) {
12695
12711
  editor.emitEvent(new EditorEvent(EditorEvent.HOVER, { editor, value: editor.hoverTarget, oldValue }));
12696
12712
  }
12713
+ function checkEditable(item) {
12714
+ return item.editable && !item.locked;
12715
+ }
12697
12716
 
12698
12717
  const order = (a, b) => a.parent.children.indexOf(a) - b.parent.children.indexOf(b);
12699
12718
  const reverseOrder = (a, b) => b.parent.children.indexOf(b) - a.parent.children.indexOf(a);
@@ -12791,10 +12810,13 @@ class EditorGroupEvent extends EditorEvent {
12791
12810
  super(type, data);
12792
12811
  }
12793
12812
  }
12813
+ EditorGroupEvent.BEFORE_GROUP = 'editor.before_group';
12794
12814
  EditorGroupEvent.GROUP = 'editor.group';
12795
12815
  EditorGroupEvent.BEFORE_UNGROUP = 'editor.before_ungroup';
12796
12816
  EditorGroupEvent.UNGROUP = 'editor.ungroup';
12817
+ EditorGroupEvent.BEFORE_OPEN = 'editor.before_open_group';
12797
12818
  EditorGroupEvent.OPEN = 'editor.open_group';
12819
+ EditorGroupEvent.BEFORE_CLOSE = 'editor.before_close_group';
12798
12820
  EditorGroupEvent.CLOSE = 'editor.close_group';
12799
12821
 
12800
12822
  const { updateMatrix } = LeafHelper;
@@ -12857,8 +12879,20 @@ class SimulateElement extends Rect {
12857
12879
 
12858
12880
  class Editor extends Group {
12859
12881
  get mergeConfig() {
12860
- const { element, config } = this;
12861
- return this.single && element.editConfig ? Object.assign(Object.assign({}, config), element.editConfig) : config;
12882
+ const { config, element, dragPoint } = this, mergeConfig = Object.assign({}, config);
12883
+ if (element && element.editConfig)
12884
+ Object.assign(mergeConfig, element.editConfig);
12885
+ if (dragPoint) {
12886
+ if (dragPoint.editConfig)
12887
+ Object.assign(mergeConfig, dragPoint.editConfig);
12888
+ if (mergeConfig.editSize === 'font-size')
12889
+ mergeConfig.lockRatio = true;
12890
+ if (dragPoint.pointType === 'resize-rotate') {
12891
+ mergeConfig.around || (mergeConfig.around = 'center');
12892
+ isNull(mergeConfig.lockRatio) && (mergeConfig.lockRatio = true);
12893
+ }
12894
+ }
12895
+ return mergeConfig;
12862
12896
  }
12863
12897
  get list() { return this.leafList.list; }
12864
12898
  get dragHoverExclude() { return [this.editBox.rect]; }
@@ -12868,6 +12902,7 @@ class Editor extends Group {
12868
12902
  get single() { return this.list.length === 1; }
12869
12903
  get dragging() { return this.editBox.dragging; }
12870
12904
  get moving() { return this.editBox.moving; }
12905
+ get dragPoint() { return this.editBox.dragPoint; }
12871
12906
  get element() { return this.multiple ? this.simulateTarget : this.list[0]; }
12872
12907
  get buttons() { return this.editBox.buttons; }
12873
12908
  constructor(userConfig, data) {
@@ -12958,7 +12993,7 @@ class Editor extends Group {
12958
12993
  else
12959
12994
  total.x = 0;
12960
12995
  }
12961
- this.move(DragEvent.getValidMove(this.element, this.dragStartPoint, total));
12996
+ this.move(DragEvent.getValidMove(this.element, this.editBox.dragStartData.point, total));
12962
12997
  }
12963
12998
  }
12964
12999
  onScale(e) {
@@ -12972,7 +13007,7 @@ class Editor extends Group {
12972
13007
  const { direction } = e.current;
12973
13008
  if (e.shiftKey || element.lockRatio)
12974
13009
  lockRatio = true;
12975
- const data = EditDataHelper.getScaleData(element, this.dragStartBounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
13010
+ const data = EditDataHelper.getScaleData(element, this.editBox.dragStartData.bounds, direction, e.getInnerTotal(element), lockRatio, EditDataHelper.getAround(around, e.altKey), flipable, this.multiple || editSize === 'scale');
12976
13011
  if (this.editTool.onScaleWithDrag) {
12977
13012
  data.drag = e;
12978
13013
  this.scaleWithDrag(data);
@@ -12987,26 +13022,29 @@ class Editor extends Group {
12987
13022
  const { direction, name } = e.current;
12988
13023
  if (skewable && name === 'resize-line')
12989
13024
  return this.onSkew(e);
12990
- const { element } = this;
13025
+ const { element } = this, { dragStartData } = this.editBox;
12991
13026
  let origin, rotation;
12992
13027
  if (e instanceof RotateEvent) {
12993
13028
  if (rotateable === 'rotate')
12994
13029
  e.stop(), rotation = e.rotation, origin = element.getBoxPoint(e);
12995
13030
  else
12996
13031
  return;
13032
+ if (element.scaleX * element.scaleY < 0)
13033
+ rotation = -rotation;
12997
13034
  }
12998
13035
  else {
12999
- const last = { x: e.x - e.moveX, y: e.y - e.moveY };
13000
- const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getBoxPoint(element), element.getBoxPoint(last), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
13036
+ const data = EditDataHelper.getRotateData(element.boxBounds, direction, e.getBoxPoint(element), element.getBoxPoint(dragStartData), e.shiftKey ? null : (element.around || element.origin || around || 'center'));
13001
13037
  rotation = data.rotation;
13002
13038
  origin = data.origin;
13003
13039
  }
13004
- rotation = MathHelper.getGapRotation(rotation, rotateGap, element.rotation);
13005
- if (!rotation)
13006
- return;
13007
13040
  if (element.scaleX * element.scaleY < 0)
13008
13041
  rotation = -rotation;
13009
- this.rotateOf(origin, MathHelper.float(rotation, 2));
13042
+ if (e instanceof DragEvent)
13043
+ rotation = dragStartData.rotation + rotation - element.rotation;
13044
+ rotation = MathHelper.float(MathHelper.getGapRotation(rotation, rotateGap, element.rotation), 2);
13045
+ if (!rotation)
13046
+ return;
13047
+ this.rotateOf(origin, rotation);
13010
13048
  }
13011
13049
  onSkew(e) {
13012
13050
  const { element } = this;
@@ -13023,7 +13061,9 @@ class Editor extends Group {
13023
13061
  const world = element.getWorldPointByLocal(typeof x === 'object' ? Object.assign({}, x) : { x, y }, null, true);
13024
13062
  if (this.multiple)
13025
13063
  element.safeChange(() => element.move(x, y));
13026
- const event = new EditorMoveEvent(EditorMoveEvent.MOVE, { target: element, editor: this, moveX: world.x, moveY: world.y });
13064
+ const data = { target: element, editor: this, moveX: world.x, moveY: world.y };
13065
+ this.emitEvent(new EditorMoveEvent(EditorMoveEvent.BEFORE_MOVE, data));
13066
+ const event = new EditorMoveEvent(EditorMoveEvent.MOVE, data);
13027
13067
  this.editTool.onMove(event);
13028
13068
  this.emitEvent(event);
13029
13069
  }
@@ -13031,7 +13071,9 @@ class Editor extends Group {
13031
13071
  if (!this.checkTransform('resizeable'))
13032
13072
  return;
13033
13073
  const { element } = this;
13034
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) }));
13074
+ data = Object.assign(Object.assign({}, data), { target: element, editor: this, worldOrigin: element.getWorldPoint(data.origin) });
13075
+ this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data));
13076
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data);
13035
13077
  this.editTool.onScaleWithDrag(event);
13036
13078
  this.emitEvent(event);
13037
13079
  }
@@ -13041,7 +13083,9 @@ class Editor extends Group {
13041
13083
  const { element } = this;
13042
13084
  const worldOrigin = this.getWorldOrigin(origin);
13043
13085
  const transform = this.multiple && this.getChangedTransform(() => element.safeChange(() => element.scaleOf(origin, scaleX, scaleY)));
13044
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX, scaleY, transform });
13086
+ const data = { target: element, editor: this, worldOrigin, scaleX, scaleY, transform };
13087
+ this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data));
13088
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data);
13045
13089
  this.editTool.onScale(event);
13046
13090
  this.emitEvent(event);
13047
13091
  }
@@ -13051,7 +13095,9 @@ class Editor extends Group {
13051
13095
  const { element } = this;
13052
13096
  const worldOrigin = this.getWorldOrigin('center');
13053
13097
  const transform = this.multiple ? this.getChangedTransform(() => element.safeChange(() => element.flip(axis))) : new Matrix(LeafHelper.getFlipTransform(element, axis));
13054
- const event = new EditorScaleEvent(EditorScaleEvent.SCALE, { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform });
13098
+ const data = { target: element, editor: this, worldOrigin, scaleX: axis === 'x' ? -1 : 1, scaleY: axis === 'y' ? -1 : 1, transform };
13099
+ this.emitEvent(new EditorScaleEvent(EditorScaleEvent.BEFORE_SCALE, data));
13100
+ const event = new EditorScaleEvent(EditorScaleEvent.SCALE, data);
13055
13101
  this.editTool.onScale(event);
13056
13102
  this.emitEvent(event);
13057
13103
  }
@@ -13061,7 +13107,9 @@ class Editor extends Group {
13061
13107
  const { element } = this;
13062
13108
  const worldOrigin = this.getWorldOrigin(origin);
13063
13109
  const transform = this.multiple && this.getChangedTransform(() => element.safeChange(() => element.rotateOf(origin, rotation)));
13064
- const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, { target: element, editor: this, worldOrigin, rotation, transform });
13110
+ const data = { target: element, editor: this, worldOrigin, rotation, transform };
13111
+ this.emitEvent(new EditorRotateEvent(EditorRotateEvent.BEFORE_ROTATE, data));
13112
+ const event = new EditorRotateEvent(EditorRotateEvent.ROTATE, data);
13065
13113
  this.editTool.onRotate(event);
13066
13114
  this.emitEvent(event);
13067
13115
  }
@@ -13071,7 +13119,9 @@ class Editor extends Group {
13071
13119
  const { element } = this;
13072
13120
  const worldOrigin = this.getWorldOrigin(origin);
13073
13121
  const transform = this.multiple && this.getChangedTransform(() => element.safeChange(() => element.skewOf(origin, skewX, skewY)));
13074
- const event = new EditorSkewEvent(EditorSkewEvent.SKEW, { target: element, editor: this, worldOrigin, skewX, skewY, transform });
13122
+ const data = { target: element, editor: this, worldOrigin, skewX, skewY, transform };
13123
+ this.emitEvent(new EditorSkewEvent(EditorSkewEvent.BEFORE_SKEW, data));
13124
+ const event = new EditorSkewEvent(EditorSkewEvent.SKEW, data);
13075
13125
  this.editTool.onSkew(event);
13076
13126
  this.emitEvent(event);
13077
13127
  }
@@ -13089,6 +13139,7 @@ class Editor extends Group {
13089
13139
  }
13090
13140
  group(userGroup) {
13091
13141
  if (this.multiple) {
13142
+ this.emitGroupEvent(EditorGroupEvent.BEFORE_GROUP);
13092
13143
  this.target = EditorHelper.group(this.list, this.element, userGroup);
13093
13144
  this.emitGroupEvent(EditorGroupEvent.GROUP, this.target);
13094
13145
  }
@@ -13104,11 +13155,13 @@ class Editor extends Group {
13104
13155
  return this.list;
13105
13156
  }
13106
13157
  openGroup(group) {
13158
+ this.emitGroupEvent(EditorGroupEvent.BEFORE_OPEN, group);
13107
13159
  this.openedGroupList.add(group);
13108
13160
  group.hitChildren = true;
13109
13161
  this.emitGroupEvent(EditorGroupEvent.OPEN, group);
13110
13162
  }
13111
13163
  closeGroup(group) {
13164
+ this.emitGroupEvent(EditorGroupEvent.BEFORE_CLOSE, group);
13112
13165
  this.openedGroupList.remove(group);
13113
13166
  group.hitChildren = false;
13114
13167
  this.emitGroupEvent(EditorGroupEvent.CLOSE, group);
@@ -13137,7 +13190,8 @@ class Editor extends Group {
13137
13190
  emitGroupEvent(type, group) {
13138
13191
  const event = new EditorGroupEvent(type, { editTarget: group });
13139
13192
  this.emitEvent(event);
13140
- group.emitEvent(event);
13193
+ if (group)
13194
+ group.emitEvent(event);
13141
13195
  }
13142
13196
  openInnerEditor(target, select) {
13143
13197
  if (target && select)
@@ -13554,16 +13608,14 @@ function scaleResize(leaf, scaleX, scaleY) {
13554
13608
  leaf.height *= scaleY;
13555
13609
  }
13556
13610
  }
13557
- function scaleResizeFontSize(leaf, scaleX, scaleY) {
13558
- const { app } = leaf;
13559
- const editor = app && app.editor;
13611
+ function scaleResizeFontSize(leaf, scaleX, scaleY, direction) {
13560
13612
  let fontScale = scaleX;
13561
- if (editor.editing) {
13613
+ if (direction !== undefined) {
13562
13614
  const layout = leaf.__layout;
13563
13615
  let { width, height } = layout.boxBounds;
13564
13616
  width *= scaleY - scaleX;
13565
13617
  height *= scaleX - scaleY;
13566
- switch (editor.resizeDirection) {
13618
+ switch (direction) {
13567
13619
  case top:
13568
13620
  case bottom:
13569
13621
  fontScale = scaleY;
@@ -13631,8 +13683,9 @@ leaf.resizeHeight = function (height) {
13631
13683
  this.scaleOf(this.__layout.boxBounds, this.__.lockRatio ? scale : 1, scale, true);
13632
13684
  };
13633
13685
  Text.prototype.__scaleResize = function (scaleX, scaleY) {
13634
- if (this.__.resizeFontSize || (this.editConfig && this.editConfig.editSize === 'font-size')) {
13635
- scaleResizeFontSize(this, scaleX, scaleY);
13686
+ const { app, editConfig } = this, editor = app && app.editor, dragPoint = editor && editor.dragPoint;
13687
+ if (this.__.resizeFontSize || (editConfig && editConfig.editSize === 'font-size') || (dragPoint && editor.mergeConfig.editSize === 'font-size')) {
13688
+ scaleResizeFontSize(this, scaleX, scaleY, dragPoint && dragPoint.direction);
13636
13689
  }
13637
13690
  else {
13638
13691
  scaleResize(this, scaleX, scaleY);
@@ -13681,34 +13734,15 @@ Plugin.add('resize');
13681
13734
 
13682
13735
  Plugin.add('editor', 'resize');
13683
13736
  Creator.editor = function (options) { return new Editor(options); };
13684
- dataType(false)(Box.prototype, 'textBox');
13685
- defineKey(UI.prototype, 'editOuter', {
13686
- get() { return this.__.__isLinePath ? 'LineEditTool' : 'EditTool'; }
13687
- });
13688
- defineKey(UI.prototype, 'editInner', {
13689
- get() { return 'PathEditor'; }
13690
- });
13691
- defineKey(Group.prototype, 'editInner', {
13692
- get() { return ''; }
13693
- });
13694
- defineKey(Text.prototype, 'editInner', {
13695
- get() { return 'TextEditor'; }
13696
- });
13697
- UI.setEditConfig = function (config) {
13698
- defineKey(this.prototype, 'editConfig', {
13699
- get() { return typeof config === 'function' ? config(this) : config; }
13700
- });
13701
- };
13702
- UI.setEditOuter = function (toolName) {
13703
- defineKey(this.prototype, 'editOuter', {
13704
- get() { return typeof toolName === 'string' ? toolName : toolName(this); }
13705
- });
13706
- };
13707
- UI.setEditInner = function (editorName) {
13708
- defineKey(this.prototype, 'editInner', {
13709
- get() { return typeof editorName === 'string' ? editorName : editorName(this); }
13710
- });
13711
- };
13737
+ Box.addAttr('textBox', false, dataType);
13738
+ UI.addAttr('editConfig', undefined, dataType);
13739
+ UI.addAttr('editOuter', (ui) => ui.__.__isLinePath ? 'LineEditTool' : 'EditTool', dataType);
13740
+ UI.addAttr('editInner', 'PathEditor', dataType);
13741
+ Group.addAttr('editInner', '', dataType);
13742
+ Text.addAttr('editInner', 'TextEditor', dataType);
13743
+ UI.setEditConfig = function (config) { this.changeAttr('editConfig', config); };
13744
+ UI.setEditOuter = function (toolName) { this.changeAttr('editOuter', toolName); };
13745
+ UI.setEditInner = function (editorName) { this.changeAttr('editInner', editorName); };
13712
13746
 
13713
13747
  function addViewport(leafer, mergeConfig, custom) {
13714
13748
  addViewportConfig(leafer.parentApp ? leafer.parentApp : leafer, mergeConfig);
@@ -13719,10 +13753,8 @@ function addViewport(leafer, mergeConfig, custom) {
13719
13753
  }), leafer.on_(ZoomEvent.BEFORE_ZOOM, (e) => {
13720
13754
  const { zoomLayer } = leafer;
13721
13755
  const changeScale = leafer.getValidScale(e.scale);
13722
- if (changeScale !== 1) {
13723
- PointHelper.scaleOf(zoomLayer, e, changeScale);
13724
- zoomLayer.scale = zoomLayer.__.scaleX * changeScale;
13725
- }
13756
+ if (changeScale !== 1)
13757
+ zoomLayer.scaleOfWorld(e, changeScale);
13726
13758
  }));
13727
13759
  }
13728
13760
  function addViewportConfig(leafer, mergeConfig) {
@@ -13949,7 +13981,7 @@ leafer.getValidScale = function (changeScale) {
13949
13981
  changeScale = min / scaleX;
13950
13982
  else if (max && absScale > max)
13951
13983
  changeScale = max / scaleX;
13952
- return disabled ? 1 : MathHelper.float(changeScale);
13984
+ return disabled ? 1 : changeScale;
13953
13985
  };
13954
13986
 
13955
13987
  function getMoveEventData(move, event) {
@@ -14090,7 +14122,7 @@ Leafer.prototype.zoom = function (zoomType, padding, fixed, transition) {
14090
14122
  const limitBounds = this.canvas.bounds.clone().shrink(padding !== undefined ? padding : 30), bounds = new Bounds();
14091
14123
  const center = { x: limitBounds.x + limitBounds.width / 2, y: limitBounds.y + limitBounds.height / 2 };
14092
14124
  let changeScale;
14093
- const { scaleX } = this.__;
14125
+ const { x, y, scaleX, scaleY } = zoomLayer.__;
14094
14126
  if (typeof zoomType === 'string') {
14095
14127
  switch (zoomType) {
14096
14128
  case 'in':
@@ -14120,7 +14152,6 @@ Leafer.prototype.zoom = function (zoomType, padding, fixed, transition) {
14120
14152
  zoomLayer.scaleOfWorld(center, changeScale, changeScale, false, transition);
14121
14153
  }
14122
14154
  else if (typeof zoomType === 'object') {
14123
- const { x, y, scaleX, scaleY } = zoomLayer;
14124
14155
  const data = { x, y, scaleX, scaleY };
14125
14156
  const isArray = zoomType instanceof Array;
14126
14157
  if (isArray || zoomType.tag) {
@@ -14268,6 +14299,18 @@ Plugin.add('scroll');
14268
14299
  class ArrowData extends LineData {
14269
14300
  }
14270
14301
 
14302
+ function arrowType(defaultValue) {
14303
+ return decorateLeafAttr(defaultValue, (key) => attr({
14304
+ set(value) {
14305
+ if (this.__setAttr(key, value)) {
14306
+ const data = this.__;
14307
+ data.__useArrow = data.startArrow !== 'none' || data.endArrow !== 'none';
14308
+ doStrokeType(this);
14309
+ }
14310
+ }
14311
+ }));
14312
+ }
14313
+
14271
14314
  let Arrow = class Arrow extends Line {
14272
14315
  get __tag() { return 'Arrow'; }
14273
14316
  constructor(data) {
@@ -14279,7 +14322,7 @@ __decorate([
14279
14322
  dataProcessor(ArrowData)
14280
14323
  ], Arrow.prototype, "__", void 0);
14281
14324
  __decorate([
14282
- strokeType('angle')
14325
+ arrowType('angle')
14283
14326
  ], Arrow.prototype, "endArrow", void 0);
14284
14327
  Arrow = __decorate([
14285
14328
  registerUI()
@@ -14512,22 +14555,9 @@ function setPoint$1(data, point, startIndex) {
14512
14555
  data[startIndex + 1] = point.y;
14513
14556
  }
14514
14557
 
14515
- function arrowType(defaultValue) {
14516
- return decorateLeafAttr(defaultValue, (key) => attr({
14517
- set(value) {
14518
- if (this.__setAttr(key, value)) {
14519
- const data = this.__;
14520
- data.__useArrow = data.startArrow !== 'none' || data.endArrow !== 'none';
14521
- doStrokeType(this);
14522
- }
14523
- }
14524
- }));
14525
- }
14526
-
14527
14558
  Plugin.add('arrow');
14528
- const ui$1 = UI.prototype;
14529
- arrowType('none')(ui$1, 'startArrow');
14530
- arrowType('none')(ui$1, 'endArrow');
14559
+ UI.addAttr('startArrow', 'none', arrowType);
14560
+ UI.addAttr('endArrow', 'none', arrowType);
14531
14561
  Object.assign(PathArrow, PathArrowModule);
14532
14562
 
14533
14563
  const { Yes, NoAndSkip, YesAndSkip } = Answer;
@@ -14695,124 +14725,134 @@ function getTrimBounds(canvas) {
14695
14725
  }
14696
14726
 
14697
14727
  const ExportModule = {
14698
- export(leaf, filename, options) {
14728
+ syncExport(leaf, filename, options) {
14699
14729
  this.running = true;
14730
+ let result;
14700
14731
  const fileType = FileHelper.fileType(filename);
14701
14732
  const isDownload = filename.includes('.');
14702
14733
  options = FileHelper.getExportOptions(options);
14703
- return addTask((success) => new Promise((resolve) => {
14704
- const over = (result) => {
14705
- success(result);
14706
- resolve();
14707
- this.running = false;
14708
- };
14709
- const { toURL } = Platform;
14710
- const { download } = Platform.origin;
14711
- if (fileType === 'json') {
14712
- isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
14713
- return over({ data: isDownload ? true : leaf.toJSON(options.json) });
14714
- }
14715
- if (fileType === 'svg') {
14716
- isDownload && download(toURL(leaf.toSVG(), 'svg'), filename);
14717
- return over({ data: isDownload ? true : leaf.toSVG() });
14734
+ const { toURL } = Platform;
14735
+ const { download } = Platform.origin;
14736
+ if (fileType === 'json') {
14737
+ isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
14738
+ result = { data: isDownload ? true : leaf.toJSON(options.json) };
14739
+ }
14740
+ else if (fileType === 'svg') {
14741
+ isDownload && download(toURL(leaf.toSVG(), 'svg'), filename);
14742
+ result = { data: isDownload ? true : leaf.toSVG() };
14743
+ }
14744
+ else {
14745
+ let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
14746
+ const { worldTransform, isLeafer, leafer, isFrame } = leaf;
14747
+ const { slice, trim, padding, onCanvas } = options;
14748
+ const smooth = options.smooth === undefined ? (leafer ? leafer.config.smooth : true) : options.smooth;
14749
+ const contextSettings = options.contextSettings || (leafer ? leafer.config.contextSettings : undefined);
14750
+ const screenshot = options.screenshot || leaf.isApp;
14751
+ const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
14752
+ const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
14753
+ if (screenshot) {
14754
+ renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
14718
14755
  }
14719
- const { leafer } = leaf;
14720
- if (leafer) {
14721
- checkLazy(leaf);
14722
- leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
14723
- let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
14724
- const { worldTransform, isLeafer, isFrame } = leaf;
14725
- const { slice, trim, padding, onCanvas } = options;
14726
- const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
14727
- const contextSettings = options.contextSettings || leafer.config.contextSettings;
14728
- const screenshot = options.screenshot || leaf.isApp;
14729
- const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
14730
- const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
14731
- if (screenshot) {
14732
- renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
14733
- }
14734
- else {
14735
- let relative = options.relative || (isLeafer ? 'inner' : 'local');
14736
- scaleX = worldTransform.scaleX;
14737
- scaleY = worldTransform.scaleY;
14738
- switch (relative) {
14739
- case 'inner':
14740
- matrix.set(worldTransform);
14741
- break;
14742
- case 'local':
14743
- matrix.set(worldTransform).divide(leaf.localTransform);
14744
- scaleX /= leaf.scaleX;
14745
- scaleY /= leaf.scaleY;
14746
- break;
14747
- case 'world':
14748
- scaleX = 1;
14749
- scaleY = 1;
14750
- break;
14751
- case 'page':
14752
- relative = leaf.leafer;
14753
- default:
14754
- matrix.set(worldTransform).divide(leaf.getTransform(relative));
14755
- const l = relative.worldTransform;
14756
- scaleX /= scaleX / l.scaleX;
14757
- scaleY /= scaleY / l.scaleY;
14758
- }
14759
- renderBounds = leaf.getBounds('render', relative);
14760
- }
14761
- const scaleData = { scaleX: 1, scaleY: 1 };
14762
- MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData);
14763
- let pixelRatio = options.pixelRatio || 1;
14764
- if (leaf.isApp) {
14765
- scaleData.scaleX *= pixelRatio;
14766
- scaleData.scaleY *= pixelRatio;
14767
- pixelRatio = leaf.app.pixelRatio;
14768
- }
14769
- const { x, y, width, height } = new Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
14770
- const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
14771
- let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
14772
- let sliceLeaf;
14773
- if (slice) {
14774
- sliceLeaf = leaf;
14775
- sliceLeaf.__worldOpacity = 0;
14776
- leaf = leafer;
14777
- renderOptions.bounds = canvas.bounds;
14778
- }
14779
- canvas.save();
14780
- if (isFrame && fill !== undefined) {
14781
- const oldFill = leaf.get('fill');
14782
- leaf.fill = '';
14783
- leaf.__render(canvas, renderOptions);
14784
- leaf.fill = oldFill;
14785
- }
14786
- else {
14787
- leaf.__render(canvas, renderOptions);
14788
- }
14789
- canvas.restore();
14790
- if (sliceLeaf)
14791
- sliceLeaf.__updateWorldOpacity();
14792
- if (trim) {
14793
- trimBounds = getTrimBounds(canvas);
14794
- const old = canvas, { width, height } = trimBounds;
14795
- const config = { x: 0, y: 0, width, height, pixelRatio };
14796
- canvas = Creator.canvas(config);
14797
- canvas.copyWorld(old, trimBounds, config);
14798
- }
14799
- if (padding) {
14800
- const [top, right, bottom, left] = MathHelper.fourNumber(padding);
14801
- const old = canvas, { width, height } = old;
14802
- canvas = Creator.canvas({ width: width + left + right, height: height + top + bottom, pixelRatio });
14803
- canvas.copyWorld(old, old.bounds, { x: left, y: top, width, height });
14804
- }
14805
- if (needFill)
14806
- canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
14807
- if (onCanvas)
14808
- onCanvas(canvas);
14809
- const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
14810
- over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
14811
- }));
14756
+ else {
14757
+ let relative = options.relative || (isLeafer ? 'inner' : 'local');
14758
+ scaleX = worldTransform.scaleX;
14759
+ scaleY = worldTransform.scaleY;
14760
+ switch (relative) {
14761
+ case 'inner':
14762
+ matrix.set(worldTransform);
14763
+ break;
14764
+ case 'local':
14765
+ matrix.set(worldTransform).divide(leaf.localTransform);
14766
+ scaleX /= leaf.scaleX;
14767
+ scaleY /= leaf.scaleY;
14768
+ break;
14769
+ case 'world':
14770
+ scaleX = 1;
14771
+ scaleY = 1;
14772
+ break;
14773
+ case 'page':
14774
+ relative = leafer || leaf;
14775
+ default:
14776
+ matrix.set(worldTransform).divide(leaf.getTransform(relative));
14777
+ const l = relative.worldTransform;
14778
+ scaleX /= scaleX / l.scaleX;
14779
+ scaleY /= scaleY / l.scaleY;
14780
+ }
14781
+ renderBounds = leaf.getBounds('render', relative);
14782
+ }
14783
+ const scaleData = { scaleX: 1, scaleY: 1 };
14784
+ MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData);
14785
+ let pixelRatio = options.pixelRatio || 1;
14786
+ if (leaf.isApp) {
14787
+ scaleData.scaleX *= pixelRatio;
14788
+ scaleData.scaleY *= pixelRatio;
14789
+ pixelRatio = leaf.app.pixelRatio;
14790
+ }
14791
+ const { x, y, width, height } = new Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
14792
+ const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
14793
+ let canvas = Creator.canvas({ width: Math.floor(width), height: Math.floor(height), pixelRatio, smooth, contextSettings });
14794
+ let sliceLeaf;
14795
+ if (slice) {
14796
+ sliceLeaf = leaf;
14797
+ sliceLeaf.__worldOpacity = 0;
14798
+ leaf = leafer || leaf;
14799
+ renderOptions.bounds = canvas.bounds;
14800
+ }
14801
+ canvas.save();
14802
+ if (isFrame && fill !== undefined) {
14803
+ const oldFill = leaf.get('fill');
14804
+ leaf.fill = '';
14805
+ leaf.__render(canvas, renderOptions);
14806
+ leaf.fill = oldFill;
14812
14807
  }
14813
14808
  else {
14814
- over({ data: false });
14809
+ leaf.__render(canvas, renderOptions);
14810
+ }
14811
+ canvas.restore();
14812
+ if (sliceLeaf)
14813
+ sliceLeaf.__updateWorldOpacity();
14814
+ if (trim) {
14815
+ trimBounds = getTrimBounds(canvas);
14816
+ const old = canvas, { width, height } = trimBounds;
14817
+ const config = { x: 0, y: 0, width, height, pixelRatio };
14818
+ canvas = Creator.canvas(config);
14819
+ canvas.copyWorld(old, trimBounds, config);
14815
14820
  }
14821
+ if (padding) {
14822
+ const [top, right, bottom, left] = MathHelper.fourNumber(padding);
14823
+ const old = canvas, { width, height } = old;
14824
+ canvas = Creator.canvas({ width: width + left + right, height: height + top + bottom, pixelRatio });
14825
+ canvas.copyWorld(old, old.bounds, { x: left, y: top, width, height });
14826
+ }
14827
+ if (needFill)
14828
+ canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
14829
+ if (onCanvas)
14830
+ onCanvas(canvas);
14831
+ const data = filename === 'canvas' ? canvas : canvas.export(filename, options);
14832
+ result = { data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds };
14833
+ }
14834
+ this.running = false;
14835
+ return result;
14836
+ },
14837
+ export(leaf, filename, options) {
14838
+ this.running = true;
14839
+ return addTask((success) => new Promise((resolve) => {
14840
+ const getResult = () => __awaiter(this, void 0, void 0, function* () {
14841
+ if (!Resource.isComplete)
14842
+ return Platform.requestRender(getResult);
14843
+ const result = ExportModule.syncExport(leaf, filename, options);
14844
+ if (result.data instanceof Promise)
14845
+ result.data = yield result.data;
14846
+ success(result);
14847
+ resolve();
14848
+ });
14849
+ leaf.updateLayout();
14850
+ checkLazy(leaf);
14851
+ const { leafer } = leaf;
14852
+ if (leafer)
14853
+ leafer.waitViewCompleted(getResult);
14854
+ else
14855
+ getResult();
14816
14856
  }));
14817
14857
  }
14818
14858
  };
@@ -14871,6 +14911,9 @@ Object.assign(Export, ExportModule);
14871
14911
  UI.prototype.export = function (filename, options) {
14872
14912
  return Export.export(this, filename, options);
14873
14913
  };
14914
+ UI.prototype.syncExport = function (filename, options) {
14915
+ return Export.syncExport(this, filename, options);
14916
+ };
14874
14917
 
14875
14918
  const textCaseMap = {
14876
14919
  'none': 'none',
@@ -14979,10 +15022,10 @@ let TextEditor = class TextEditor extends InnerEditor {
14979
15022
  this.onFocus = this.onFocus.bind(this);
14980
15023
  this.onInput = this.onInput.bind(this);
14981
15024
  this.onUpdate = this.onUpdate.bind(this);
14982
- this.onEscape = this.onEscape.bind(this);
15025
+ this.onKeydown = this.onKeydown.bind(this);
14983
15026
  div.addEventListener("focus", this.onFocus);
14984
15027
  div.addEventListener("input", this.onInput);
14985
- window.addEventListener('keydown', this.onEscape);
15028
+ window.addEventListener('keydown', this.onKeydown);
14986
15029
  window.addEventListener('scroll', this.onUpdate);
14987
15030
  const selection = window.getSelection();
14988
15031
  const range = document.createRange();
@@ -15000,14 +15043,25 @@ let TextEditor = class TextEditor extends InnerEditor {
15000
15043
  }
15001
15044
  onInput() {
15002
15045
  const { editDom } = this;
15003
- this.editTarget.text = this.isHTMLText ? editDom.innerHTML : editDom.innerText.replace(/\n\n/, '\n');
15046
+ this.editTarget.text = this.isHTMLText ? editDom.innerHTML : editDom.innerText;
15004
15047
  }
15005
15048
  onFocus() {
15006
15049
  this.editDom.style.outline = 'none';
15007
15050
  }
15008
- onEscape(e) {
15051
+ onKeydown(e) {
15009
15052
  if (e.code === 'Escape')
15010
15053
  this.editor.closeInnerEditor();
15054
+ if (e.key === 'Enter') {
15055
+ e.preventDefault();
15056
+ const br = document.createElement('br');
15057
+ const selection = window.getSelection();
15058
+ const range = selection.getRangeAt(0);
15059
+ range.deleteContents();
15060
+ range.insertNode(br);
15061
+ range.setStartAfter(br);
15062
+ range.setEndAfter(br);
15063
+ this.onInput();
15064
+ }
15011
15065
  }
15012
15066
  onUpdate() {
15013
15067
  const { editTarget: text } = this;
@@ -15063,7 +15117,7 @@ let TextEditor = class TextEditor extends InnerEditor {
15063
15117
  editor.off_(this.eventIds);
15064
15118
  dom.removeEventListener("focus", this.onFocus);
15065
15119
  dom.removeEventListener("input", this.onInput);
15066
- window.removeEventListener('keydown', this.onEscape);
15120
+ window.removeEventListener('keydown', this.onKeydown);
15067
15121
  window.removeEventListener('scroll', this.onUpdate);
15068
15122
  dom.remove();
15069
15123
  this.editDom = this.eventIds = undefined;
@@ -15085,7 +15139,6 @@ class HTMLTextData extends ImageData {
15085
15139
 
15086
15140
  let HTMLText = class HTMLText extends Image {
15087
15141
  get __tag() { return 'HTMLText'; }
15088
- get editInner() { return 'TextEditor'; }
15089
15142
  constructor(data) {
15090
15143
  super(data);
15091
15144
  }
@@ -15130,6 +15183,9 @@ __decorate([
15130
15183
  __decorate([
15131
15184
  boundsType('')
15132
15185
  ], HTMLText.prototype, "text", void 0);
15186
+ __decorate([
15187
+ dataType('TextEditor')
15188
+ ], HTMLText.prototype, "editInner", void 0);
15133
15189
  HTMLText = __decorate([
15134
15190
  registerUI()
15135
15191
  ], HTMLText);