@leafer-ui/draw 1.6.1 → 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
 
@@ -286,13 +322,11 @@ class TextData extends UIData {
286
322
  setFontWeight(value) {
287
323
  if (typeof value === 'string') {
288
324
  this.__setInput('fontWeight', value);
289
- this._fontWeight = fontWeightMap[value] || 400;
290
- }
291
- else {
292
- if (this.__input)
293
- this.__removeInput('fontWeight');
294
- this._fontWeight = value;
325
+ value = fontWeightMap[value] || 400;
295
326
  }
327
+ else if (this.__input)
328
+ this.__removeInput('fontWeight');
329
+ this._fontWeight = value;
296
330
  }
297
331
  setBoxStyle(value) {
298
332
  let t = this.__leaf, box = t.__box;
@@ -327,8 +361,6 @@ class ImageData extends RectData {
327
361
  this._url = value;
328
362
  }
329
363
  __setImageFill(value) {
330
- if (this.__leaf.image)
331
- this.__leaf.image = null;
332
364
  this.fill = value ? { type: 'image', mode: 'stretch', url: value } : undefined;
333
365
  }
334
366
  __getData() {
@@ -394,21 +426,19 @@ const UIBounds = {
394
426
  }
395
427
  };
396
428
 
429
+ const { stintSet } = core.DataHelper;
397
430
  const UIRender = {
398
431
  __updateChange() {
399
- const data = this.__, w = this.__world;
432
+ const data = this.__;
400
433
  if (data.__useEffect) {
401
- const { shadow, innerShadow, blur, backgroundBlur, filter } = this.__;
402
- 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);
403
437
  }
404
- const half = data.__hasHalf;
405
- 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);
406
440
  data.__checkSingle();
407
- const complex = data.__isFills || data.__isStrokes || data.cornerRadius || data.__useEffect;
408
- if (complex)
409
- data.__complex = true;
410
- else
411
- data.__complex && (data.__complex = false);
441
+ stintSet(data, '__complex', data.__isFills || data.__isStrokes || data.cornerRadius || data.__useEffect);
412
442
  },
413
443
  __drawFast(canvas, options) {
414
444
  drawFast(this, canvas, options);
@@ -418,21 +448,23 @@ const UIRender = {
418
448
  if (data.__complex) {
419
449
  if (data.__needComputePaint)
420
450
  data.__computePaint();
421
- const { fill, stroke, __drawAfterFill } = data;
451
+ const { fill, stroke, __drawAfterFill, __fillAfterStroke, __isFastShadow } = data;
422
452
  this.__drawRenderPath(canvas);
423
- if (data.__useEffect) {
453
+ if (data.__useEffect && !__isFastShadow) {
424
454
  const shape = Paint.shape(this, canvas, options);
425
455
  this.__nowWorld = this.__getNowWorld(options);
426
456
  const { shadow, innerShadow, filter } = data;
427
457
  if (shadow)
428
458
  Effect.shadow(this, canvas, shape);
459
+ if (__fillAfterStroke)
460
+ data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
429
461
  if (fill)
430
462
  data.__isFills ? Paint.fills(fill, this, canvas) : Paint.fill(fill, this, canvas);
431
463
  if (__drawAfterFill)
432
464
  this.__drawAfterFill(canvas, options);
433
465
  if (innerShadow)
434
466
  Effect.innerShadow(this, canvas, shape);
435
- if (stroke)
467
+ if (stroke && !__fillAfterStroke)
436
468
  data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
437
469
  if (filter)
438
470
  Filter.apply(filter, this, this.__nowWorld, canvas, originCanvas, shape);
@@ -441,21 +473,27 @@ const UIRender = {
441
473
  shape.canvas.recycle();
442
474
  }
443
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
+ }
444
482
  if (fill)
445
483
  data.__isFills ? Paint.fills(fill, this, canvas) : Paint.fill(fill, this, canvas);
484
+ if (__isFastShadow)
485
+ canvas.restore();
446
486
  if (__drawAfterFill)
447
487
  this.__drawAfterFill(canvas, options);
448
- if (stroke)
488
+ if (stroke && !__fillAfterStroke)
449
489
  data.__isStrokes ? Paint.strokes(stroke, this, canvas) : Paint.stroke(stroke, this, canvas);
450
490
  }
451
491
  }
452
492
  else {
453
- if (data.__pathInputed) {
493
+ if (data.__pathInputed)
454
494
  drawFast(this, canvas, options);
455
- }
456
- else {
495
+ else
457
496
  this.__drawFast(canvas, options);
458
- }
459
497
  }
460
498
  },
461
499
  __renderShape(canvas, options, ignoreFill, ignoreStroke) {
@@ -464,11 +502,11 @@ const UIRender = {
464
502
  const { fill, stroke } = this.__;
465
503
  this.__drawRenderPath(canvas);
466
504
  if (fill && !ignoreFill)
467
- 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);
468
506
  if (this.__.__isCanvas)
469
507
  this.__drawAfterFill(canvas, options);
470
508
  if (stroke && !ignoreStroke)
471
- 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);
472
510
  }
473
511
  },
474
512
  __drawAfterFill(canvas, options) {
@@ -483,13 +521,15 @@ const UIRender = {
483
521
  }
484
522
  };
485
523
  function drawFast(ui, canvas, options) {
486
- const { fill, stroke, __drawAfterFill } = ui.__;
524
+ const { fill, stroke, __drawAfterFill, __fillAfterStroke } = ui.__;
487
525
  ui.__drawRenderPath(canvas);
526
+ if (__fillAfterStroke)
527
+ Paint.stroke(stroke, ui, canvas);
488
528
  if (fill)
489
529
  Paint.fill(fill, ui, canvas);
490
530
  if (__drawAfterFill)
491
531
  ui.__drawAfterFill(canvas, options);
492
- if (stroke)
532
+ if (stroke && !__fillAfterStroke)
493
533
  Paint.stroke(stroke, ui, canvas);
494
534
  }
495
535
 
@@ -619,6 +659,9 @@ exports.UI = UI_1 = class UI extends core.Leaf {
619
659
  else
620
660
  drawer.rect(x, y, width, height);
621
661
  }
662
+ drawImagePlaceholder(canvas, _image) {
663
+ Paint.fill(this.__.placeholderColor, this, canvas);
664
+ }
622
665
  animate(_keyframe, _options, _type, _isTemp) {
623
666
  return core.Plugin.need('animate');
624
667
  }
@@ -855,6 +898,12 @@ __decorate([
855
898
  __decorate([
856
899
  effectType()
857
900
  ], exports.UI.prototype, "filter", void 0);
901
+ __decorate([
902
+ core.surfaceType()
903
+ ], exports.UI.prototype, "placeholderColor", void 0);
904
+ __decorate([
905
+ core.dataType(100)
906
+ ], exports.UI.prototype, "placeholderDelay", void 0);
858
907
  __decorate([
859
908
  core.dataType({})
860
909
  ], exports.UI.prototype, "data", void 0);
@@ -1256,15 +1305,20 @@ exports.Leafer = Leafer_1 = class Leafer extends exports.Group {
1256
1305
  }
1257
1306
  __listenEvents() {
1258
1307
  const runId = core.Run.start('FirstCreate ' + this.innerName);
1259
- this.once(core.LeaferEvent.START, () => core.Run.end(runId));
1260
- this.once(core.LayoutEvent.START, () => this.updateLazyBounds());
1261
- this.once(core.RenderEvent.START, () => this.__onCreated());
1262
- this.once(core.RenderEvent.END, () => this.__onViewReady());
1263
- 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
+ ]));
1264
1319
  }
1265
1320
  __removeListenEvents() {
1266
1321
  this.off_(this.__eventIds);
1267
- this.__eventIds.length = 0;
1268
1322
  }
1269
1323
  destroy(sync) {
1270
1324
  const doDestory = () => {
@@ -1372,13 +1426,13 @@ exports.Box = class Box extends exports.Group {
1372
1426
  super.__updateRenderBounds();
1373
1427
  copy(childrenRenderBounds, renderBounds);
1374
1428
  this.__updateRectRenderBounds();
1375
- isOverflow = !includes$1(renderBounds, childrenRenderBounds) || undefined;
1429
+ isOverflow = !includes$1(renderBounds, childrenRenderBounds);
1376
1430
  if (isOverflow && this.__.overflow !== 'hide')
1377
1431
  add(renderBounds, childrenRenderBounds);
1378
1432
  }
1379
1433
  else
1380
1434
  this.__updateRectRenderBounds();
1381
- this.isOverflow !== isOverflow && (this.isOverflow = isOverflow);
1435
+ core.DataHelper.stintSet(this, 'isOverflow', isOverflow);
1382
1436
  }
1383
1437
  __updateRectRenderBounds() { }
1384
1438
  __updateRectChange() { }
@@ -1682,17 +1736,10 @@ exports.Star = __decorate([
1682
1736
 
1683
1737
  exports.Image = class Image extends exports.Rect {
1684
1738
  get __tag() { return 'Image'; }
1685
- 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; }
1686
1741
  constructor(data) {
1687
1742
  super(data);
1688
- this.on(core.ImageEvent.LOADED, (e) => {
1689
- if (e.attrName === 'fill' && e.attrValue.url === this.url)
1690
- this.image = e.image;
1691
- });
1692
- }
1693
- destroy() {
1694
- this.image = null;
1695
- super.destroy();
1696
1743
  }
1697
1744
  };
1698
1745
  __decorate([
@@ -1708,11 +1755,11 @@ const MyImage = exports.Image;
1708
1755
 
1709
1756
  exports.Canvas = class Canvas extends exports.Rect {
1710
1757
  get __tag() { return 'Canvas'; }
1758
+ get context() { return this.canvas.context; }
1711
1759
  get ready() { return !this.url; }
1712
1760
  constructor(data) {
1713
1761
  super(data);
1714
1762
  this.canvas = core.Creator.canvas(this.__);
1715
- this.context = this.canvas.context;
1716
1763
  if (data && data.url)
1717
1764
  this.drawImage(data.url);
1718
1765
  }
@@ -1756,7 +1803,7 @@ exports.Canvas = class Canvas extends exports.Rect {
1756
1803
  destroy() {
1757
1804
  if (this.canvas) {
1758
1805
  this.canvas.destroy();
1759
- this.canvas = this.context = null;
1806
+ this.canvas = null;
1760
1807
  }
1761
1808
  super.destroy();
1762
1809
  }
@@ -1802,7 +1849,7 @@ exports.Text = class Text extends exports.UI {
1802
1849
  data.__baseLine = data.__lineHeight - (data.__lineHeight - fontSize * 0.7) / 2;
1803
1850
  data.__font = `${italic ? 'italic ' : ''}${textCase === 'small-caps' ? 'small-caps ' : ''}${fontWeight !== 'normal' ? fontWeight + ' ' : ''}${fontSize}px ${fontFamily}`;
1804
1851
  data.__clipText = textOverflow !== 'show' && !data.__autoSize;
1805
- data.__textDrawData = TextConvert.getDrawData(data.text, this.__);
1852
+ data.__textDrawData = TextConvert.getDrawData((data.__isPlacehold = data.placeholder && data.text === '') ? data.placeholder : data.text, this.__);
1806
1853
  }
1807
1854
  __updateBoxBounds() {
1808
1855
  const data = this.__;
@@ -1832,12 +1879,11 @@ exports.Text = class Text extends exports.UI {
1832
1879
  super.__updateBoxBounds();
1833
1880
  if (italic)
1834
1881
  b.width += fontSize * 0.16;
1835
- const isOverflow = !includes(b, contentBounds) || undefined;
1836
- if (isOverflow)
1882
+ core.DataHelper.stintSet(this, 'isOverflow', !includes(b, contentBounds));
1883
+ if (this.isOverflow)
1837
1884
  setList(data.__textBoxBounds = {}, [b, contentBounds]), layout.renderChanged = true;
1838
1885
  else
1839
1886
  data.__textBoxBounds = b;
1840
- this.isOverflow !== isOverflow && (this.isOverflow = isOverflow);
1841
1887
  }
1842
1888
  __onUpdateSize() {
1843
1889
  if (this.__box)
@@ -1900,6 +1946,9 @@ __decorate([
1900
1946
  __decorate([
1901
1947
  core.boundsType('')
1902
1948
  ], exports.Text.prototype, "text", void 0);
1949
+ __decorate([
1950
+ core.boundsType('')
1951
+ ], exports.Text.prototype, "placeholder", void 0);
1903
1952
  __decorate([
1904
1953
  core.boundsType('caption')
1905
1954
  ], exports.Text.prototype, "fontFamily", void 0);
@@ -2058,4 +2107,3 @@ Object.keys(core).forEach(function (k) {
2058
2107
  get: function () { return core[k]; }
2059
2108
  });
2060
2109
  });
2061
- //# sourceMappingURL=draw.cjs.map