@leafer-ui/worker 1.9.7 → 1.9.9

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/dist/worker.cjs CHANGED
@@ -429,6 +429,7 @@ class Renderer {
429
429
  usePartRender: true,
430
430
  maxFPS: 120
431
431
  };
432
+ this.frames = [];
432
433
  this.target = target;
433
434
  this.canvas = canvas;
434
435
  if (userConfig) this.config = core.DataHelper.default(userConfig, this.config);
@@ -581,12 +582,15 @@ class Renderer {
581
582
  const target = this.target;
582
583
  if (this.requestTime || !target) return;
583
584
  if (target.parentApp) return target.parentApp.requestRender(false);
584
- const requestTime = this.requestTime = Date.now();
585
+ this.requestTime = this.frameTime || Date.now();
585
586
  const render = () => {
586
- const nowFPS = 1e3 / (Date.now() - requestTime);
587
+ const nowFPS = 1e3 / ((this.frameTime = Date.now()) - this.requestTime);
587
588
  const {maxFPS: maxFPS} = this.config;
588
- if (maxFPS && nowFPS > maxFPS - .5) return core.Platform.requestRender(render);
589
- this.FPS = Math.min(120, Math.ceil(nowFPS));
589
+ if (maxFPS && nowFPS > maxFPS) return core.Platform.requestRender(render);
590
+ const {frames: frames} = this;
591
+ if (frames.length > 30) frames.shift();
592
+ frames.push(nowFPS);
593
+ this.FPS = Math.round(frames.reduce((a, b) => a + b, 0) / frames.length);
590
594
  this.requestTime = 0;
591
595
  this.checkRender();
592
596
  };
@@ -1036,24 +1040,29 @@ function drawOutside(stroke, ui, canvas) {
1036
1040
  }
1037
1041
  }
1038
1042
 
1039
- const {getSpread: getSpread, getOuterOf: getOuterOf, getByMove: getByMove, getIntersectData: getIntersectData} = core.BoundsHelper;
1043
+ const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = core.BoundsHelper;
1044
+
1045
+ const tempBounds$1 = {};
1040
1046
 
1041
1047
  function shape(ui, current, options) {
1042
1048
  const canvas = current.getSameCanvas();
1043
- const nowWorld = ui.__nowWorld, currentBounds = current.bounds;
1044
- let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
1049
+ const currentBounds = current.bounds, nowWorld = ui.__nowWorld, layout = ui.__layout;
1050
+ const nowWorldShapeBounds = ui.__nowWorldShapeBounds || (ui.__nowWorldShapeBounds = {});
1051
+ toOuterOf(layout.strokeSpread ? (copyAndSpread(tempBounds$1, layout.boxBounds, layout.strokeSpread),
1052
+ tempBounds$1) : layout.boxBounds, nowWorld, nowWorldShapeBounds);
1053
+ let bounds, renderBounds, matrix, fitMatrix, shapeBounds, worldCanvas;
1045
1054
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
1046
- if (currentBounds.includes(nowWorld)) {
1055
+ if (currentBounds.includes(nowWorldShapeBounds)) {
1047
1056
  worldCanvas = canvas;
1048
- bounds = shapeBounds = nowWorld;
1057
+ bounds = shapeBounds = nowWorldShapeBounds;
1058
+ renderBounds = nowWorld;
1049
1059
  } else {
1050
- const {renderShapeSpread: spread} = ui.__layout;
1051
1060
  let worldClipBounds;
1052
1061
  if (core.Platform.fullImageShadow) {
1053
- worldClipBounds = nowWorld;
1062
+ worldClipBounds = nowWorldShapeBounds;
1054
1063
  } else {
1055
- const spreadBounds = spread ? getSpread(currentBounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : currentBounds;
1056
- worldClipBounds = getIntersectData(spreadBounds, nowWorld);
1064
+ const spreadBounds = layout.renderShapeSpread ? getSpread(currentBounds, core.FourNumberHelper.swapAndScale(layout.renderShapeSpread, scaleX, scaleY)) : currentBounds;
1065
+ worldClipBounds = getIntersectData(spreadBounds, nowWorldShapeBounds);
1057
1066
  }
1058
1067
  fitMatrix = currentBounds.getFitMatrix(worldClipBounds);
1059
1068
  let {a: fitScaleX, d: fitScaleY} = fitMatrix;
@@ -1063,8 +1072,10 @@ function shape(ui, current, options) {
1063
1072
  scaleX *= fitScaleX;
1064
1073
  scaleY *= fitScaleY;
1065
1074
  }
1066
- shapeBounds = getOuterOf(nowWorld, fitMatrix);
1075
+ shapeBounds = getOuterOf(nowWorldShapeBounds, fitMatrix);
1067
1076
  bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1077
+ renderBounds = getOuterOf(nowWorld, fitMatrix);
1078
+ move$1(renderBounds, -fitMatrix.e, -fitMatrix.f);
1068
1079
  const userMatrix = options.matrix;
1069
1080
  if (userMatrix) {
1070
1081
  matrix = new core.Matrix(fitMatrix);
@@ -1083,6 +1094,7 @@ function shape(ui, current, options) {
1083
1094
  matrix: matrix,
1084
1095
  fitMatrix: fitMatrix,
1085
1096
  bounds: bounds,
1097
+ renderBounds: renderBounds,
1086
1098
  worldCanvas: worldCanvas,
1087
1099
  shapeBounds: shapeBounds,
1088
1100
  scaleX: scaleX,
@@ -1186,7 +1198,7 @@ const PaintModule = {
1186
1198
  shape: shape
1187
1199
  };
1188
1200
 
1189
- let origin = {}, tempMatrix = core.getMatrixData();
1201
+ let origin = {}, tempMatrix$1 = core.getMatrixData();
1190
1202
 
1191
1203
  const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
1192
1204
 
@@ -1201,12 +1213,12 @@ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1201
1213
  data.transform = transform;
1202
1214
  }
1203
1215
 
1204
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
1216
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1205
1217
  const transform = get$3();
1206
1218
  layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1207
- if (clipSize) {
1208
- tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
1209
- multiplyParent(transform, tempMatrix);
1219
+ if (clipScaleX) {
1220
+ tempMatrix$1.a = clipScaleX, tempMatrix$1.d = clipScaleY;
1221
+ multiplyParent(transform, tempMatrix$1);
1210
1222
  }
1211
1223
  data.transform = transform;
1212
1224
  }
@@ -1307,7 +1319,12 @@ function getPatternData(paint, box, image) {
1307
1319
 
1308
1320
  case "normal":
1309
1321
  case "clip":
1310
- if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1322
+ if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1323
+ let clipScaleX, clipScaleY;
1324
+ if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1325
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1326
+ if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : scaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1327
+ }
1311
1328
  break;
1312
1329
 
1313
1330
  case "repeat":
@@ -1465,7 +1482,7 @@ function ignoreRender(ui, value) {
1465
1482
 
1466
1483
  const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1467
1484
 
1468
- const {floor: floor, ceil: ceil, max: max, abs: abs} = Math;
1485
+ const {floor: floor, ceil: ceil, max: max$1, abs: abs} = Math;
1469
1486
 
1470
1487
  function createPattern(ui, paint, pixelRatio) {
1471
1488
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
@@ -1514,8 +1531,8 @@ function createPattern(ui, paint, pixelRatio) {
1514
1531
  if (transform || scaleX !== 1 || scaleY !== 1) {
1515
1532
  const canvasWidth = width + (xGap || 0);
1516
1533
  const canvasHeight = height + (yGap || 0);
1517
- scaleX /= canvasWidth / max(floor(canvasWidth), 1);
1518
- scaleY /= canvasHeight / max(floor(canvasHeight), 1);
1534
+ scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1535
+ scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1519
1536
  if (!imageMatrix) {
1520
1537
  imageMatrix = get$1();
1521
1538
  if (transform) copy$1(imageMatrix, transform);
@@ -1574,17 +1591,15 @@ function checkImage(ui, canvas, paint, allowDraw) {
1574
1591
  if (allowDraw) {
1575
1592
  if (data.repeat) {
1576
1593
  allowDraw = false;
1577
- } else {
1578
- if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1579
- let {width: width, height: height} = data;
1580
- width *= scaleX * pixelRatio;
1581
- height *= scaleY * pixelRatio;
1582
- if (data.scaleX) {
1583
- width *= data.scaleX;
1584
- height *= data.scaleY;
1585
- }
1586
- allowDraw = width * height > core.Platform.image.maxCacheSize;
1594
+ } else if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1595
+ let {width: width, height: height} = data;
1596
+ width *= scaleX * pixelRatio;
1597
+ height *= scaleY * pixelRatio;
1598
+ if (data.scaleX) {
1599
+ width *= data.scaleX;
1600
+ height *= data.scaleY;
1587
1601
  }
1602
+ allowDraw = width * height > core.Platform.image.maxCacheSize;
1588
1603
  }
1589
1604
  }
1590
1605
  if (allowDraw) {
@@ -1764,75 +1779,82 @@ const PaintGradientModule = {
1764
1779
  getTransform: getTransform
1765
1780
  };
1766
1781
 
1767
- const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = core.BoundsHelper;
1782
+ const {copy: copy, move: move, toOffsetOutBounds: toOffsetOutBounds$1} = core.BoundsHelper, {max: max} = Math;
1768
1783
 
1769
- const tempBounds = {};
1784
+ const tempBounds = {}, tempMatrix = new core.Matrix;
1770
1785
 
1771
1786
  const offsetOutBounds$1 = {};
1772
1787
 
1773
1788
  function shadow(ui, current, shape) {
1774
- let copyBounds, spreadScale;
1775
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
1789
+ let copyBounds, transform;
1790
+ const {__nowWorld: nowWorld} = ui;
1776
1791
  const {shadow: shadow} = ui.__;
1777
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1792
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1778
1793
  const other = current.getSameCanvas();
1779
1794
  const end = shadow.length - 1;
1780
- toOffsetOutBounds$1(bounds, offsetOutBounds$1);
1795
+ toOffsetOutBounds$1(bounds, offsetOutBounds$1, renderBounds);
1781
1796
  shadow.forEach((item, index) => {
1782
1797
  let otherScale = 1;
1783
1798
  if (item.scaleFixed) {
1784
1799
  const sx = Math.abs(nowWorld.scaleX);
1785
1800
  if (sx > 1) otherScale = 1 / sx;
1786
1801
  }
1787
- other.setWorldShadow(offsetOutBounds$1.offsetX + item.x * scaleX * otherScale, offsetOutBounds$1.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale, draw.ColorConvert.string(item.color));
1788
- spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1789
- drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
1790
- copyBounds = bounds;
1802
+ other.setWorldShadow(offsetOutBounds$1.offsetX + (item.x || 0) * scaleX * otherScale, offsetOutBounds$1.offsetY + (item.y || 0) * scaleY * otherScale, (item.blur || 0) * scaleX * otherScale, draw.ColorConvert.string(item.color));
1803
+ transform = draw.Effect.getShadowTransform(ui, other, shape, item, offsetOutBounds$1, otherScale);
1804
+ if (transform) other.setTransform(transform);
1805
+ drawWorldShadow(other, offsetOutBounds$1, shape);
1806
+ if (transform) other.resetTransform();
1807
+ copyBounds = renderBounds;
1791
1808
  if (item.box) {
1792
1809
  other.restore();
1793
1810
  other.save();
1794
1811
  if (worldCanvas) {
1795
- other.copyWorld(other, bounds, nowWorld, "copy");
1812
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
1796
1813
  copyBounds = nowWorld;
1797
1814
  }
1798
1815
  worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
1799
1816
  }
1800
- if (draw.Effect.isTransformShadow(item)) draw.Effect.renderTransformShadow(ui, current, other, copyBounds, item); else core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1817
+ core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1801
1818
  if (end && index < end) other.clearWorld(copyBounds);
1802
1819
  });
1803
1820
  other.recycle(copyBounds);
1804
1821
  }
1805
1822
 
1806
- function getShadowSpread(_ui, shadow) {
1807
- let width = 0;
1808
- shadow.forEach(item => width = Math.max(width, Math.max(Math.abs(item.y), Math.abs(item.x)) + (item.spread > 0 ? item.spread : 0) + item.blur * 1.5));
1809
- return width;
1823
+ function getShadowRenderSpread(_ui, shadow) {
1824
+ let top = 0, right = 0, bottom = 0, left = 0, x, y, spread, blur;
1825
+ shadow.forEach(item => {
1826
+ x = item.x || 0, y = item.y || 0, spread = item.spread || 0, blur = (item.blur || 0) * 1.5;
1827
+ top = max(top, spread + blur - y);
1828
+ right = max(right, spread + blur + x);
1829
+ bottom = max(bottom, spread + blur + y);
1830
+ left = max(left, spread + blur - x);
1831
+ });
1832
+ return top === right && right === bottom && bottom === left ? top : [ top, right, bottom, left ];
1833
+ }
1834
+
1835
+ function getShadowTransform(ui, canvas, _shape, shadow, outBounds, otherScale, isInnerShaodw) {
1836
+ if (shadow.spread) {
1837
+ const spreadScale = 1 + shadow.spread * 2 / ui.__layout.strokeBounds.width * otherScale * (isInnerShaodw ? -1 : 1);
1838
+ tempMatrix.set().scaleOfOuter({
1839
+ x: (outBounds.x + outBounds.width / 2) * canvas.pixelRatio,
1840
+ y: (outBounds.y + outBounds.height / 2) * canvas.pixelRatio
1841
+ }, spreadScale);
1842
+ return tempMatrix;
1843
+ }
1844
+ return undefined;
1810
1845
  }
1811
1846
 
1812
- function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1813
- const {bounds: bounds, shapeBounds: shapeBounds} = shape;
1847
+ function drawWorldShadow(canvas, outBounds, shape) {
1848
+ const {shapeBounds: shapeBounds} = shape;
1849
+ let from, to;
1814
1850
  if (core.Platform.fullImageShadow) {
1815
1851
  copy(tempBounds, canvas.bounds);
1816
- tempBounds.x += outBounds.x - shapeBounds.x;
1817
- tempBounds.y += outBounds.y - shapeBounds.y;
1818
- if (spreadScale) {
1819
- const {fitMatrix: fitMatrix} = shape;
1820
- tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1821
- tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1822
- tempBounds.width *= spreadScale;
1823
- tempBounds.height *= spreadScale;
1824
- }
1825
- canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
1852
+ move(tempBounds, outBounds.x - shapeBounds.x, outBounds.y - shapeBounds.y);
1853
+ from = canvas.bounds, to = tempBounds;
1826
1854
  } else {
1827
- if (spreadScale) {
1828
- copy(tempBounds, outBounds);
1829
- tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
1830
- tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
1831
- tempBounds.width *= spreadScale;
1832
- tempBounds.height *= spreadScale;
1833
- }
1834
- canvas.copyWorld(shape.canvas, shapeBounds, spreadScale ? tempBounds : outBounds);
1855
+ from = shapeBounds, to = outBounds;
1835
1856
  }
1857
+ canvas.copyWorld(shape.canvas, from, to);
1836
1858
  }
1837
1859
 
1838
1860
  const {toOffsetOutBounds: toOffsetOutBounds} = core.BoundsHelper;
@@ -1840,13 +1862,13 @@ const {toOffsetOutBounds: toOffsetOutBounds} = core.BoundsHelper;
1840
1862
  const offsetOutBounds = {};
1841
1863
 
1842
1864
  function innerShadow(ui, current, shape) {
1843
- let copyBounds, spreadScale;
1844
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
1865
+ let copyBounds, transform;
1866
+ const {__nowWorld: nowWorld} = ui;
1845
1867
  const {innerShadow: innerShadow} = ui.__;
1846
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1868
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1847
1869
  const other = current.getSameCanvas();
1848
1870
  const end = innerShadow.length - 1;
1849
- toOffsetOutBounds(bounds, offsetOutBounds);
1871
+ toOffsetOutBounds(bounds, offsetOutBounds, renderBounds);
1850
1872
  innerShadow.forEach((item, index) => {
1851
1873
  let otherScale = 1;
1852
1874
  if (item.scaleFixed) {
@@ -1854,17 +1876,18 @@ function innerShadow(ui, current, shape) {
1854
1876
  if (sx > 1) otherScale = 1 / sx;
1855
1877
  }
1856
1878
  other.save();
1857
- other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
1858
- spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1859
- drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1879
+ other.setWorldShadow(offsetOutBounds.offsetX + (item.x || 0) * scaleX * otherScale, offsetOutBounds.offsetY + (item.y || 0) * scaleY * otherScale, (item.blur || 0) * scaleX * otherScale);
1880
+ transform = draw.Effect.getShadowTransform(ui, other, shape, item, offsetOutBounds, otherScale, true);
1881
+ if (transform) other.setTransform(transform);
1882
+ drawWorldShadow(other, offsetOutBounds, shape);
1860
1883
  other.restore();
1861
1884
  if (worldCanvas) {
1862
- other.copyWorld(other, bounds, nowWorld, "copy");
1885
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
1863
1886
  other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
1864
1887
  copyBounds = nowWorld;
1865
1888
  } else {
1866
1889
  other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
1867
- copyBounds = bounds;
1890
+ copyBounds = renderBounds;
1868
1891
  }
1869
1892
  other.fillWorld(copyBounds, draw.ColorConvert.string(item.color), "source-in");
1870
1893
  core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
@@ -1873,6 +1896,8 @@ function innerShadow(ui, current, shape) {
1873
1896
  other.recycle(copyBounds);
1874
1897
  }
1875
1898
 
1899
+ const getInnerShadowSpread = getShadowRenderSpread;
1900
+
1876
1901
  function blur(ui, current, origin) {
1877
1902
  const {blur: blur} = ui.__;
1878
1903
  origin.setWorldBlur(blur * ui.__nowWorld.a);
@@ -1887,10 +1912,12 @@ const EffectModule = {
1887
1912
  innerShadow: innerShadow,
1888
1913
  blur: blur,
1889
1914
  backgroundBlur: backgroundBlur,
1890
- getShadowSpread: getShadowSpread,
1915
+ getShadowRenderSpread: getShadowRenderSpread,
1916
+ getShadowTransform: getShadowTransform,
1891
1917
  isTransformShadow(_shadow) {
1892
1918
  return undefined;
1893
- }
1919
+ },
1920
+ getInnerShadowSpread: getInnerShadowSpread
1894
1921
  };
1895
1922
 
1896
1923
  const {excludeRenderBounds: excludeRenderBounds} = core.LeafBoundsHelper;
@@ -1907,6 +1934,7 @@ draw.Group.prototype.__renderMask = function(canvas, options) {
1907
1934
  maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1908
1935
  maskCanvas = contentCanvas = null;
1909
1936
  }
1937
+ if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1910
1938
  maskOpacity = child.__.opacity;
1911
1939
  usedGrayscaleAlpha = false;
1912
1940
  if (mask === "path" || mask === "clipping-path") {
@@ -1924,7 +1952,6 @@ draw.Group.prototype.__renderMask = function(canvas, options) {
1924
1952
  if (!contentCanvas) contentCanvas = getCanvas(canvas);
1925
1953
  child.__render(maskCanvas, options);
1926
1954
  }
1927
- if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1928
1955
  continue;
1929
1956
  }
1930
1957
  const childBlendMode = maskOpacity === 1 && child.__.__blendMode;
@@ -2486,6 +2513,7 @@ const TextConvertModule = {
2486
2513
  };
2487
2514
 
2488
2515
  function string(color, opacity) {
2516
+ if (!color) return "#000";
2489
2517
  const doOpacity = core.isNumber(opacity) && opacity < 1;
2490
2518
  if (core.isString(color)) {
2491
2519
  if (doOpacity && draw.ColorConvert.object) color = draw.ColorConvert.object(color); else return color;