@leafer-ui/draw 1.6.2 → 1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/draw.cjs CHANGED
@@ -65,8 +65,32 @@ function zoomLayerType() {
65
65
  };
66
66
  }
67
67
 
68
+ function hasTransparent$1(color) {
69
+ if (!color || color.length === 7 || color.length === 4)
70
+ return false;
71
+ if (color === 'transparent')
72
+ return true;
73
+ const first = color[0];
74
+ if (first === '#') {
75
+ switch (color.length) {
76
+ case 5: return color[4] !== 'f' && color[4] !== 'F';
77
+ case 9: return (color[7] !== 'f' && color[7] !== 'F') || (color[8] !== 'f' && color[8] !== 'F');
78
+ }
79
+ }
80
+ else if (first === 'r' || first === 'h') {
81
+ if (color[3] === 'a') {
82
+ const i = color.lastIndexOf(',');
83
+ if (i > -1)
84
+ return parseFloat(color.slice(i + 1)) < 1;
85
+ }
86
+ }
87
+ return false;
88
+ }
89
+
68
90
  const TextConvert = {};
69
- const ColorConvert = {};
91
+ const ColorConvert = {
92
+ hasTransparent: hasTransparent$1
93
+ };
70
94
  const UnitConvert = {
71
95
  number(value, percentRefer) {
72
96
  return typeof value === 'object' ? (value.type === 'percent' ? value.value * percentRefer : value.value) : value;
@@ -92,6 +116,7 @@ const Transition = {
92
116
  };
93
117
 
94
118
  const { parse, objectToCanvasData } = core.PathConvert;
119
+ const { stintSet: stintSet$1 } = core.DataHelper, { hasTransparent } = ColorConvert;
95
120
  const emptyPaint = {};
96
121
  const debug$1 = core.Debug.get('UIData');
97
122
  class UIData extends core.LeafData {
@@ -150,38 +175,22 @@ class UIData extends core.LeafData {
150
175
  if (this.__naturalWidth)
151
176
  this.__removeNaturalSize();
152
177
  if (typeof value === 'string' || !value) {
153
- if (this.__isFills) {
154
- this.__removeInput('fill');
155
- PaintImage.recycleImage('fill', this);
156
- this.__isFills = false;
157
- this.__pixelFill && (this.__pixelFill = false);
158
- }
178
+ stintSet$1(this, '__isTransparentFill', hasTransparent(value));
179
+ this.__isFills && this.__removePaint('fill', true);
159
180
  this._fill = value;
160
181
  }
161
182
  else if (typeof value === 'object') {
162
- this.__setInput('fill', value);
163
- const layout = this.__leaf.__layout;
164
- layout.boxChanged || layout.boxChange();
165
- this.__isFills = true;
166
- this._fill || (this._fill = emptyPaint);
183
+ this.__setPaint('fill', value);
167
184
  }
168
185
  }
169
186
  setStroke(value) {
170
187
  if (typeof value === 'string' || !value) {
171
- if (this.__isStrokes) {
172
- this.__removeInput('stroke');
173
- PaintImage.recycleImage('stroke', this);
174
- this.__isStrokes = false;
175
- this.__pixelStroke && (this.__pixelStroke = false);
176
- }
188
+ stintSet$1(this, '__isTransparentStroke', hasTransparent(value));
189
+ this.__isStrokes && this.__removePaint('stroke', true);
177
190
  this._stroke = value;
178
191
  }
179
192
  else if (typeof value === 'object') {
180
- this.__setInput('stroke', value);
181
- const layout = this.__leaf.__layout;
182
- layout.boxChanged || layout.boxChange();
183
- this.__isStrokes = true;
184
- this._stroke || (this._stroke = emptyPaint);
193
+ this.__setPaint('stroke', value);
185
194
  }
186
195
  }
187
196
  setPath(value) {
@@ -211,7 +220,34 @@ class UIData extends core.LeafData {
211
220
  Paint.compute('fill', this.__leaf);
212
221
  if (stroke)
213
222
  Paint.compute('stroke', this.__leaf);
214
- this.__needComputePaint = false;
223
+ this.__needComputePaint = undefined;
224
+ }
225
+ __setPaint(attrName, value) {
226
+ this.__setInput(attrName, value);
227
+ const layout = this.__leaf.__layout;
228
+ layout.boxChanged || layout.boxChange();
229
+ if (value instanceof Array && !value.length) {
230
+ this.__removePaint(attrName);
231
+ }
232
+ else {
233
+ if (attrName === 'fill')
234
+ this.__isFills = true, this._fill || (this._fill = emptyPaint);
235
+ else
236
+ this.__isStrokes = true, this._stroke || (this._stroke = emptyPaint);
237
+ }
238
+ }
239
+ __removePaint(attrName, removeInput) {
240
+ if (removeInput)
241
+ this.__removeInput(attrName);
242
+ PaintImage.recycleImage(attrName, this);
243
+ if (attrName === 'fill') {
244
+ stintSet$1(this, '__isAlphaPixelFill', undefined);
245
+ this._fill = this.__isFills = undefined;
246
+ }
247
+ else {
248
+ stintSet$1(this, '__isAlphaPixelStroke', undefined);
249
+ this._stroke = this.__isStrokes = undefined;
250
+ }
215
251
  }
216
252
  }
217
253
  function setArray(data, key, value) {
@@ -219,10 +255,10 @@ function setArray(data, key, value) {
219
255
  if (value instanceof Array) {
220
256
  if (value.some((item) => item.visible === false))
221
257
  value = value.filter((item) => item.visible !== false);
222
- value.length || (value = null);
258
+ value.length || (value = undefined);
223
259
  }
224
260
  else
225
- value = value && value.visible !== false ? [value] : null;
261
+ value = value && value.visible !== false ? [value] : undefined;
226
262
  data['_' + key] = value;
227
263
  }
228
264
 
@@ -325,8 +361,6 @@ class ImageData extends RectData {
325
361
  this._url = value;
326
362
  }
327
363
  __setImageFill(value) {
328
- if (this.__leaf.image)
329
- this.__leaf.image = null;
330
364
  this.fill = value ? { type: 'image', mode: 'stretch', url: value } : undefined;
331
365
  }
332
366
  __getData() {
@@ -392,21 +426,19 @@ const UIBounds = {
392
426
  }
393
427
  };
394
428
 
429
+ const { stintSet } = core.DataHelper;
395
430
  const UIRender = {
396
431
  __updateChange() {
397
- const data = this.__, w = this.__world;
432
+ const data = this.__;
398
433
  if (data.__useEffect) {
399
- const { shadow, innerShadow, blur, backgroundBlur, filter } = this.__;
400
- data.__useEffect = !!(shadow || innerShadow || blur || backgroundBlur || filter);
434
+ const { shadow, fill, stroke } = data, otherEffect = data.innerShadow || data.blur || data.backgroundBlur || data.filter;
435
+ stintSet(data, '__isFastShadow', shadow && !otherEffect && shadow.length < 2 && !shadow[0].spread && !(shadow[0].box && data.__isTransparentFill) && fill && !(fill instanceof Array && fill.length > 1) && (this.useFastShadow || !stroke || (stroke && data.strokeAlign === 'inside')));
436
+ data.__useEffect = !!(shadow || otherEffect);
401
437
  }
402
- const half = data.__hasHalf;
403
- w.half !== half && (w.half = half);
438
+ stintSet(this.__world, 'half', data.__hasHalf);
439
+ stintSet(data, '__fillAfterStroke', data.stroke && data.strokeAlign === 'outside' && data.fill && !data.__isTransparentFill);
404
440
  data.__checkSingle();
405
- const complex = data.__isFills || data.__isStrokes || data.cornerRadius || data.__useEffect;
406
- if (complex)
407
- data.__complex = true;
408
- else
409
- data.__complex && (data.__complex = false);
441
+ stintSet(data, '__complex', data.__isFills || data.__isStrokes || data.cornerRadius || data.__useEffect);
410
442
  },
411
443
  __drawFast(canvas, options) {
412
444
  drawFast(this, canvas, options);
@@ -416,21 +448,23 @@ const UIRender = {
416
448
  if (data.__complex) {
417
449
  if (data.__needComputePaint)
418
450
  data.__computePaint();
419
- const { fill, stroke, __drawAfterFill } = data;
451
+ const { fill, stroke, __drawAfterFill, __fillAfterStroke, __isFastShadow } = data;
420
452
  this.__drawRenderPath(canvas);
421
- if (data.__useEffect) {
453
+ if (data.__useEffect && !__isFastShadow) {
422
454
  const shape = Paint.shape(this, canvas, options);
423
455
  this.__nowWorld = this.__getNowWorld(options);
424
456
  const { shadow, innerShadow, filter } = data;
425
457
  if (shadow)
426
458
  Effect.shadow(this, canvas, shape);
459
+ if (__fillAfterStroke)
460
+ data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
427
461
  if (fill)
428
462
  data.__isFills ? Paint.fills(fill, this, canvas) : Paint.fill(fill, this, canvas);
429
463
  if (__drawAfterFill)
430
464
  this.__drawAfterFill(canvas, options);
431
465
  if (innerShadow)
432
466
  Effect.innerShadow(this, canvas, shape);
433
- if (stroke)
467
+ if (stroke && !__fillAfterStroke)
434
468
  data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
435
469
  if (filter)
436
470
  Filter.apply(filter, this, this.__nowWorld, canvas, originCanvas, shape);
@@ -439,21 +473,27 @@ const UIRender = {
439
473
  shape.canvas.recycle();
440
474
  }
441
475
  else {
476
+ if (__fillAfterStroke)
477
+ data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
478
+ if (__isFastShadow) {
479
+ const shadow = data.shadow[0], { scaleX, scaleY } = this.__nowWorld;
480
+ canvas.save(), canvas.setWorldShadow(shadow.x * scaleX, shadow.y * scaleY, shadow.blur * scaleX, ColorConvert.string(shadow.color));
481
+ }
442
482
  if (fill)
443
483
  data.__isFills ? Paint.fills(fill, this, canvas) : Paint.fill(fill, this, canvas);
484
+ if (__isFastShadow)
485
+ canvas.restore();
444
486
  if (__drawAfterFill)
445
487
  this.__drawAfterFill(canvas, options);
446
- if (stroke)
488
+ if (stroke && !__fillAfterStroke)
447
489
  data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
448
490
  }
449
491
  }
450
492
  else {
451
- if (data.__pathInputed) {
493
+ if (data.__pathInputed)
452
494
  drawFast(this, canvas, options);
453
- }
454
- else {
495
+ else
455
496
  this.__drawFast(canvas, options);
456
- }
457
497
  }
458
498
  },
459
499
  __renderShape(canvas, options, ignoreFill, ignoreStroke) {
@@ -462,11 +502,11 @@ const UIRender = {
462
502
  const { fill, stroke } = this.__;
463
503
  this.__drawRenderPath(canvas);
464
504
  if (fill && !ignoreFill)
465
- this.__.__pixelFill ? Paint.fills(fill, this, canvas) : Paint.fill('#000000', this, canvas);
505
+ this.__.__isAlphaPixelFill ? Paint.fills(fill, this, canvas) : Paint.fill('#000000', this, canvas);
466
506
  if (this.__.__isCanvas)
467
507
  this.__drawAfterFill(canvas, options);
468
508
  if (stroke && !ignoreStroke)
469
- this.__.__pixelStroke ? Paint.strokes(stroke, this, canvas) : Paint.stroke('#000000', this, canvas);
509
+ this.__.__isAlphaPixelStroke ? Paint.strokes(stroke, this, canvas) : Paint.stroke('#000000', this, canvas);
470
510
  }
471
511
  },
472
512
  __drawAfterFill(canvas, options) {
@@ -481,13 +521,15 @@ const UIRender = {
481
521
  }
482
522
  };
483
523
  function drawFast(ui, canvas, options) {
484
- const { fill, stroke, __drawAfterFill } = ui.__;
524
+ const { fill, stroke, __drawAfterFill, __fillAfterStroke } = ui.__;
485
525
  ui.__drawRenderPath(canvas);
526
+ if (__fillAfterStroke)
527
+ Paint.stroke(stroke, ui, canvas);
486
528
  if (fill)
487
529
  Paint.fill(fill, ui, canvas);
488
530
  if (__drawAfterFill)
489
531
  ui.__drawAfterFill(canvas, options);
490
- if (stroke)
532
+ if (stroke && !__fillAfterStroke)
491
533
  Paint.stroke(stroke, ui, canvas);
492
534
  }
493
535
 
@@ -859,6 +901,9 @@ __decorate([
859
901
  __decorate([
860
902
  core.surfaceType()
861
903
  ], exports.UI.prototype, "placeholderColor", void 0);
904
+ __decorate([
905
+ core.dataType(100)
906
+ ], exports.UI.prototype, "placeholderDelay", void 0);
862
907
  __decorate([
863
908
  core.dataType({})
864
909
  ], exports.UI.prototype, "data", void 0);
@@ -1260,15 +1305,20 @@ exports.Leafer = Leafer_1 = class Leafer extends exports.Group {
1260
1305
  }
1261
1306
  __listenEvents() {
1262
1307
  const runId = core.Run.start('FirstCreate ' + this.innerName);
1263
- this.once(core.LeaferEvent.START, () => core.Run.end(runId));
1264
- this.once(core.LayoutEvent.START, () => this.updateLazyBounds());
1265
- this.once(core.RenderEvent.START, () => this.__onCreated());
1266
- this.once(core.RenderEvent.END, () => this.__onViewReady());
1267
- this.__eventIds.push(this.on_(core.WatchEvent.DATA, this.__onWatchData, this), this.on_(core.LayoutEvent.END, this.__onLayoutEnd, this), this.on_(core.RenderEvent.NEXT, this.__onNextRender, this));
1308
+ this.once([
1309
+ [core.LeaferEvent.START, () => core.Run.end(runId)],
1310
+ [core.LayoutEvent.START, this.updateLazyBounds, this],
1311
+ [core.RenderEvent.START, this.__onCreated, this],
1312
+ [core.RenderEvent.END, this.__onViewReady, this]
1313
+ ]);
1314
+ this.__eventIds.push(this.on_([
1315
+ [core.WatchEvent.DATA, this.__onWatchData, this],
1316
+ [core.LayoutEvent.END, this.__onLayoutEnd, this],
1317
+ [core.RenderEvent.NEXT, this.__onNextRender, this]
1318
+ ]));
1268
1319
  }
1269
1320
  __removeListenEvents() {
1270
1321
  this.off_(this.__eventIds);
1271
- this.__eventIds.length = 0;
1272
1322
  }
1273
1323
  destroy(sync) {
1274
1324
  const doDestory = () => {
@@ -1376,13 +1426,13 @@ exports.Box = class Box extends exports.Group {
1376
1426
  super.__updateRenderBounds();
1377
1427
  copy(childrenRenderBounds, renderBounds);
1378
1428
  this.__updateRectRenderBounds();
1379
- isOverflow = !includes$1(renderBounds, childrenRenderBounds) || undefined;
1429
+ isOverflow = !includes$1(renderBounds, childrenRenderBounds);
1380
1430
  if (isOverflow && this.__.overflow !== 'hide')
1381
1431
  add(renderBounds, childrenRenderBounds);
1382
1432
  }
1383
1433
  else
1384
1434
  this.__updateRectRenderBounds();
1385
- this.isOverflow !== isOverflow && (this.isOverflow = isOverflow);
1435
+ core.DataHelper.stintSet(this, 'isOverflow', isOverflow);
1386
1436
  }
1387
1437
  __updateRectRenderBounds() { }
1388
1438
  __updateRectChange() { }
@@ -1686,18 +1736,10 @@ exports.Star = __decorate([
1686
1736
 
1687
1737
  exports.Image = class Image extends exports.Rect {
1688
1738
  get __tag() { return 'Image'; }
1689
- get ready() { return this.image ? this.image.ready : false; }
1739
+ get ready() { const { image } = this; return image && image.ready; }
1740
+ get image() { const { fill } = this.__; return fill instanceof Array && fill[0].image; }
1690
1741
  constructor(data) {
1691
1742
  super(data);
1692
- this.on_(core.ImageEvent.LOADED, this.__onLoaded, this);
1693
- }
1694
- __onLoaded(e) {
1695
- if (e.attrName === 'fill' && e.attrValue.url === this.url)
1696
- this.image = e.image;
1697
- }
1698
- destroy() {
1699
- this.image = null;
1700
- super.destroy();
1701
1743
  }
1702
1744
  };
1703
1745
  __decorate([
@@ -1713,11 +1755,11 @@ const MyImage = exports.Image;
1713
1755
 
1714
1756
  exports.Canvas = class Canvas extends exports.Rect {
1715
1757
  get __tag() { return 'Canvas'; }
1758
+ get context() { return this.canvas.context; }
1716
1759
  get ready() { return !this.url; }
1717
1760
  constructor(data) {
1718
1761
  super(data);
1719
1762
  this.canvas = core.Creator.canvas(this.__);
1720
- this.context = this.canvas.context;
1721
1763
  if (data && data.url)
1722
1764
  this.drawImage(data.url);
1723
1765
  }
@@ -1761,7 +1803,7 @@ exports.Canvas = class Canvas extends exports.Rect {
1761
1803
  destroy() {
1762
1804
  if (this.canvas) {
1763
1805
  this.canvas.destroy();
1764
- this.canvas = this.context = null;
1806
+ this.canvas = null;
1765
1807
  }
1766
1808
  super.destroy();
1767
1809
  }
@@ -1837,12 +1879,11 @@ exports.Text = class Text extends exports.UI {
1837
1879
  super.__updateBoxBounds();
1838
1880
  if (italic)
1839
1881
  b.width += fontSize * 0.16;
1840
- const isOverflow = !includes(b, contentBounds) || undefined;
1841
- if (isOverflow)
1882
+ core.DataHelper.stintSet(this, 'isOverflow', !includes(b, contentBounds));
1883
+ if (this.isOverflow)
1842
1884
  setList(data.__textBoxBounds = {}, [b, contentBounds]), layout.renderChanged = true;
1843
1885
  else
1844
1886
  data.__textBoxBounds = b;
1845
- this.isOverflow !== isOverflow && (this.isOverflow = isOverflow);
1846
1887
  }
1847
1888
  __onUpdateSize() {
1848
1889
  if (this.__box)