@leafer-editor/worker 1.4.2 → 1.5.0

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