leafer-ui 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/web.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Debug, LeaferCanvasBase, Platform, isString, isUndefined, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, Plugin, MathHelper, isObject, Matrix, getMatrixData, MatrixHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4, isNumber } from "@leafer/core";
1
+ import { Debug, LeaferCanvasBase, Platform, isString, isUndefined, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, Plugin, MathHelper, isObject, FourNumberHelper, Matrix, getMatrixData, MatrixHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4, isNumber } from "@leafer/core";
2
2
 
3
3
  export * from "@leafer/core";
4
4
 
@@ -43,7 +43,7 @@ class LeaferCanvas extends LeaferCanvasBase {
43
43
  }
44
44
  if (Platform.syncDomFont && !this.parentView) {
45
45
  style.display = "none";
46
- document.body.appendChild(this.view);
46
+ if (document.body) document.body.appendChild(this.view);
47
47
  }
48
48
  this.__createContext();
49
49
  if (!this.autoLayout) this.resize(config);
@@ -639,6 +639,7 @@ class Renderer {
639
639
  usePartRender: true,
640
640
  maxFPS: 120
641
641
  };
642
+ this.frames = [];
642
643
  this.target = target;
643
644
  this.canvas = canvas;
644
645
  if (userConfig) this.config = DataHelper.default(userConfig, this.config);
@@ -791,12 +792,15 @@ class Renderer {
791
792
  const target = this.target;
792
793
  if (this.requestTime || !target) return;
793
794
  if (target.parentApp) return target.parentApp.requestRender(false);
794
- const requestTime = this.requestTime = Date.now();
795
+ this.requestTime = this.frameTime || Date.now();
795
796
  const render = () => {
796
- const nowFPS = 1e3 / (Date.now() - requestTime);
797
+ const nowFPS = 1e3 / ((this.frameTime = Date.now()) - this.requestTime);
797
798
  const {maxFPS: maxFPS} = this.config;
798
- if (maxFPS && nowFPS > maxFPS - .5) return Platform.requestRender(render);
799
- this.FPS = Math.min(120, Math.ceil(nowFPS));
799
+ if (maxFPS && nowFPS > maxFPS) return Platform.requestRender(render);
800
+ const {frames: frames} = this;
801
+ if (frames.length > 30) frames.shift();
802
+ frames.push(nowFPS);
803
+ this.FPS = Math.round(frames.reduce((a, b) => a + b, 0) / frames.length);
800
804
  this.requestTime = 0;
801
805
  this.checkRender();
802
806
  };
@@ -1574,24 +1578,29 @@ function drawOutside(stroke, ui, canvas) {
1574
1578
  }
1575
1579
  }
1576
1580
 
1577
- const {getSpread: getSpread, getOuterOf: getOuterOf, getByMove: getByMove, getIntersectData: getIntersectData} = BoundsHelper;
1581
+ const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = BoundsHelper;
1582
+
1583
+ const tempBounds$1 = {};
1578
1584
 
1579
1585
  function shape(ui, current, options) {
1580
1586
  const canvas = current.getSameCanvas();
1581
- const nowWorld = ui.__nowWorld, currentBounds = current.bounds;
1582
- let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
1587
+ const currentBounds = current.bounds, nowWorld = ui.__nowWorld, layout = ui.__layout;
1588
+ const nowWorldShapeBounds = ui.__nowWorldShapeBounds || (ui.__nowWorldShapeBounds = {});
1589
+ toOuterOf(layout.strokeSpread ? (copyAndSpread(tempBounds$1, layout.boxBounds, layout.strokeSpread),
1590
+ tempBounds$1) : layout.boxBounds, nowWorld, nowWorldShapeBounds);
1591
+ let bounds, renderBounds, matrix, fitMatrix, shapeBounds, worldCanvas;
1583
1592
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
1584
- if (currentBounds.includes(nowWorld)) {
1593
+ if (currentBounds.includes(nowWorldShapeBounds)) {
1585
1594
  worldCanvas = canvas;
1586
- bounds = shapeBounds = nowWorld;
1595
+ bounds = shapeBounds = nowWorldShapeBounds;
1596
+ renderBounds = nowWorld;
1587
1597
  } else {
1588
- const {renderShapeSpread: spread} = ui.__layout;
1589
1598
  let worldClipBounds;
1590
1599
  if (Platform.fullImageShadow) {
1591
- worldClipBounds = nowWorld;
1600
+ worldClipBounds = nowWorldShapeBounds;
1592
1601
  } else {
1593
- const spreadBounds = spread ? getSpread(currentBounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : currentBounds;
1594
- worldClipBounds = getIntersectData(spreadBounds, nowWorld);
1602
+ const spreadBounds = layout.renderShapeSpread ? getSpread(currentBounds, FourNumberHelper.swapAndScale(layout.renderShapeSpread, scaleX, scaleY)) : currentBounds;
1603
+ worldClipBounds = getIntersectData(spreadBounds, nowWorldShapeBounds);
1595
1604
  }
1596
1605
  fitMatrix = currentBounds.getFitMatrix(worldClipBounds);
1597
1606
  let {a: fitScaleX, d: fitScaleY} = fitMatrix;
@@ -1601,8 +1610,10 @@ function shape(ui, current, options) {
1601
1610
  scaleX *= fitScaleX;
1602
1611
  scaleY *= fitScaleY;
1603
1612
  }
1604
- shapeBounds = getOuterOf(nowWorld, fitMatrix);
1613
+ shapeBounds = getOuterOf(nowWorldShapeBounds, fitMatrix);
1605
1614
  bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1615
+ renderBounds = getOuterOf(nowWorld, fitMatrix);
1616
+ move$1(renderBounds, -fitMatrix.e, -fitMatrix.f);
1606
1617
  const userMatrix = options.matrix;
1607
1618
  if (userMatrix) {
1608
1619
  matrix = new Matrix(fitMatrix);
@@ -1621,6 +1632,7 @@ function shape(ui, current, options) {
1621
1632
  matrix: matrix,
1622
1633
  fitMatrix: fitMatrix,
1623
1634
  bounds: bounds,
1635
+ renderBounds: renderBounds,
1624
1636
  worldCanvas: worldCanvas,
1625
1637
  shapeBounds: shapeBounds,
1626
1638
  scaleX: scaleX,
@@ -1724,7 +1736,7 @@ const PaintModule = {
1724
1736
  shape: shape
1725
1737
  };
1726
1738
 
1727
- let origin = {}, tempMatrix = getMatrixData();
1739
+ let origin = {}, tempMatrix$1 = getMatrixData();
1728
1740
 
1729
1741
  const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
1730
1742
 
@@ -1739,12 +1751,12 @@ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1739
1751
  data.transform = transform;
1740
1752
  }
1741
1753
 
1742
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
1754
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1743
1755
  const transform = get$3();
1744
1756
  layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1745
- if (clipSize) {
1746
- tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
1747
- multiplyParent(transform, tempMatrix);
1757
+ if (clipScaleX) {
1758
+ tempMatrix$1.a = clipScaleX, tempMatrix$1.d = clipScaleY;
1759
+ multiplyParent(transform, tempMatrix$1);
1748
1760
  }
1749
1761
  data.transform = transform;
1750
1762
  }
@@ -1845,7 +1857,12 @@ function getPatternData(paint, box, image) {
1845
1857
 
1846
1858
  case "normal":
1847
1859
  case "clip":
1848
- if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1860
+ if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1861
+ let clipScaleX, clipScaleY;
1862
+ if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1863
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1864
+ if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : scaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1865
+ }
1849
1866
  break;
1850
1867
 
1851
1868
  case "repeat":
@@ -2003,7 +2020,7 @@ function ignoreRender(ui, value) {
2003
2020
 
2004
2021
  const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
2005
2022
 
2006
- const {floor: floor, ceil: ceil, max: max, abs: abs} = Math;
2023
+ const {floor: floor, ceil: ceil, max: max$1, abs: abs} = Math;
2007
2024
 
2008
2025
  function createPattern(ui, paint, pixelRatio) {
2009
2026
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
@@ -2052,8 +2069,8 @@ function createPattern(ui, paint, pixelRatio) {
2052
2069
  if (transform || scaleX !== 1 || scaleY !== 1) {
2053
2070
  const canvasWidth = width + (xGap || 0);
2054
2071
  const canvasHeight = height + (yGap || 0);
2055
- scaleX /= canvasWidth / max(floor(canvasWidth), 1);
2056
- scaleY /= canvasHeight / max(floor(canvasHeight), 1);
2072
+ scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
2073
+ scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
2057
2074
  if (!imageMatrix) {
2058
2075
  imageMatrix = get$1();
2059
2076
  if (transform) copy$1(imageMatrix, transform);
@@ -2112,17 +2129,15 @@ function checkImage(ui, canvas, paint, allowDraw) {
2112
2129
  if (allowDraw) {
2113
2130
  if (data.repeat) {
2114
2131
  allowDraw = false;
2115
- } else {
2116
- if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
2117
- let {width: width, height: height} = data;
2118
- width *= scaleX * pixelRatio;
2119
- height *= scaleY * pixelRatio;
2120
- if (data.scaleX) {
2121
- width *= data.scaleX;
2122
- height *= data.scaleY;
2123
- }
2124
- allowDraw = width * height > Platform.image.maxCacheSize;
2132
+ } else if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
2133
+ let {width: width, height: height} = data;
2134
+ width *= scaleX * pixelRatio;
2135
+ height *= scaleY * pixelRatio;
2136
+ if (data.scaleX) {
2137
+ width *= data.scaleX;
2138
+ height *= data.scaleY;
2125
2139
  }
2140
+ allowDraw = width * height > Platform.image.maxCacheSize;
2126
2141
  }
2127
2142
  }
2128
2143
  if (allowDraw) {
@@ -2302,75 +2317,82 @@ const PaintGradientModule = {
2302
2317
  getTransform: getTransform
2303
2318
  };
2304
2319
 
2305
- const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = BoundsHelper;
2320
+ const {copy: copy, move: move, toOffsetOutBounds: toOffsetOutBounds$1} = BoundsHelper, {max: max} = Math;
2306
2321
 
2307
- const tempBounds = {};
2322
+ const tempBounds = {}, tempMatrix = new Matrix;
2308
2323
 
2309
2324
  const offsetOutBounds$1 = {};
2310
2325
 
2311
2326
  function shadow(ui, current, shape) {
2312
- let copyBounds, spreadScale;
2313
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
2327
+ let copyBounds, transform;
2328
+ const {__nowWorld: nowWorld} = ui;
2314
2329
  const {shadow: shadow} = ui.__;
2315
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
2330
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
2316
2331
  const other = current.getSameCanvas();
2317
2332
  const end = shadow.length - 1;
2318
- toOffsetOutBounds$1(bounds, offsetOutBounds$1);
2333
+ toOffsetOutBounds$1(bounds, offsetOutBounds$1, renderBounds);
2319
2334
  shadow.forEach((item, index) => {
2320
2335
  let otherScale = 1;
2321
2336
  if (item.scaleFixed) {
2322
2337
  const sx = Math.abs(nowWorld.scaleX);
2323
2338
  if (sx > 1) otherScale = 1 / sx;
2324
2339
  }
2325
- other.setWorldShadow(offsetOutBounds$1.offsetX + item.x * scaleX * otherScale, offsetOutBounds$1.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale, ColorConvert.string(item.color));
2326
- spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
2327
- drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
2328
- copyBounds = bounds;
2340
+ other.setWorldShadow(offsetOutBounds$1.offsetX + (item.x || 0) * scaleX * otherScale, offsetOutBounds$1.offsetY + (item.y || 0) * scaleY * otherScale, (item.blur || 0) * scaleX * otherScale, ColorConvert.string(item.color));
2341
+ transform = Effect.getShadowTransform(ui, other, shape, item, offsetOutBounds$1, otherScale);
2342
+ if (transform) other.setTransform(transform);
2343
+ drawWorldShadow(other, offsetOutBounds$1, shape);
2344
+ if (transform) other.resetTransform();
2345
+ copyBounds = renderBounds;
2329
2346
  if (item.box) {
2330
2347
  other.restore();
2331
2348
  other.save();
2332
2349
  if (worldCanvas) {
2333
- other.copyWorld(other, bounds, nowWorld, "copy");
2350
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
2334
2351
  copyBounds = nowWorld;
2335
2352
  }
2336
2353
  worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
2337
2354
  }
2338
- if (Effect.isTransformShadow(item)) Effect.renderTransformShadow(ui, current, other, copyBounds, item); else LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
2355
+ LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
2339
2356
  if (end && index < end) other.clearWorld(copyBounds);
2340
2357
  });
2341
2358
  other.recycle(copyBounds);
2342
2359
  }
2343
2360
 
2344
- function getShadowSpread(_ui, shadow) {
2345
- let width = 0;
2346
- 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));
2347
- return width;
2361
+ function getShadowRenderSpread(_ui, shadow) {
2362
+ let top = 0, right = 0, bottom = 0, left = 0, x, y, spread, blur;
2363
+ shadow.forEach(item => {
2364
+ x = item.x || 0, y = item.y || 0, spread = item.spread || 0, blur = (item.blur || 0) * 1.5;
2365
+ top = max(top, spread + blur - y);
2366
+ right = max(right, spread + blur + x);
2367
+ bottom = max(bottom, spread + blur + y);
2368
+ left = max(left, spread + blur - x);
2369
+ });
2370
+ return top === right && right === bottom && bottom === left ? top : [ top, right, bottom, left ];
2348
2371
  }
2349
2372
 
2350
- function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
2351
- const {bounds: bounds, shapeBounds: shapeBounds} = shape;
2373
+ function getShadowTransform(ui, canvas, _shape, shadow, outBounds, otherScale, isInnerShaodw) {
2374
+ if (shadow.spread) {
2375
+ const spreadScale = 1 + shadow.spread * 2 / ui.__layout.strokeBounds.width * otherScale * (isInnerShaodw ? -1 : 1);
2376
+ tempMatrix.set().scaleOfOuter({
2377
+ x: (outBounds.x + outBounds.width / 2) * canvas.pixelRatio,
2378
+ y: (outBounds.y + outBounds.height / 2) * canvas.pixelRatio
2379
+ }, spreadScale);
2380
+ return tempMatrix;
2381
+ }
2382
+ return undefined;
2383
+ }
2384
+
2385
+ function drawWorldShadow(canvas, outBounds, shape) {
2386
+ const {shapeBounds: shapeBounds} = shape;
2387
+ let from, to;
2352
2388
  if (Platform.fullImageShadow) {
2353
2389
  copy(tempBounds, canvas.bounds);
2354
- tempBounds.x += outBounds.x - shapeBounds.x;
2355
- tempBounds.y += outBounds.y - shapeBounds.y;
2356
- if (spreadScale) {
2357
- const {fitMatrix: fitMatrix} = shape;
2358
- tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
2359
- tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
2360
- tempBounds.width *= spreadScale;
2361
- tempBounds.height *= spreadScale;
2362
- }
2363
- canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
2390
+ move(tempBounds, outBounds.x - shapeBounds.x, outBounds.y - shapeBounds.y);
2391
+ from = canvas.bounds, to = tempBounds;
2364
2392
  } else {
2365
- if (spreadScale) {
2366
- copy(tempBounds, outBounds);
2367
- tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
2368
- tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
2369
- tempBounds.width *= spreadScale;
2370
- tempBounds.height *= spreadScale;
2371
- }
2372
- canvas.copyWorld(shape.canvas, shapeBounds, spreadScale ? tempBounds : outBounds);
2393
+ from = shapeBounds, to = outBounds;
2373
2394
  }
2395
+ canvas.copyWorld(shape.canvas, from, to);
2374
2396
  }
2375
2397
 
2376
2398
  const {toOffsetOutBounds: toOffsetOutBounds} = BoundsHelper;
@@ -2378,13 +2400,13 @@ const {toOffsetOutBounds: toOffsetOutBounds} = BoundsHelper;
2378
2400
  const offsetOutBounds = {};
2379
2401
 
2380
2402
  function innerShadow(ui, current, shape) {
2381
- let copyBounds, spreadScale;
2382
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
2403
+ let copyBounds, transform;
2404
+ const {__nowWorld: nowWorld} = ui;
2383
2405
  const {innerShadow: innerShadow} = ui.__;
2384
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
2406
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
2385
2407
  const other = current.getSameCanvas();
2386
2408
  const end = innerShadow.length - 1;
2387
- toOffsetOutBounds(bounds, offsetOutBounds);
2409
+ toOffsetOutBounds(bounds, offsetOutBounds, renderBounds);
2388
2410
  innerShadow.forEach((item, index) => {
2389
2411
  let otherScale = 1;
2390
2412
  if (item.scaleFixed) {
@@ -2392,17 +2414,18 @@ function innerShadow(ui, current, shape) {
2392
2414
  if (sx > 1) otherScale = 1 / sx;
2393
2415
  }
2394
2416
  other.save();
2395
- other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
2396
- spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
2397
- drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
2417
+ other.setWorldShadow(offsetOutBounds.offsetX + (item.x || 0) * scaleX * otherScale, offsetOutBounds.offsetY + (item.y || 0) * scaleY * otherScale, (item.blur || 0) * scaleX * otherScale);
2418
+ transform = Effect.getShadowTransform(ui, other, shape, item, offsetOutBounds, otherScale, true);
2419
+ if (transform) other.setTransform(transform);
2420
+ drawWorldShadow(other, offsetOutBounds, shape);
2398
2421
  other.restore();
2399
2422
  if (worldCanvas) {
2400
- other.copyWorld(other, bounds, nowWorld, "copy");
2423
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
2401
2424
  other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
2402
2425
  copyBounds = nowWorld;
2403
2426
  } else {
2404
2427
  other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
2405
- copyBounds = bounds;
2428
+ copyBounds = renderBounds;
2406
2429
  }
2407
2430
  other.fillWorld(copyBounds, ColorConvert.string(item.color), "source-in");
2408
2431
  LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
@@ -2411,6 +2434,8 @@ function innerShadow(ui, current, shape) {
2411
2434
  other.recycle(copyBounds);
2412
2435
  }
2413
2436
 
2437
+ const getInnerShadowSpread = getShadowRenderSpread;
2438
+
2414
2439
  function blur(ui, current, origin) {
2415
2440
  const {blur: blur} = ui.__;
2416
2441
  origin.setWorldBlur(blur * ui.__nowWorld.a);
@@ -2425,10 +2450,12 @@ const EffectModule = {
2425
2450
  innerShadow: innerShadow,
2426
2451
  blur: blur,
2427
2452
  backgroundBlur: backgroundBlur,
2428
- getShadowSpread: getShadowSpread,
2453
+ getShadowRenderSpread: getShadowRenderSpread,
2454
+ getShadowTransform: getShadowTransform,
2429
2455
  isTransformShadow(_shadow) {
2430
2456
  return undefined;
2431
- }
2457
+ },
2458
+ getInnerShadowSpread: getInnerShadowSpread
2432
2459
  };
2433
2460
 
2434
2461
  const {excludeRenderBounds: excludeRenderBounds} = LeafBoundsHelper;
@@ -2445,6 +2472,7 @@ Group.prototype.__renderMask = function(canvas, options) {
2445
2472
  maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
2446
2473
  maskCanvas = contentCanvas = null;
2447
2474
  }
2475
+ if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
2448
2476
  maskOpacity = child.__.opacity;
2449
2477
  usedGrayscaleAlpha = false;
2450
2478
  if (mask === "path" || mask === "clipping-path") {
@@ -2462,7 +2490,6 @@ Group.prototype.__renderMask = function(canvas, options) {
2462
2490
  if (!contentCanvas) contentCanvas = getCanvas(canvas);
2463
2491
  child.__render(maskCanvas, options);
2464
2492
  }
2465
- if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
2466
2493
  continue;
2467
2494
  }
2468
2495
  const childBlendMode = maskOpacity === 1 && child.__.__blendMode;
@@ -3024,6 +3051,7 @@ const TextConvertModule = {
3024
3051
  };
3025
3052
 
3026
3053
  function string(color, opacity) {
3054
+ if (!color) return "#000";
3027
3055
  const doOpacity = isNumber(opacity) && opacity < 1;
3028
3056
  if (isString(color)) {
3029
3057
  if (doOpacity && ColorConvert.object) color = ColorConvert.object(color); else return color;