@leafer-draw/miniapp 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/miniapp.cjs CHANGED
@@ -580,6 +580,7 @@ class Renderer {
580
580
  usePartRender: true,
581
581
  maxFPS: 120
582
582
  };
583
+ this.frames = [];
583
584
  this.target = target;
584
585
  this.canvas = canvas;
585
586
  if (userConfig) this.config = core.DataHelper.default(userConfig, this.config);
@@ -732,12 +733,15 @@ class Renderer {
732
733
  const target = this.target;
733
734
  if (this.requestTime || !target) return;
734
735
  if (target.parentApp) return target.parentApp.requestRender(false);
735
- const requestTime = this.requestTime = Date.now();
736
+ this.requestTime = this.frameTime || Date.now();
736
737
  const render = () => {
737
- const nowFPS = 1e3 / (Date.now() - requestTime);
738
+ const nowFPS = 1e3 / ((this.frameTime = Date.now()) - this.requestTime);
738
739
  const {maxFPS: maxFPS} = this.config;
739
- if (maxFPS && nowFPS > maxFPS - .5) return core.Platform.requestRender(render);
740
- this.FPS = Math.min(120, Math.ceil(nowFPS));
740
+ if (maxFPS && nowFPS > maxFPS) return core.Platform.requestRender(render);
741
+ const {frames: frames} = this;
742
+ if (frames.length > 30) frames.shift();
743
+ frames.push(nowFPS);
744
+ this.FPS = Math.round(frames.reduce((a, b) => a + b, 0) / frames.length);
741
745
  this.requestTime = 0;
742
746
  this.checkRender();
743
747
  };
@@ -1004,24 +1008,29 @@ function drawOutside(stroke, ui, canvas) {
1004
1008
  }
1005
1009
  }
1006
1010
 
1007
- const {getSpread: getSpread, getOuterOf: getOuterOf, getByMove: getByMove, getIntersectData: getIntersectData} = core.BoundsHelper;
1011
+ const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = core.BoundsHelper;
1012
+
1013
+ const tempBounds$1 = {};
1008
1014
 
1009
1015
  function shape(ui, current, options) {
1010
1016
  const canvas = current.getSameCanvas();
1011
- const nowWorld = ui.__nowWorld, currentBounds = current.bounds;
1012
- let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
1017
+ const currentBounds = current.bounds, nowWorld = ui.__nowWorld, layout = ui.__layout;
1018
+ const nowWorldShapeBounds = ui.__nowWorldShapeBounds || (ui.__nowWorldShapeBounds = {});
1019
+ toOuterOf(layout.strokeSpread ? (copyAndSpread(tempBounds$1, layout.boxBounds, layout.strokeSpread),
1020
+ tempBounds$1) : layout.boxBounds, nowWorld, nowWorldShapeBounds);
1021
+ let bounds, renderBounds, matrix, fitMatrix, shapeBounds, worldCanvas;
1013
1022
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
1014
- if (currentBounds.includes(nowWorld)) {
1023
+ if (currentBounds.includes(nowWorldShapeBounds)) {
1015
1024
  worldCanvas = canvas;
1016
- bounds = shapeBounds = nowWorld;
1025
+ bounds = shapeBounds = nowWorldShapeBounds;
1026
+ renderBounds = nowWorld;
1017
1027
  } else {
1018
- const {renderShapeSpread: spread} = ui.__layout;
1019
1028
  let worldClipBounds;
1020
1029
  if (core.Platform.fullImageShadow) {
1021
- worldClipBounds = nowWorld;
1030
+ worldClipBounds = nowWorldShapeBounds;
1022
1031
  } else {
1023
- const spreadBounds = spread ? getSpread(currentBounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : currentBounds;
1024
- worldClipBounds = getIntersectData(spreadBounds, nowWorld);
1032
+ const spreadBounds = layout.renderShapeSpread ? getSpread(currentBounds, core.FourNumberHelper.swapAndScale(layout.renderShapeSpread, scaleX, scaleY)) : currentBounds;
1033
+ worldClipBounds = getIntersectData(spreadBounds, nowWorldShapeBounds);
1025
1034
  }
1026
1035
  fitMatrix = currentBounds.getFitMatrix(worldClipBounds);
1027
1036
  let {a: fitScaleX, d: fitScaleY} = fitMatrix;
@@ -1031,8 +1040,10 @@ function shape(ui, current, options) {
1031
1040
  scaleX *= fitScaleX;
1032
1041
  scaleY *= fitScaleY;
1033
1042
  }
1034
- shapeBounds = getOuterOf(nowWorld, fitMatrix);
1043
+ shapeBounds = getOuterOf(nowWorldShapeBounds, fitMatrix);
1035
1044
  bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1045
+ renderBounds = getOuterOf(nowWorld, fitMatrix);
1046
+ move$1(renderBounds, -fitMatrix.e, -fitMatrix.f);
1036
1047
  const userMatrix = options.matrix;
1037
1048
  if (userMatrix) {
1038
1049
  matrix = new core.Matrix(fitMatrix);
@@ -1051,6 +1062,7 @@ function shape(ui, current, options) {
1051
1062
  matrix: matrix,
1052
1063
  fitMatrix: fitMatrix,
1053
1064
  bounds: bounds,
1065
+ renderBounds: renderBounds,
1054
1066
  worldCanvas: worldCanvas,
1055
1067
  shapeBounds: shapeBounds,
1056
1068
  scaleX: scaleX,
@@ -1154,7 +1166,7 @@ const PaintModule = {
1154
1166
  shape: shape
1155
1167
  };
1156
1168
 
1157
- let origin = {}, tempMatrix = core.getMatrixData();
1169
+ let origin = {}, tempMatrix$1 = core.getMatrixData();
1158
1170
 
1159
1171
  const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
1160
1172
 
@@ -1169,12 +1181,12 @@ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1169
1181
  data.transform = transform;
1170
1182
  }
1171
1183
 
1172
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
1184
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1173
1185
  const transform = get$3();
1174
1186
  layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1175
- if (clipSize) {
1176
- tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
1177
- multiplyParent(transform, tempMatrix);
1187
+ if (clipScaleX) {
1188
+ tempMatrix$1.a = clipScaleX, tempMatrix$1.d = clipScaleY;
1189
+ multiplyParent(transform, tempMatrix$1);
1178
1190
  }
1179
1191
  data.transform = transform;
1180
1192
  }
@@ -1275,7 +1287,12 @@ function getPatternData(paint, box, image) {
1275
1287
 
1276
1288
  case "normal":
1277
1289
  case "clip":
1278
- if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1290
+ if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1291
+ let clipScaleX, clipScaleY;
1292
+ if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1293
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1294
+ if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : scaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1295
+ }
1279
1296
  break;
1280
1297
 
1281
1298
  case "repeat":
@@ -1433,7 +1450,7 @@ function ignoreRender(ui, value) {
1433
1450
 
1434
1451
  const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1435
1452
 
1436
- const {floor: floor, ceil: ceil, max: max, abs: abs} = Math;
1453
+ const {floor: floor, ceil: ceil, max: max$1, abs: abs} = Math;
1437
1454
 
1438
1455
  function createPattern(ui, paint, pixelRatio) {
1439
1456
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
@@ -1482,8 +1499,8 @@ function createPattern(ui, paint, pixelRatio) {
1482
1499
  if (transform || scaleX !== 1 || scaleY !== 1) {
1483
1500
  const canvasWidth = width + (xGap || 0);
1484
1501
  const canvasHeight = height + (yGap || 0);
1485
- scaleX /= canvasWidth / max(floor(canvasWidth), 1);
1486
- scaleY /= canvasHeight / max(floor(canvasHeight), 1);
1502
+ scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1503
+ scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1487
1504
  if (!imageMatrix) {
1488
1505
  imageMatrix = get$1();
1489
1506
  if (transform) copy$1(imageMatrix, transform);
@@ -1542,17 +1559,15 @@ function checkImage(ui, canvas, paint, allowDraw) {
1542
1559
  if (allowDraw) {
1543
1560
  if (data.repeat) {
1544
1561
  allowDraw = false;
1545
- } else {
1546
- if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1547
- let {width: width, height: height} = data;
1548
- width *= scaleX * pixelRatio;
1549
- height *= scaleY * pixelRatio;
1550
- if (data.scaleX) {
1551
- width *= data.scaleX;
1552
- height *= data.scaleY;
1553
- }
1554
- allowDraw = width * height > core.Platform.image.maxCacheSize;
1562
+ } else if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1563
+ let {width: width, height: height} = data;
1564
+ width *= scaleX * pixelRatio;
1565
+ height *= scaleY * pixelRatio;
1566
+ if (data.scaleX) {
1567
+ width *= data.scaleX;
1568
+ height *= data.scaleY;
1555
1569
  }
1570
+ allowDraw = width * height > core.Platform.image.maxCacheSize;
1556
1571
  }
1557
1572
  }
1558
1573
  if (allowDraw) {
@@ -1732,75 +1747,82 @@ const PaintGradientModule = {
1732
1747
  getTransform: getTransform
1733
1748
  };
1734
1749
 
1735
- const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = core.BoundsHelper;
1750
+ const {copy: copy, move: move, toOffsetOutBounds: toOffsetOutBounds$1} = core.BoundsHelper, {max: max} = Math;
1736
1751
 
1737
- const tempBounds = {};
1752
+ const tempBounds = {}, tempMatrix = new core.Matrix;
1738
1753
 
1739
1754
  const offsetOutBounds$1 = {};
1740
1755
 
1741
1756
  function shadow(ui, current, shape) {
1742
- let copyBounds, spreadScale;
1743
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
1757
+ let copyBounds, transform;
1758
+ const {__nowWorld: nowWorld} = ui;
1744
1759
  const {shadow: shadow} = ui.__;
1745
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1760
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1746
1761
  const other = current.getSameCanvas();
1747
1762
  const end = shadow.length - 1;
1748
- toOffsetOutBounds$1(bounds, offsetOutBounds$1);
1763
+ toOffsetOutBounds$1(bounds, offsetOutBounds$1, renderBounds);
1749
1764
  shadow.forEach((item, index) => {
1750
1765
  let otherScale = 1;
1751
1766
  if (item.scaleFixed) {
1752
1767
  const sx = Math.abs(nowWorld.scaleX);
1753
1768
  if (sx > 1) otherScale = 1 / sx;
1754
1769
  }
1755
- 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));
1756
- spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1757
- drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
1758
- copyBounds = bounds;
1770
+ 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));
1771
+ transform = draw.Effect.getShadowTransform(ui, other, shape, item, offsetOutBounds$1, otherScale);
1772
+ if (transform) other.setTransform(transform);
1773
+ drawWorldShadow(other, offsetOutBounds$1, shape);
1774
+ if (transform) other.resetTransform();
1775
+ copyBounds = renderBounds;
1759
1776
  if (item.box) {
1760
1777
  other.restore();
1761
1778
  other.save();
1762
1779
  if (worldCanvas) {
1763
- other.copyWorld(other, bounds, nowWorld, "copy");
1780
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
1764
1781
  copyBounds = nowWorld;
1765
1782
  }
1766
1783
  worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
1767
1784
  }
1768
- if (draw.Effect.isTransformShadow(item)) draw.Effect.renderTransformShadow(ui, current, other, copyBounds, item); else core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1785
+ core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1769
1786
  if (end && index < end) other.clearWorld(copyBounds);
1770
1787
  });
1771
1788
  other.recycle(copyBounds);
1772
1789
  }
1773
1790
 
1774
- function getShadowSpread(_ui, shadow) {
1775
- let width = 0;
1776
- 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));
1777
- return width;
1791
+ function getShadowRenderSpread(_ui, shadow) {
1792
+ let top = 0, right = 0, bottom = 0, left = 0, x, y, spread, blur;
1793
+ shadow.forEach(item => {
1794
+ x = item.x || 0, y = item.y || 0, spread = item.spread || 0, blur = (item.blur || 0) * 1.5;
1795
+ top = max(top, spread + blur - y);
1796
+ right = max(right, spread + blur + x);
1797
+ bottom = max(bottom, spread + blur + y);
1798
+ left = max(left, spread + blur - x);
1799
+ });
1800
+ return top === right && right === bottom && bottom === left ? top : [ top, right, bottom, left ];
1801
+ }
1802
+
1803
+ function getShadowTransform(ui, canvas, _shape, shadow, outBounds, otherScale, isInnerShaodw) {
1804
+ if (shadow.spread) {
1805
+ const spreadScale = 1 + shadow.spread * 2 / ui.__layout.strokeBounds.width * otherScale * (isInnerShaodw ? -1 : 1);
1806
+ tempMatrix.set().scaleOfOuter({
1807
+ x: (outBounds.x + outBounds.width / 2) * canvas.pixelRatio,
1808
+ y: (outBounds.y + outBounds.height / 2) * canvas.pixelRatio
1809
+ }, spreadScale);
1810
+ return tempMatrix;
1811
+ }
1812
+ return undefined;
1778
1813
  }
1779
1814
 
1780
- function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1781
- const {bounds: bounds, shapeBounds: shapeBounds} = shape;
1815
+ function drawWorldShadow(canvas, outBounds, shape) {
1816
+ const {shapeBounds: shapeBounds} = shape;
1817
+ let from, to;
1782
1818
  if (core.Platform.fullImageShadow) {
1783
1819
  copy(tempBounds, canvas.bounds);
1784
- tempBounds.x += outBounds.x - shapeBounds.x;
1785
- tempBounds.y += outBounds.y - shapeBounds.y;
1786
- if (spreadScale) {
1787
- const {fitMatrix: fitMatrix} = shape;
1788
- tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1789
- tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1790
- tempBounds.width *= spreadScale;
1791
- tempBounds.height *= spreadScale;
1792
- }
1793
- canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
1820
+ move(tempBounds, outBounds.x - shapeBounds.x, outBounds.y - shapeBounds.y);
1821
+ from = canvas.bounds, to = tempBounds;
1794
1822
  } else {
1795
- if (spreadScale) {
1796
- copy(tempBounds, outBounds);
1797
- tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
1798
- tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
1799
- tempBounds.width *= spreadScale;
1800
- tempBounds.height *= spreadScale;
1801
- }
1802
- canvas.copyWorld(shape.canvas, shapeBounds, spreadScale ? tempBounds : outBounds);
1823
+ from = shapeBounds, to = outBounds;
1803
1824
  }
1825
+ canvas.copyWorld(shape.canvas, from, to);
1804
1826
  }
1805
1827
 
1806
1828
  const {toOffsetOutBounds: toOffsetOutBounds} = core.BoundsHelper;
@@ -1808,13 +1830,13 @@ const {toOffsetOutBounds: toOffsetOutBounds} = core.BoundsHelper;
1808
1830
  const offsetOutBounds = {};
1809
1831
 
1810
1832
  function innerShadow(ui, current, shape) {
1811
- let copyBounds, spreadScale;
1812
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
1833
+ let copyBounds, transform;
1834
+ const {__nowWorld: nowWorld} = ui;
1813
1835
  const {innerShadow: innerShadow} = ui.__;
1814
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1836
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1815
1837
  const other = current.getSameCanvas();
1816
1838
  const end = innerShadow.length - 1;
1817
- toOffsetOutBounds(bounds, offsetOutBounds);
1839
+ toOffsetOutBounds(bounds, offsetOutBounds, renderBounds);
1818
1840
  innerShadow.forEach((item, index) => {
1819
1841
  let otherScale = 1;
1820
1842
  if (item.scaleFixed) {
@@ -1822,17 +1844,18 @@ function innerShadow(ui, current, shape) {
1822
1844
  if (sx > 1) otherScale = 1 / sx;
1823
1845
  }
1824
1846
  other.save();
1825
- other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
1826
- spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1827
- drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1847
+ other.setWorldShadow(offsetOutBounds.offsetX + (item.x || 0) * scaleX * otherScale, offsetOutBounds.offsetY + (item.y || 0) * scaleY * otherScale, (item.blur || 0) * scaleX * otherScale);
1848
+ transform = draw.Effect.getShadowTransform(ui, other, shape, item, offsetOutBounds, otherScale, true);
1849
+ if (transform) other.setTransform(transform);
1850
+ drawWorldShadow(other, offsetOutBounds, shape);
1828
1851
  other.restore();
1829
1852
  if (worldCanvas) {
1830
- other.copyWorld(other, bounds, nowWorld, "copy");
1853
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
1831
1854
  other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
1832
1855
  copyBounds = nowWorld;
1833
1856
  } else {
1834
1857
  other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
1835
- copyBounds = bounds;
1858
+ copyBounds = renderBounds;
1836
1859
  }
1837
1860
  other.fillWorld(copyBounds, draw.ColorConvert.string(item.color), "source-in");
1838
1861
  core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
@@ -1841,6 +1864,8 @@ function innerShadow(ui, current, shape) {
1841
1864
  other.recycle(copyBounds);
1842
1865
  }
1843
1866
 
1867
+ const getInnerShadowSpread = getShadowRenderSpread;
1868
+
1844
1869
  function blur(ui, current, origin) {
1845
1870
  const {blur: blur} = ui.__;
1846
1871
  origin.setWorldBlur(blur * ui.__nowWorld.a);
@@ -1855,10 +1880,12 @@ const EffectModule = {
1855
1880
  innerShadow: innerShadow,
1856
1881
  blur: blur,
1857
1882
  backgroundBlur: backgroundBlur,
1858
- getShadowSpread: getShadowSpread,
1883
+ getShadowRenderSpread: getShadowRenderSpread,
1884
+ getShadowTransform: getShadowTransform,
1859
1885
  isTransformShadow(_shadow) {
1860
1886
  return undefined;
1861
- }
1887
+ },
1888
+ getInnerShadowSpread: getInnerShadowSpread
1862
1889
  };
1863
1890
 
1864
1891
  const {excludeRenderBounds: excludeRenderBounds} = core.LeafBoundsHelper;
@@ -1875,6 +1902,7 @@ draw.Group.prototype.__renderMask = function(canvas, options) {
1875
1902
  maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1876
1903
  maskCanvas = contentCanvas = null;
1877
1904
  }
1905
+ if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1878
1906
  maskOpacity = child.__.opacity;
1879
1907
  usedGrayscaleAlpha = false;
1880
1908
  if (mask === "path" || mask === "clipping-path") {
@@ -1892,7 +1920,6 @@ draw.Group.prototype.__renderMask = function(canvas, options) {
1892
1920
  if (!contentCanvas) contentCanvas = getCanvas(canvas);
1893
1921
  child.__render(maskCanvas, options);
1894
1922
  }
1895
- if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1896
1923
  continue;
1897
1924
  }
1898
1925
  const childBlendMode = maskOpacity === 1 && child.__.__blendMode;
@@ -2454,6 +2481,7 @@ const TextConvertModule = {
2454
2481
  };
2455
2482
 
2456
2483
  function string(color, opacity) {
2484
+ if (!color) return "#000";
2457
2485
  const doOpacity = core.isNumber(opacity) && opacity < 1;
2458
2486
  if (core.isString(color)) {
2459
2487
  if (doOpacity && draw.ColorConvert.object) color = draw.ColorConvert.object(color); else return color;