leafer-draw 1.5.3 → 1.6.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.
@@ -45,7 +45,7 @@ const IncrementId = {
45
45
  };
46
46
  const I$1 = IncrementId;
47
47
 
48
- const { round, pow: pow$1, PI: PI$4 } = Math;
48
+ const { round: round$3, pow: pow$1, PI: PI$4 } = Math;
49
49
  const MathHelper = {
50
50
  within(value, min, max) {
51
51
  if (typeof min === 'object')
@@ -109,7 +109,7 @@ const MathHelper = {
109
109
  },
110
110
  float(num, maxLength) {
111
111
  const a = maxLength !== undefined ? pow$1(10, maxLength) : 1000000000000;
112
- num = round(num * a) / a;
112
+ num = round$3(num * a) / a;
113
113
  return num === -0 ? 0 : num;
114
114
  },
115
115
  getScaleData(scale, size, originSize, scaleData) {
@@ -132,8 +132,15 @@ const MathHelper = {
132
132
  scaleData.scaleX = scale.x;
133
133
  scaleData.scaleY = scale.y;
134
134
  }
135
+ },
136
+ randInt,
137
+ randColor(opacity) {
138
+ return `rgba(${randInt(255)},${randInt(255)},${randInt(255)},${opacity || 1})`;
135
139
  }
136
140
  };
141
+ function randInt(num) {
142
+ return Math.round(Math.random() * num);
143
+ }
137
144
  const OneRadian = PI$4 / 180;
138
145
  const PI2 = PI$4 * 2;
139
146
  const PI_2 = PI$4 / 2;
@@ -431,7 +438,7 @@ const MatrixHelper = {
431
438
  const M$6 = MatrixHelper;
432
439
 
433
440
  const { toInnerPoint: toInnerPoint$2, toOuterPoint: toOuterPoint$3 } = MatrixHelper;
434
- const { sin: sin$4, cos: cos$4, abs: abs$4, sqrt: sqrt$2, atan2: atan2$2, min: min$1, PI: PI$3 } = Math;
441
+ const { sin: sin$4, cos: cos$4, abs: abs$4, sqrt: sqrt$2, atan2: atan2$2, min: min$1, round: round$2, PI: PI$3 } = Math;
435
442
  const PointHelper = {
436
443
  defaultPoint: getPointData(),
437
444
  tempPoint: {},
@@ -452,6 +459,10 @@ const PointHelper = {
452
459
  t.x = x;
453
460
  t.y = y;
454
461
  },
462
+ round(t, halfPixel) {
463
+ t.x = halfPixel ? round$2(t.x - 0.5) + 0.5 : round$2(t.x);
464
+ t.y = halfPixel ? round$2(t.y - 0.5) + 0.5 : round$2(t.y);
465
+ },
455
466
  move(t, x, y) {
456
467
  t.x += x;
457
468
  t.y += y;
@@ -1317,6 +1328,7 @@ const StringNumberMap = {
1317
1328
  'E': 1
1318
1329
  };
1319
1330
 
1331
+ const { randColor } = MathHelper;
1320
1332
  class Debug {
1321
1333
  constructor(name) {
1322
1334
  this.repeatMap = {};
@@ -1331,6 +1343,19 @@ class Debug {
1331
1343
  static set exclude(name) {
1332
1344
  this.excludeList = getNameList(name);
1333
1345
  }
1346
+ static drawRepaint(canvas, bounds) {
1347
+ const color = randColor();
1348
+ canvas.fillWorld(bounds, color.replace('1)', '.1)'));
1349
+ canvas.strokeWorld(bounds, color);
1350
+ }
1351
+ static drawBounds(leaf, canvas, _options) {
1352
+ const showHit = Debug.showBounds === 'hit', w = leaf.__nowWorld, color = randColor();
1353
+ if (showHit)
1354
+ canvas.setWorld(w), leaf.__drawHitPath(canvas), canvas.fillStyle = color.replace('1)', '.2)'), canvas.fill();
1355
+ canvas.resetTransform();
1356
+ canvas.setStroke(color, 2);
1357
+ showHit ? canvas.stroke() : canvas.strokeWorld(w, color);
1358
+ }
1334
1359
  log(...messages) {
1335
1360
  if (D$4.enable) {
1336
1361
  if (D$4.filterList.length && D$4.filterList.every(name => name !== this.name))
@@ -1417,7 +1442,7 @@ const Plugin = {
1417
1442
  return rs;
1418
1443
  },
1419
1444
  need(name) {
1420
- console.error('need plugin: ' + (name.includes('-x') ? '' : '@leafer-in/') + name);
1445
+ console.error('please install plugin: ' + (name.includes('-x') ? '' : '@leafer-in/') + name);
1421
1446
  }
1422
1447
  };
1423
1448
  setTimeout(() => check.forEach(name => Plugin.has(name, true)));
@@ -2017,7 +2042,7 @@ __decorate([
2017
2042
  contextMethod()
2018
2043
  ], Canvas$1.prototype, "strokeText", null);
2019
2044
 
2020
- const { copy: copy$8 } = MatrixHelper;
2045
+ const { copy: copy$8, multiplyParent: multiplyParent$3 } = MatrixHelper, { round: round$1 } = Math;
2021
2046
  const minSize = { width: 1, height: 1, pixelRatio: 1 };
2022
2047
  const canvasSizeAttrs = ['width', 'height', 'pixelRatio'];
2023
2048
  class LeaferCanvasBase extends Canvas$1 {
@@ -2026,6 +2051,8 @@ class LeaferCanvasBase extends Canvas$1 {
2026
2051
  get pixelRatio() { return this.size.pixelRatio; }
2027
2052
  get pixelWidth() { return this.width * this.pixelRatio; }
2028
2053
  get pixelHeight() { return this.height * this.pixelRatio; }
2054
+ get pixelSnap() { return this.config.pixelSnap; }
2055
+ set pixelSnap(value) { this.config.pixelSnap = value; }
2029
2056
  get allowBackgroundColor() { return this.view && this.parentView; }
2030
2057
  constructor(config, manager) {
2031
2058
  super();
@@ -2086,15 +2113,22 @@ class LeaferCanvasBase extends Canvas$1 {
2086
2113
  stopAutoLayout() { }
2087
2114
  setCursor(_cursor) { }
2088
2115
  setWorld(matrix, parentMatrix) {
2089
- const { pixelRatio } = this;
2090
- const w = this.worldTransform;
2091
- if (parentMatrix) {
2092
- const { a, b, c, d, e, f } = parentMatrix;
2093
- this.setTransform(w.a = ((matrix.a * a) + (matrix.b * c)) * pixelRatio, w.b = ((matrix.a * b) + (matrix.b * d)) * pixelRatio, w.c = ((matrix.c * a) + (matrix.d * c)) * pixelRatio, w.d = ((matrix.c * b) + (matrix.d * d)) * pixelRatio, w.e = (((matrix.e * a) + (matrix.f * c) + e)) * pixelRatio, w.f = (((matrix.e * b) + (matrix.f * d) + f)) * pixelRatio);
2094
- }
2095
- else {
2096
- this.setTransform(w.a = matrix.a * pixelRatio, w.b = matrix.b * pixelRatio, w.c = matrix.c * pixelRatio, w.d = matrix.d * pixelRatio, w.e = matrix.e * pixelRatio, w.f = matrix.f * pixelRatio);
2116
+ const { pixelRatio, pixelSnap } = this, w = this.worldTransform;
2117
+ if (parentMatrix)
2118
+ multiplyParent$3(matrix, parentMatrix, w);
2119
+ w.a = matrix.a * pixelRatio;
2120
+ w.b = matrix.b * pixelRatio;
2121
+ w.c = matrix.c * pixelRatio;
2122
+ w.d = matrix.d * pixelRatio;
2123
+ w.e = matrix.e * pixelRatio;
2124
+ w.f = matrix.f * pixelRatio;
2125
+ if (pixelSnap) {
2126
+ if (matrix.half && (matrix.half * pixelRatio) % 2)
2127
+ w.e = round$1(w.e - 0.5) + 0.5, w.f = round$1(w.f - 0.5) + 0.5;
2128
+ else
2129
+ w.e = round$1(w.e), w.f = round$1(w.f);
2097
2130
  }
2131
+ this.setTransform(w.a, w.b, w.c, w.d, w.e, w.f);
2098
2132
  }
2099
2133
  useWorldTransform(worldTransform) {
2100
2134
  if (worldTransform)
@@ -2237,12 +2271,13 @@ class LeaferCanvasBase extends Canvas$1 {
2237
2271
  return this.width === size.width && this.height === size.height && (!size.pixelRatio || this.pixelRatio === size.pixelRatio);
2238
2272
  }
2239
2273
  getSameCanvas(useSameWorldTransform, useSameSmooth) {
2240
- const canvas = this.manager ? this.manager.get(this.size) : Creator.canvas(Object.assign({}, this.size));
2274
+ const { size, pixelSnap } = this, canvas = this.manager ? this.manager.get(size) : Creator.canvas(Object.assign({}, size));
2241
2275
  canvas.save();
2242
2276
  if (useSameWorldTransform)
2243
2277
  copy$8(canvas.worldTransform, this.worldTransform), canvas.useWorldTransform();
2244
2278
  if (useSameSmooth)
2245
2279
  canvas.smooth = this.smooth;
2280
+ canvas.pixelSnap !== pixelSnap && (canvas.pixelSnap = pixelSnap);
2246
2281
  return canvas;
2247
2282
  }
2248
2283
  recycle(clearBounds) {
@@ -3669,7 +3704,7 @@ const Resource = {
3669
3704
  const R = Resource;
3670
3705
 
3671
3706
  const ImageManager = {
3672
- maxRecycled: 100,
3707
+ maxRecycled: 10,
3673
3708
  recycledList: [],
3674
3709
  patternTasker: new TaskProcessor(),
3675
3710
  get(config) {
@@ -4022,9 +4057,8 @@ function hitType(defaultValue) {
4022
4057
  set(value) {
4023
4058
  if (this.__setAttr(key, value)) {
4024
4059
  this.__layout.hitCanvasChanged = true;
4025
- if (Debug.showHitView) {
4060
+ if (Debug.showBounds === 'hit')
4026
4061
  this.__layout.surfaceChanged || this.__layout.surfaceChange();
4027
- }
4028
4062
  if (this.leafer)
4029
4063
  this.leafer.updateCursor();
4030
4064
  }
@@ -4185,7 +4219,7 @@ function registerUIEvent() {
4185
4219
  }
4186
4220
 
4187
4221
  const { copy: copy$6, toInnerPoint: toInnerPoint$1, toOuterPoint: toOuterPoint$1, scaleOfOuter: scaleOfOuter$2, rotateOfOuter: rotateOfOuter$2, skewOfOuter, multiplyParent: multiplyParent$2, divideParent, getLayout } = MatrixHelper;
4188
- const matrix = {};
4222
+ const matrix = {}, { round } = Math;
4189
4223
  const LeafHelper = {
4190
4224
  updateAllMatrix(leaf, checkAutoLayout, waitAutoLayout) {
4191
4225
  if (checkAutoLayout && leaf.__hasAutoLayout && leaf.__layout.matrixChanged)
@@ -4259,6 +4293,8 @@ const LeafHelper = {
4259
4293
  y = x.y, x = x.x;
4260
4294
  x += t.x;
4261
4295
  y += t.y;
4296
+ if (t.leafer && t.leafer.config.pointSnap)
4297
+ x = round(x), y = round(y);
4262
4298
  transition ? t.animate({ x, y }, transition) : (t.x = x, t.y = y);
4263
4299
  },
4264
4300
  zoomOfWorld(t, origin, scaleX, scaleY, resize, transition) {
@@ -4497,6 +4533,7 @@ class LeafLayout {
4497
4533
  set contentBounds(bounds) { this._contentBounds = bounds; }
4498
4534
  get strokeBounds() { return this._strokeBounds || this.boxBounds; }
4499
4535
  get renderBounds() { return this._renderBounds || this.boxBounds; }
4536
+ set renderBounds(bounds) { this._renderBounds = bounds; }
4500
4537
  get localContentBounds() { toOuterOf$2(this.contentBounds, this.leaf.__localMatrix, this[localContent] || (this[localContent] = {})); return this[localContent]; }
4501
4538
  get localStrokeBounds() { return this._localStrokeBounds || this; }
4502
4539
  get localRenderBounds() { return this._localRenderBounds || this; }
@@ -4515,11 +4552,13 @@ class LeafLayout {
4515
4552
  get height() { return this.boxBounds.height; }
4516
4553
  constructor(leaf) {
4517
4554
  this.leaf = leaf;
4518
- this.boxBounds = { x: 0, y: 0, width: 0, height: 0 };
4519
4555
  if (this.leaf.__local)
4520
4556
  this._localRenderBounds = this._localStrokeBounds = this.leaf.__local;
4521
- this.boxChange();
4522
- this.matrixChange();
4557
+ if (leaf.__world) {
4558
+ this.boxBounds = { x: 0, y: 0, width: 0, height: 0 };
4559
+ this.boxChange();
4560
+ this.matrixChange();
4561
+ }
4523
4562
  }
4524
4563
  createLocal() {
4525
4564
  const local = this.leaf.__local = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0 };
@@ -4851,6 +4890,9 @@ class ResizeEvent extends Event {
4851
4890
  }
4852
4891
  this.old = oldSize;
4853
4892
  }
4893
+ static isResizing(leaf) {
4894
+ return this.resizingKeys && this.resizingKeys[leaf.innerId] !== undefined;
4895
+ }
4854
4896
  }
4855
4897
  ResizeEvent.RESIZE = 'resize';
4856
4898
 
@@ -4893,6 +4935,7 @@ class RenderEvent extends Event {
4893
4935
  }
4894
4936
  RenderEvent.REQUEST = 'render.request';
4895
4937
  RenderEvent.CHILD_START = 'render.child_start';
4938
+ RenderEvent.CHILD_END = 'render.child_end';
4896
4939
  RenderEvent.START = 'render.start';
4897
4940
  RenderEvent.BEFORE = 'render.before';
4898
4941
  RenderEvent.RENDER = 'render';
@@ -5272,24 +5315,27 @@ const LeafBounds = {
5272
5315
  const LeafRender = {
5273
5316
  __render(canvas, options) {
5274
5317
  if (this.__worldOpacity) {
5318
+ const data = this.__;
5275
5319
  canvas.setWorld(this.__nowWorld = this.__getNowWorld(options));
5276
- canvas.opacity = this.__.opacity;
5320
+ canvas.opacity = options.dimOpacity && !data.dimskip ? data.opacity * options.dimOpacity : data.opacity;
5277
5321
  if (this.__.__single) {
5278
- if (this.__.eraser === 'path')
5322
+ if (data.eraser === 'path')
5279
5323
  return this.__renderEraser(canvas, options);
5280
5324
  const tempCanvas = canvas.getSameCanvas(true, true);
5281
5325
  this.__draw(tempCanvas, options, canvas);
5282
5326
  if (this.__worldFlipped) {
5283
- canvas.copyWorldByReset(tempCanvas, this.__nowWorld, null, this.__.__blendMode, true);
5327
+ canvas.copyWorldByReset(tempCanvas, this.__nowWorld, null, data.__blendMode, true);
5284
5328
  }
5285
5329
  else {
5286
- canvas.copyWorldToInner(tempCanvas, this.__nowWorld, this.__layout.renderBounds, this.__.__blendMode);
5330
+ canvas.copyWorldToInner(tempCanvas, this.__nowWorld, this.__layout.renderBounds, data.__blendMode);
5287
5331
  }
5288
5332
  tempCanvas.recycle(this.__nowWorld);
5289
5333
  }
5290
5334
  else {
5291
5335
  this.__draw(canvas, options);
5292
5336
  }
5337
+ if (Debug.showBounds)
5338
+ Debug.drawBounds(this, canvas, options);
5293
5339
  }
5294
5340
  },
5295
5341
  __clip(canvas, options) {
@@ -5319,14 +5365,19 @@ const BranchRender = {
5319
5365
  __render(canvas, options) {
5320
5366
  this.__nowWorld = this.__getNowWorld(options);
5321
5367
  if (this.__worldOpacity) {
5322
- if (this.__.__single) {
5323
- if (this.__.eraser === 'path')
5368
+ const data = this.__;
5369
+ if (data.dim)
5370
+ options.dimOpacity = data.dim === true ? 0.2 : data.dim;
5371
+ else if (data.dimskip)
5372
+ options.dimOpacity && (options.dimOpacity = 0);
5373
+ if (data.__single) {
5374
+ if (data.eraser === 'path')
5324
5375
  return this.__renderEraser(canvas, options);
5325
5376
  const tempCanvas = canvas.getSameCanvas(false, true);
5326
5377
  this.__renderBranch(tempCanvas, options);
5327
5378
  const nowWorld = this.__nowWorld;
5328
- canvas.opacity = this.__.opacity;
5329
- canvas.copyWorldByReset(tempCanvas, nowWorld, nowWorld, this.__.__blendMode, true);
5379
+ canvas.opacity = options.dimOpacity ? data.opacity * options.dimOpacity : data.opacity;
5380
+ canvas.copyWorldByReset(tempCanvas, nowWorld, nowWorld, data.__blendMode, true);
5330
5381
  tempCanvas.recycle(nowWorld);
5331
5382
  }
5332
5383
  else {
@@ -5401,9 +5452,11 @@ let Leaf = class Leaf {
5401
5452
  reset(data) {
5402
5453
  if (this.leafer)
5403
5454
  this.leafer.forceRender(this.__world);
5404
- this.__world = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0, scaleX: 1, scaleY: 1 };
5405
- if (data !== null)
5406
- this.__local = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0 };
5455
+ if (data !== 0) {
5456
+ this.__world = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0, scaleX: 1, scaleY: 1 };
5457
+ if (data !== null)
5458
+ this.__local = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0, x: 0, y: 0, width: 0, height: 0 };
5459
+ }
5407
5460
  this.__worldOpacity = 1;
5408
5461
  this.__ = new this.__DataProcessor(this);
5409
5462
  this.__layout = new this.__LayoutProcessor(this);
@@ -5539,9 +5592,10 @@ let Leaf = class Leaf {
5539
5592
  if (options.matrix) {
5540
5593
  if (!this.__cameraWorld)
5541
5594
  this.__cameraWorld = {};
5542
- const cameraWorld = this.__cameraWorld;
5543
- multiplyParent(this.__world, options.matrix, cameraWorld, undefined, this.__world);
5595
+ const cameraWorld = this.__cameraWorld, world = this.__world;
5596
+ multiplyParent(world, options.matrix, cameraWorld, undefined, world);
5544
5597
  toOuterOf(this.__layout.renderBounds, cameraWorld, cameraWorld);
5598
+ cameraWorld.half !== world.half && (cameraWorld.half = world.half);
5545
5599
  return cameraWorld;
5546
5600
  }
5547
5601
  else {
@@ -5701,7 +5755,7 @@ let Leaf = class Leaf {
5701
5755
  __updateHitCanvas() { }
5702
5756
  __render(_canvas, _options) { }
5703
5757
  __drawFast(_canvas, _options) { }
5704
- __draw(_canvas, _options) { }
5758
+ __draw(_canvas, _options, _originCanvas) { }
5705
5759
  __clip(_canvas, _options) { }
5706
5760
  __renderShape(_canvas, _options, _ignoreFill, _ignoreStroke) { }
5707
5761
  __updateWorldOpacity() { }
@@ -6071,7 +6125,7 @@ class LeafLevelList {
6071
6125
  }
6072
6126
  }
6073
6127
 
6074
- const version = "1.5.3";
6128
+ const version = "1.6.0";
6075
6129
 
6076
6130
  const debug$4 = Debug.get('LeaferCanvas');
6077
6131
  class LeaferCanvas extends LeaferCanvasBase {
@@ -6492,7 +6546,6 @@ function updateChange(updateList) {
6492
6546
  }
6493
6547
 
6494
6548
  const { worldBounds } = LeafBoundsHelper;
6495
- const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
6496
6549
  class LayoutBlockData {
6497
6550
  constructor(list) {
6498
6551
  this.updatedBounds = new Bounds();
@@ -6506,13 +6559,7 @@ class LayoutBlockData {
6506
6559
  this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
6507
6560
  }
6508
6561
  setAfter() {
6509
- const { list } = this.updatedList;
6510
- if (list.some(leaf => leaf.noBounds)) {
6511
- this.afterBounds.set(bigBounds);
6512
- }
6513
- else {
6514
- this.afterBounds.setListWithFn(list, worldBounds);
6515
- }
6562
+ this.afterBounds.setListWithFn(this.updatedList.list, worldBounds);
6516
6563
  this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
6517
6564
  }
6518
6565
  merge(data) {
@@ -6714,6 +6761,13 @@ class Renderer {
6714
6761
  requestLayout() {
6715
6762
  this.target.emit(LayoutEvent.REQUEST);
6716
6763
  }
6764
+ checkRender() {
6765
+ if (this.running) {
6766
+ if (this.changed && this.canvas.view)
6767
+ this.render();
6768
+ this.target.emit(RenderEvent.NEXT);
6769
+ }
6770
+ }
6717
6771
  render(callback) {
6718
6772
  if (!(this.running && this.canvas.view))
6719
6773
  return this.update();
@@ -6722,8 +6776,6 @@ class Renderer {
6722
6776
  this.totalBounds = new Bounds();
6723
6777
  debug$2.log(target.innerName, '--->');
6724
6778
  try {
6725
- if (!target.isApp)
6726
- target.app.emit(RenderEvent.CHILD_START, target);
6727
6779
  this.emitRender(RenderEvent.START);
6728
6780
  this.renderOnce(callback);
6729
6781
  this.emitRender(RenderEvent.END, this.totalBounds);
@@ -6791,20 +6843,12 @@ class Renderer {
6791
6843
  }
6792
6844
  clipRender(block) {
6793
6845
  const t = Run.start('PartRender');
6794
- const { canvas } = this;
6795
- const bounds = block.getIntersect(canvas.bounds);
6796
- const includes = block.includes(this.target.__world);
6797
- const realBounds = new Bounds(bounds);
6846
+ const { canvas } = this, bounds = block.getIntersect(canvas.bounds), realBounds = new Bounds(bounds);
6798
6847
  canvas.save();
6799
- if (includes && !Debug.showRepaint) {
6800
- canvas.clear();
6801
- }
6802
- else {
6803
- bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
6804
- canvas.clearWorld(bounds, true);
6805
- canvas.clipWorld(bounds, true);
6806
- }
6807
- this.__render(bounds, includes, realBounds);
6848
+ bounds.spread(Renderer.clipSpread).ceil();
6849
+ canvas.clearWorld(bounds, true);
6850
+ canvas.clipWorld(bounds, true);
6851
+ this.__render(bounds, block.includes(this.target.__world), realBounds);
6808
6852
  canvas.restore();
6809
6853
  Run.end(t);
6810
6854
  }
@@ -6818,23 +6862,17 @@ class Renderer {
6818
6862
  Run.end(t);
6819
6863
  }
6820
6864
  __render(bounds, includes, realBounds) {
6821
- const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
6865
+ const { canvas } = this, options = includes ? { includes } : { bounds, includes };
6822
6866
  if (this.needFill)
6823
- this.canvas.fillWorld(bounds, this.config.fill);
6867
+ canvas.fillWorld(bounds, this.config.fill);
6824
6868
  if (Debug.showRepaint)
6825
- this.canvas.strokeWorld(bounds, 'red');
6826
- this.target.__render(this.canvas, options);
6869
+ Debug.drawRepaint(canvas, bounds);
6870
+ this.target.__render(canvas, options);
6827
6871
  this.renderBounds = realBounds = realBounds || bounds;
6828
6872
  this.renderOptions = options;
6829
6873
  this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
6830
- if (Debug.showHitView)
6831
- this.renderHitView(options);
6832
- if (Debug.showBoundsView)
6833
- this.renderBoundsView(options);
6834
- this.canvas.updateRender(realBounds);
6835
- }
6836
- renderHitView(_options) { }
6837
- renderBoundsView(_options) { }
6874
+ canvas.updateRender(realBounds);
6875
+ }
6838
6876
  addBlock(block) {
6839
6877
  if (!this.updateBlocks)
6840
6878
  this.updateBlocks = [];
@@ -6850,17 +6888,24 @@ class Renderer {
6850
6888
  }
6851
6889
  }
6852
6890
  __requestRender() {
6891
+ const target = this.target;
6892
+ if (target.parentApp)
6893
+ return target.parentApp.renderer.update(false);
6853
6894
  if (this.requestTime)
6854
6895
  return;
6855
6896
  const requestTime = this.requestTime = Date.now();
6856
6897
  Platform.requestRender(() => {
6857
6898
  this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - requestTime)));
6858
6899
  this.requestTime = 0;
6859
- if (this.running) {
6860
- if (this.changed && this.canvas.view)
6861
- this.render();
6862
- this.target.emit(RenderEvent.NEXT);
6900
+ if (target.isApp) {
6901
+ target.emit(RenderEvent.CHILD_START, target);
6902
+ target.children.forEach(leafer => {
6903
+ leafer.renderer.FPS = this.FPS;
6904
+ leafer.renderer.checkRender();
6905
+ });
6906
+ target.emit(RenderEvent.CHILD_END, target);
6863
6907
  }
6908
+ this.checkRender();
6864
6909
  });
6865
6910
  }
6866
6911
  __onResize(e) {
@@ -6918,6 +6963,7 @@ class Renderer {
6918
6963
  }
6919
6964
  }
6920
6965
  }
6966
+ Renderer.clipSpread = 10;
6921
6967
 
6922
6968
  Object.assign(Creator, {
6923
6969
  watcher: (target, options) => new Watcher(target, options),
@@ -7006,6 +7052,7 @@ class UIData extends LeafData {
7006
7052
  return strokeWidth;
7007
7053
  }
7008
7054
  get __hasStroke() { return this.stroke && this.strokeWidth; }
7055
+ get __hasHalf() { const t = this; return (t.stroke && t.strokeAlign === 'center' && t.strokeWidth % 2) || undefined; }
7009
7056
  get __hasMultiPaint() {
7010
7057
  const t = this;
7011
7058
  if ((t.__isFills && t.fill.length > 1) || (t.__isStrokes && t.stroke.length > 1) || t.__useEffect)
@@ -7050,14 +7097,14 @@ class UIData extends LeafData {
7050
7097
  this.__removeInput('fill');
7051
7098
  PaintImage.recycleImage('fill', this);
7052
7099
  this.__isFills = false;
7053
- if (this.__pixelFill)
7054
- this.__pixelFill = false;
7100
+ this.__pixelFill && (this.__pixelFill = false);
7055
7101
  }
7056
7102
  this._fill = value;
7057
7103
  }
7058
7104
  else if (typeof value === 'object') {
7059
7105
  this.__setInput('fill', value);
7060
- this.__leaf.__layout.boxChanged || this.__leaf.__layout.boxChange();
7106
+ const layout = this.__leaf.__layout;
7107
+ layout.boxChanged || layout.boxChange();
7061
7108
  this.__isFills = true;
7062
7109
  this._fill || (this._fill = emptyPaint);
7063
7110
  }
@@ -7068,14 +7115,14 @@ class UIData extends LeafData {
7068
7115
  this.__removeInput('stroke');
7069
7116
  PaintImage.recycleImage('stroke', this);
7070
7117
  this.__isStrokes = false;
7071
- if (this.__pixelStroke)
7072
- this.__pixelStroke = false;
7118
+ this.__pixelStroke && (this.__pixelStroke = false);
7073
7119
  }
7074
7120
  this._stroke = value;
7075
7121
  }
7076
7122
  else if (typeof value === 'object') {
7077
7123
  this.__setInput('stroke', value);
7078
- this.__leaf.__layout.boxChanged || this.__leaf.__layout.boxChange();
7124
+ const layout = this.__leaf.__layout;
7125
+ layout.boxChanged || layout.boxChange();
7079
7126
  this.__isStrokes = true;
7080
7127
  this._stroke || (this._stroke = emptyPaint);
7081
7128
  }
@@ -7190,6 +7237,31 @@ class TextData extends UIData {
7190
7237
  this._fontWeight = value;
7191
7238
  }
7192
7239
  }
7240
+ setBoxStyle(value) {
7241
+ let t = this.__leaf, box = t.__box;
7242
+ if (value) {
7243
+ const { boxStyle } = this;
7244
+ if (box)
7245
+ for (let key in boxStyle)
7246
+ box[key] = undefined;
7247
+ else
7248
+ box = t.__box = UICreator.get('Rect', 0);
7249
+ const layout = t.__layout, boxLayout = box.__layout;
7250
+ if (!boxStyle)
7251
+ box.parent = t, box.__world = t.__world, boxLayout.boxBounds = layout.boxBounds;
7252
+ box.set(value);
7253
+ if (boxLayout.strokeChanged)
7254
+ layout.strokeChange();
7255
+ if (boxLayout.renderChanged)
7256
+ layout.renderChange();
7257
+ box.__updateChange();
7258
+ }
7259
+ else if (box) {
7260
+ t.__box = box.parent = null;
7261
+ box.destroy();
7262
+ }
7263
+ this._boxStyle = value;
7264
+ }
7193
7265
  }
7194
7266
 
7195
7267
  class ImageData extends RectData {
@@ -7227,7 +7299,7 @@ class CanvasData extends RectData {
7227
7299
  const UIBounds = {
7228
7300
  __updateStrokeSpread() {
7229
7301
  let width = 0, boxWidth = 0;
7230
- const data = this.__, { strokeAlign, strokeWidth } = data;
7302
+ const data = this.__, { strokeAlign, strokeWidth } = data, box = this.__box;
7231
7303
  if ((data.stroke || data.hitStroke === 'all') && strokeWidth && strokeAlign !== 'inside') {
7232
7304
  boxWidth = width = strokeAlign === 'center' ? strokeWidth / 2 : strokeWidth;
7233
7305
  if (!data.__boxStroke) {
@@ -7238,6 +7310,10 @@ const UIBounds = {
7238
7310
  }
7239
7311
  if (data.__useArrow)
7240
7312
  width += strokeWidth * 5;
7313
+ if (box) {
7314
+ width = Math.max(box.__layout.strokeSpread = box.__updateStrokeSpread(), width);
7315
+ boxWidth = box.__layout.strokeBoxSpread;
7316
+ }
7241
7317
  this.__layout.strokeBoxSpread = boxWidth;
7242
7318
  return width;
7243
7319
  },
@@ -7256,25 +7332,26 @@ const UIBounds = {
7256
7332
  if (backgroundBlur)
7257
7333
  shapeWidth = Math.max(shapeWidth, backgroundBlur);
7258
7334
  this.__layout.renderShapeSpread = shapeWidth;
7259
- return width + (this.__layout.strokeSpread || 0);
7335
+ width += this.__layout.strokeSpread || 0;
7336
+ return this.__box ? Math.max(this.__box.__updateRenderSpread(), width) : width;
7260
7337
  }
7261
7338
  };
7262
7339
 
7263
7340
  const UIRender = {
7264
7341
  __updateChange() {
7265
- const data = this.__;
7342
+ const data = this.__, w = this.__world;
7266
7343
  if (data.__useEffect) {
7267
7344
  const { shadow, innerShadow, blur, backgroundBlur, filter } = this.__;
7268
7345
  data.__useEffect = !!(shadow || innerShadow || blur || backgroundBlur || filter);
7269
7346
  }
7347
+ const half = data.__hasHalf;
7348
+ w.half !== half && (w.half = half);
7270
7349
  data.__checkSingle();
7271
7350
  const complex = data.__isFills || data.__isStrokes || data.cornerRadius || data.__useEffect;
7272
- if (complex) {
7351
+ if (complex)
7273
7352
  data.__complex = true;
7274
- }
7275
- else {
7353
+ else
7276
7354
  data.__complex && (data.__complex = false);
7277
- }
7278
7355
  },
7279
7356
  __drawFast(canvas, options) {
7280
7357
  drawFast(this, canvas, options);
@@ -7361,10 +7438,11 @@ function drawFast(ui, canvas, options) {
7361
7438
 
7362
7439
  const RectRender = {
7363
7440
  __drawFast(canvas, options) {
7364
- let { width, height, fill, stroke, __drawAfterFill } = this.__;
7441
+ let { x, y, width, height } = this.__layout.boxBounds;
7442
+ const { fill, stroke, __drawAfterFill } = this.__;
7365
7443
  if (fill) {
7366
7444
  canvas.fillStyle = fill;
7367
- canvas.fillRect(0, 0, width, height);
7445
+ canvas.fillRect(x, y, width, height);
7368
7446
  }
7369
7447
  if (__drawAfterFill)
7370
7448
  this.__drawAfterFill(canvas, options);
@@ -7383,14 +7461,14 @@ const RectRender = {
7383
7461
  if (width < 0 || height < 0) {
7384
7462
  canvas.save();
7385
7463
  this.__clip(canvas, options);
7386
- canvas.strokeRect(half, half, width, height);
7464
+ canvas.strokeRect(x + half, y + half, width, height);
7387
7465
  canvas.restore();
7388
7466
  }
7389
7467
  else
7390
- canvas.strokeRect(half, half, width, height);
7468
+ canvas.strokeRect(x + half, y + half, width, height);
7391
7469
  break;
7392
7470
  case 'outside':
7393
- canvas.strokeRect(-half, -half, width + __strokeWidth, height + __strokeWidth);
7471
+ canvas.strokeRect(x - half, y - half, width + __strokeWidth, height + __strokeWidth);
7394
7472
  break;
7395
7473
  }
7396
7474
  }
@@ -7546,6 +7624,12 @@ __decorate([
7546
7624
  __decorate([
7547
7625
  surfaceType(false)
7548
7626
  ], UI.prototype, "locked", void 0);
7627
+ __decorate([
7628
+ surfaceType(false)
7629
+ ], UI.prototype, "dim", void 0);
7630
+ __decorate([
7631
+ surfaceType(false)
7632
+ ], UI.prototype, "dimskip", void 0);
7549
7633
  __decorate([
7550
7634
  sortType(0)
7551
7635
  ], UI.prototype, "zIndex", void 0);
@@ -7807,7 +7891,7 @@ let Leafer = Leafer_1 = class Leafer extends Group {
7807
7891
  start: true,
7808
7892
  hittable: true,
7809
7893
  smooth: true,
7810
- lazySpeard: 100
7894
+ lazySpeard: 100,
7811
7895
  };
7812
7896
  this.leafs = 0;
7813
7897
  this.__eventIds = [];
@@ -8231,13 +8315,13 @@ let Box = class Box extends Group {
8231
8315
  super.__updateRenderBounds();
8232
8316
  copy$2(childrenRenderBounds, renderBounds);
8233
8317
  this.__updateRectRenderBounds();
8234
- isOverflow = !includes$1(renderBounds, childrenRenderBounds);
8318
+ isOverflow = !includes$1(renderBounds, childrenRenderBounds) || undefined;
8235
8319
  if (isOverflow && this.__.overflow !== 'hide')
8236
8320
  add(renderBounds, childrenRenderBounds);
8237
8321
  }
8238
8322
  else
8239
8323
  this.__updateRectRenderBounds();
8240
- !this.isOverflow !== !isOverflow && (this.isOverflow = isOverflow);
8324
+ this.isOverflow !== isOverflow && (this.isOverflow = isOverflow);
8241
8325
  }
8242
8326
  __updateRectRenderBounds() { }
8243
8327
  __updateRectChange() { }
@@ -8645,33 +8729,13 @@ Canvas = __decorate([
8645
8729
  registerUI()
8646
8730
  ], Canvas);
8647
8731
 
8648
- const { copyAndSpread, includes, isSame: isSame$1, spread, setList } = BoundsHelper;
8732
+ const { copyAndSpread, includes, spread, setList } = BoundsHelper;
8649
8733
  let Text = class Text extends UI {
8650
8734
  get __tag() { return 'Text'; }
8651
- get textDrawData() {
8652
- this.__layout.update();
8653
- return this.__.__textDrawData;
8654
- }
8735
+ get textDrawData() { this.updateLayout(); return this.__.__textDrawData; }
8655
8736
  constructor(data) {
8656
8737
  super(data);
8657
8738
  }
8658
- __drawHitPath(canvas) {
8659
- const { __lineHeight, fontSize, __baseLine, __textDrawData: data } = this.__;
8660
- canvas.beginPath();
8661
- if (this.__.__letterSpacing < 0) {
8662
- this.__drawPathByData(canvas);
8663
- }
8664
- else {
8665
- data.rows.forEach(row => canvas.rect(row.x, row.y - __baseLine, row.width, __lineHeight < fontSize ? fontSize : __lineHeight));
8666
- }
8667
- }
8668
- __drawPathByData(drawer, _data) {
8669
- const { x, y, width, height } = this.__layout.boxBounds;
8670
- drawer.rect(x, y, width, height);
8671
- }
8672
- __drawRenderPath(canvas) {
8673
- canvas.font = this.__.__font;
8674
- }
8675
8739
  __updateTextDrawData() {
8676
8740
  const data = this.__;
8677
8741
  const { lineHeight, letterSpacing, fontFamily, fontSize, fontWeight, italic, textCase, textOverflow, padding } = data;
@@ -8688,15 +8752,16 @@ let Text = class Text extends UI {
8688
8752
  const layout = this.__layout;
8689
8753
  const { fontSize, italic, padding, __autoWidth: autoWidth, __autoHeight: autoHeight } = data;
8690
8754
  this.__updateTextDrawData();
8691
- const { bounds } = data.__textDrawData;
8755
+ const { bounds: contentBounds } = data.__textDrawData;
8692
8756
  const b = layout.boxBounds;
8757
+ layout.contentBounds = contentBounds;
8693
8758
  if (data.__lineHeight < fontSize)
8694
- spread(bounds, fontSize / 2);
8759
+ spread(contentBounds, fontSize / 2);
8695
8760
  if (autoWidth || autoHeight) {
8696
- b.x = autoWidth ? bounds.x : 0;
8697
- b.y = autoHeight ? bounds.y : 0;
8698
- b.width = autoWidth ? bounds.width : data.width;
8699
- b.height = autoHeight ? bounds.height : data.height;
8761
+ b.x = autoWidth ? contentBounds.x : 0;
8762
+ b.y = autoHeight ? contentBounds.y : 0;
8763
+ b.width = autoWidth ? contentBounds.width : data.width;
8764
+ b.height = autoHeight ? contentBounds.height : data.height;
8700
8765
  if (padding) {
8701
8766
  const [top, right, bottom, left] = data.__padding;
8702
8767
  if (autoWidth)
@@ -8710,23 +8775,45 @@ let Text = class Text extends UI {
8710
8775
  super.__updateBoxBounds();
8711
8776
  if (italic)
8712
8777
  b.width += fontSize * 0.16;
8713
- const contentBounds = includes(b, bounds) ? b : bounds;
8714
- if (!isSame$1(contentBounds, layout.contentBounds)) {
8715
- layout.contentBounds = contentBounds;
8716
- layout.renderChanged = true;
8717
- setList(data.__textBoxBounds = {}, [b, bounds]);
8718
- }
8778
+ const isOverflow = !includes(b, contentBounds) || undefined;
8779
+ if (isOverflow)
8780
+ setList(data.__textBoxBounds = {}, [b, contentBounds]), layout.renderChanged = true;
8719
8781
  else
8720
- data.__textBoxBounds = contentBounds;
8782
+ data.__textBoxBounds = b;
8783
+ this.isOverflow !== isOverflow && (this.isOverflow = isOverflow);
8784
+ }
8785
+ __onUpdateSize() {
8786
+ if (this.__box)
8787
+ this.__box.__onUpdateSize();
8788
+ super.__onUpdateSize();
8721
8789
  }
8722
8790
  __updateRenderSpread() {
8723
8791
  let width = super.__updateRenderSpread();
8724
8792
  if (!width)
8725
- width = this.__layout.boxBounds === this.__layout.contentBounds ? 0 : 1;
8793
+ width = this.isOverflow ? 1 : 0;
8726
8794
  return width;
8727
8795
  }
8728
8796
  __updateRenderBounds() {
8729
- copyAndSpread(this.__layout.renderBounds, this.__.__textBoxBounds, this.__layout.renderSpread);
8797
+ const { renderBounds, renderSpread } = this.__layout;
8798
+ copyAndSpread(renderBounds, this.__.__textBoxBounds, renderSpread);
8799
+ if (this.__box)
8800
+ this.__box.__layout.renderBounds = renderBounds;
8801
+ }
8802
+ __drawRenderPath(canvas) {
8803
+ canvas.font = this.__.__font;
8804
+ }
8805
+ __draw(canvas, options, originCanvas) {
8806
+ const box = this.__box;
8807
+ if (box)
8808
+ box.__nowWorld = this.__nowWorld, box.__draw(canvas, options, originCanvas);
8809
+ if (this.textEditing && !Export.running)
8810
+ return;
8811
+ super.__draw(canvas, options, originCanvas);
8812
+ }
8813
+ destroy() {
8814
+ if (this.boxStyle)
8815
+ this.boxStyle = null;
8816
+ super.destroy();
8730
8817
  }
8731
8818
  };
8732
8819
  __decorate([
@@ -8738,6 +8825,9 @@ __decorate([
8738
8825
  __decorate([
8739
8826
  boundsType(0)
8740
8827
  ], Text.prototype, "height", void 0);
8828
+ __decorate([
8829
+ surfaceType()
8830
+ ], Text.prototype, "boxStyle", void 0);
8741
8831
  __decorate([
8742
8832
  dataType(false)
8743
8833
  ], Text.prototype, "resizeFontSize", void 0);
@@ -9223,9 +9313,11 @@ const tempBox = new Bounds();
9223
9313
  const tempPoint = {};
9224
9314
  const tempScaleData = {};
9225
9315
  function createData(leafPaint, image, paint, box) {
9226
- const { blendMode, sync } = paint;
9316
+ const { blendMode, changeful, sync } = paint;
9227
9317
  if (blendMode)
9228
9318
  leafPaint.blendMode = blendMode;
9319
+ if (changeful)
9320
+ leafPaint.changeful = changeful;
9229
9321
  if (sync)
9230
9322
  leafPaint.sync = sync;
9231
9323
  leafPaint.data = getPatternData(paint, box, image);
@@ -9458,40 +9550,32 @@ function createPattern(ui, paint, pixelRatio) {
9458
9550
  }
9459
9551
 
9460
9552
  const { abs } = Math;
9461
- function checkImage(ui, canvas, paint, allowPaint) {
9553
+ function checkImage(ui, canvas, paint, allowDraw) {
9462
9554
  const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
9463
- const { pixelRatio } = canvas;
9464
- if (!paint.data || (paint.patternId === scaleX + '-' + scaleY + '-' + pixelRatio && !Export.running)) {
9555
+ const { pixelRatio } = canvas, { data } = paint;
9556
+ if (!data || (paint.patternId === scaleX + '-' + scaleY + '-' + pixelRatio && !Export.running)) {
9465
9557
  return false;
9466
9558
  }
9467
9559
  else {
9468
- const { data } = paint;
9469
- if (allowPaint) {
9470
- if (!data.repeat) {
9471
- let { width, height } = data;
9472
- width *= abs(scaleX) * pixelRatio;
9473
- height *= abs(scaleY) * pixelRatio;
9474
- if (data.scaleX) {
9475
- width *= data.scaleX;
9476
- height *= data.scaleY;
9477
- }
9478
- allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
9560
+ if (allowDraw) {
9561
+ if (data.repeat) {
9562
+ allowDraw = false;
9479
9563
  }
9480
9564
  else {
9481
- allowPaint = false;
9565
+ if (!(paint.changeful || ResizeEvent.isResizing(ui) || Export.running)) {
9566
+ let { width, height } = data;
9567
+ width *= abs(scaleX) * pixelRatio;
9568
+ height *= abs(scaleY) * pixelRatio;
9569
+ if (data.scaleX) {
9570
+ width *= data.scaleX;
9571
+ height *= data.scaleY;
9572
+ }
9573
+ allowDraw = (width * height > Platform.image.maxCacheSize);
9574
+ }
9482
9575
  }
9483
9576
  }
9484
- if (allowPaint) {
9485
- canvas.save();
9486
- ui.windingRule ? canvas.clip(ui.windingRule) : canvas.clip();
9487
- if (paint.blendMode)
9488
- canvas.blendMode = paint.blendMode;
9489
- if (data.opacity)
9490
- canvas.opacity *= data.opacity;
9491
- if (data.transform)
9492
- canvas.transform(data.transform);
9493
- canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
9494
- canvas.restore();
9577
+ if (allowDraw) {
9578
+ drawImage(ui, canvas, paint, data);
9495
9579
  return true;
9496
9580
  }
9497
9581
  else {
@@ -9512,13 +9596,26 @@ function checkImage(ui, canvas, paint, allowPaint) {
9512
9596
  }
9513
9597
  }
9514
9598
  }
9599
+ function drawImage(ui, canvas, paint, data) {
9600
+ canvas.save();
9601
+ ui.windingRule ? canvas.clip(ui.windingRule) : canvas.clip();
9602
+ if (paint.blendMode)
9603
+ canvas.blendMode = paint.blendMode;
9604
+ if (data.opacity)
9605
+ canvas.opacity *= data.opacity;
9606
+ if (data.transform)
9607
+ canvas.transform(data.transform);
9608
+ canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
9609
+ canvas.restore();
9610
+ }
9515
9611
 
9516
9612
  function recycleImage(attrName, data) {
9517
9613
  const paints = data['_' + attrName];
9518
9614
  if (paints instanceof Array) {
9519
- let image, recycleMap, input, url;
9615
+ let paint, image, recycleMap, input, url;
9520
9616
  for (let i = 0, len = paints.length; i < len; i++) {
9521
- image = paints[i].image;
9617
+ paint = paints[i];
9618
+ image = paint.image;
9522
9619
  url = image && image.url;
9523
9620
  if (url) {
9524
9621
  if (!recycleMap)
@@ -9533,8 +9630,6 @@ function recycleImage(attrName, data) {
9533
9630
  }
9534
9631
  image.unload(paints[i].loadId, !input.some((item) => item.url === url));
9535
9632
  }
9536
- else
9537
- paints[i].style = null;
9538
9633
  }
9539
9634
  }
9540
9635
  return recycleMap;
@@ -9713,7 +9808,7 @@ const { toOffsetOutBounds } = BoundsHelper;
9713
9808
  const offsetOutBounds = {};
9714
9809
  function innerShadow(ui, current, shape) {
9715
9810
  let copyBounds, spreadScale;
9716
- const { __nowWorld: nowWorld, __layout: __layout } = ui;
9811
+ const { __nowWorld: nowWorld, __layout } = ui;
9717
9812
  const { innerShadow } = ui.__;
9718
9813
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
9719
9814
  const other = current.getSameCanvas();