@leafer-draw/node 1.9.7 → 1.9.8

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/node.cjs CHANGED
@@ -452,6 +452,7 @@ class Renderer {
452
452
  usePartRender: true,
453
453
  maxFPS: 120
454
454
  };
455
+ this.frames = [];
455
456
  this.target = target;
456
457
  this.canvas = canvas;
457
458
  if (userConfig) this.config = core.DataHelper.default(userConfig, this.config);
@@ -604,12 +605,15 @@ class Renderer {
604
605
  const target = this.target;
605
606
  if (this.requestTime || !target) return;
606
607
  if (target.parentApp) return target.parentApp.requestRender(false);
607
- const requestTime = this.requestTime = Date.now();
608
+ this.requestTime = this.frameTime || Date.now();
608
609
  const render = () => {
609
- const nowFPS = 1e3 / (Date.now() - requestTime);
610
+ const nowFPS = 1e3 / ((this.frameTime = Date.now()) - this.requestTime);
610
611
  const {maxFPS: maxFPS} = this.config;
611
- if (maxFPS && nowFPS > maxFPS - .5) return core.Platform.requestRender(render);
612
- this.FPS = Math.min(120, Math.ceil(nowFPS));
612
+ if (maxFPS && nowFPS > maxFPS) return core.Platform.requestRender(render);
613
+ const {frames: frames} = this;
614
+ if (frames.length > 30) frames.shift();
615
+ frames.push(nowFPS);
616
+ this.FPS = Math.round(frames.reduce((a, b) => a + b, 0) / frames.length);
613
617
  this.requestTime = 0;
614
618
  this.checkRender();
615
619
  };
@@ -876,24 +880,29 @@ function drawOutside(stroke, ui, canvas) {
876
880
  }
877
881
  }
878
882
 
879
- const {getSpread: getSpread, getOuterOf: getOuterOf, getByMove: getByMove, getIntersectData: getIntersectData} = core.BoundsHelper;
883
+ const {getSpread: getSpread, copyAndSpread: copyAndSpread, toOuterOf: toOuterOf, getOuterOf: getOuterOf, getByMove: getByMove, move: move$1, getIntersectData: getIntersectData} = core.BoundsHelper;
884
+
885
+ const tempBounds$1 = {};
880
886
 
881
887
  function shape(ui, current, options) {
882
888
  const canvas = current.getSameCanvas();
883
- const nowWorld = ui.__nowWorld, currentBounds = current.bounds;
884
- let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
889
+ const currentBounds = current.bounds, nowWorld = ui.__nowWorld, layout = ui.__layout;
890
+ const nowWorldShapeBounds = ui.__nowWorldShapeBounds || (ui.__nowWorldShapeBounds = {});
891
+ toOuterOf(layout.strokeSpread ? (copyAndSpread(tempBounds$1, layout.boxBounds, layout.strokeSpread),
892
+ tempBounds$1) : layout.boxBounds, nowWorld, nowWorldShapeBounds);
893
+ let bounds, renderBounds, matrix, fitMatrix, shapeBounds, worldCanvas;
885
894
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
886
- if (currentBounds.includes(nowWorld)) {
895
+ if (currentBounds.includes(nowWorldShapeBounds)) {
887
896
  worldCanvas = canvas;
888
- bounds = shapeBounds = nowWorld;
897
+ bounds = shapeBounds = nowWorldShapeBounds;
898
+ renderBounds = nowWorld;
889
899
  } else {
890
- const {renderShapeSpread: spread} = ui.__layout;
891
900
  let worldClipBounds;
892
901
  if (core.Platform.fullImageShadow) {
893
- worldClipBounds = nowWorld;
902
+ worldClipBounds = nowWorldShapeBounds;
894
903
  } else {
895
- const spreadBounds = spread ? getSpread(currentBounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : currentBounds;
896
- worldClipBounds = getIntersectData(spreadBounds, nowWorld);
904
+ const spreadBounds = layout.renderShapeSpread ? getSpread(currentBounds, core.FourNumberHelper.swapAndScale(layout.renderShapeSpread, scaleX, scaleY)) : currentBounds;
905
+ worldClipBounds = getIntersectData(spreadBounds, nowWorldShapeBounds);
897
906
  }
898
907
  fitMatrix = currentBounds.getFitMatrix(worldClipBounds);
899
908
  let {a: fitScaleX, d: fitScaleY} = fitMatrix;
@@ -903,8 +912,10 @@ function shape(ui, current, options) {
903
912
  scaleX *= fitScaleX;
904
913
  scaleY *= fitScaleY;
905
914
  }
906
- shapeBounds = getOuterOf(nowWorld, fitMatrix);
915
+ shapeBounds = getOuterOf(nowWorldShapeBounds, fitMatrix);
907
916
  bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
917
+ renderBounds = getOuterOf(nowWorld, fitMatrix);
918
+ move$1(renderBounds, -fitMatrix.e, -fitMatrix.f);
908
919
  const userMatrix = options.matrix;
909
920
  if (userMatrix) {
910
921
  matrix = new core.Matrix(fitMatrix);
@@ -923,6 +934,7 @@ function shape(ui, current, options) {
923
934
  matrix: matrix,
924
935
  fitMatrix: fitMatrix,
925
936
  bounds: bounds,
937
+ renderBounds: renderBounds,
926
938
  worldCanvas: worldCanvas,
927
939
  shapeBounds: shapeBounds,
928
940
  scaleX: scaleX,
@@ -1026,7 +1038,7 @@ const PaintModule = {
1026
1038
  shape: shape
1027
1039
  };
1028
1040
 
1029
- let origin = {}, tempMatrix = core.getMatrixData();
1041
+ let origin = {}, tempMatrix$1 = core.getMatrixData();
1030
1042
 
1031
1043
  const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = core.MatrixHelper;
1032
1044
 
@@ -1041,12 +1053,12 @@ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1041
1053
  data.transform = transform;
1042
1054
  }
1043
1055
 
1044
- function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
1056
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY) {
1045
1057
  const transform = get$3();
1046
1058
  layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1047
- if (clipSize) {
1048
- tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
1049
- multiplyParent(transform, tempMatrix);
1059
+ if (clipScaleX) {
1060
+ tempMatrix$1.a = clipScaleX, tempMatrix$1.d = clipScaleY;
1061
+ multiplyParent(transform, tempMatrix$1);
1050
1062
  }
1051
1063
  data.transform = transform;
1052
1064
  }
@@ -1147,7 +1159,12 @@ function getPatternData(paint, box, image) {
1147
1159
 
1148
1160
  case "normal":
1149
1161
  case "clip":
1150
- if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1162
+ if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) {
1163
+ let clipScaleX, clipScaleY;
1164
+ if (clipSize) clipScaleX = box.width / clipSize.width, clipScaleY = box.height / clipSize.height;
1165
+ clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, clipScaleX, clipScaleY);
1166
+ if (clipScaleX) scaleX = scaleX ? scaleX * clipScaleX : scaleX, scaleY = scaleY ? scaleY * clipScaleY : clipScaleY;
1167
+ }
1151
1168
  break;
1152
1169
 
1153
1170
  case "repeat":
@@ -1305,7 +1322,7 @@ function ignoreRender(ui, value) {
1305
1322
 
1306
1323
  const {get: get$1, scale: scale, copy: copy$1} = core.MatrixHelper;
1307
1324
 
1308
- const {floor: floor, ceil: ceil, max: max, abs: abs} = Math;
1325
+ const {floor: floor, ceil: ceil, max: max$1, abs: abs} = Math;
1309
1326
 
1310
1327
  function createPattern(ui, paint, pixelRatio) {
1311
1328
  let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
@@ -1354,8 +1371,8 @@ function createPattern(ui, paint, pixelRatio) {
1354
1371
  if (transform || scaleX !== 1 || scaleY !== 1) {
1355
1372
  const canvasWidth = width + (xGap || 0);
1356
1373
  const canvasHeight = height + (yGap || 0);
1357
- scaleX /= canvasWidth / max(floor(canvasWidth), 1);
1358
- scaleY /= canvasHeight / max(floor(canvasHeight), 1);
1374
+ scaleX /= canvasWidth / max$1(floor(canvasWidth), 1);
1375
+ scaleY /= canvasHeight / max$1(floor(canvasHeight), 1);
1359
1376
  if (!imageMatrix) {
1360
1377
  imageMatrix = get$1();
1361
1378
  if (transform) copy$1(imageMatrix, transform);
@@ -1381,17 +1398,15 @@ function checkImage(ui, canvas, paint, allowDraw) {
1381
1398
  if (allowDraw) {
1382
1399
  if (data.repeat) {
1383
1400
  allowDraw = false;
1384
- } else {
1385
- if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1386
- let {width: width, height: height} = data;
1387
- width *= scaleX * pixelRatio;
1388
- height *= scaleY * pixelRatio;
1389
- if (data.scaleX) {
1390
- width *= data.scaleX;
1391
- height *= data.scaleY;
1392
- }
1393
- allowDraw = width * height > core.Platform.image.maxCacheSize;
1401
+ } else if (!(paint.changeful || core.Platform.name === "miniapp" && core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
1402
+ let {width: width, height: height} = data;
1403
+ width *= scaleX * pixelRatio;
1404
+ height *= scaleY * pixelRatio;
1405
+ if (data.scaleX) {
1406
+ width *= data.scaleX;
1407
+ height *= data.scaleY;
1394
1408
  }
1409
+ allowDraw = width * height > core.Platform.image.maxCacheSize;
1395
1410
  }
1396
1411
  }
1397
1412
  if (allowDraw) {
@@ -1571,20 +1586,20 @@ const PaintGradientModule = {
1571
1586
  getTransform: getTransform
1572
1587
  };
1573
1588
 
1574
- const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = core.BoundsHelper;
1589
+ const {copy: copy, move: move, toOffsetOutBounds: toOffsetOutBounds$1} = core.BoundsHelper, {max: max} = Math;
1575
1590
 
1576
- const tempBounds = {};
1591
+ const tempBounds = {}, tempMatrix = new core.Matrix;
1577
1592
 
1578
1593
  const offsetOutBounds$1 = {};
1579
1594
 
1580
1595
  function shadow(ui, current, shape) {
1581
- let copyBounds, spreadScale;
1582
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
1596
+ let copyBounds, transform;
1597
+ const {__nowWorld: nowWorld} = ui;
1583
1598
  const {shadow: shadow} = ui.__;
1584
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1599
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1585
1600
  const other = current.getSameCanvas();
1586
1601
  const end = shadow.length - 1;
1587
- toOffsetOutBounds$1(bounds, offsetOutBounds$1);
1602
+ toOffsetOutBounds$1(bounds, offsetOutBounds$1, renderBounds);
1588
1603
  shadow.forEach((item, index) => {
1589
1604
  let otherScale = 1;
1590
1605
  if (item.scaleFixed) {
@@ -1592,54 +1607,61 @@ function shadow(ui, current, shape) {
1592
1607
  if (sx > 1) otherScale = 1 / sx;
1593
1608
  }
1594
1609
  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));
1595
- spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1596
- drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
1597
- copyBounds = bounds;
1610
+ transform = getShadowTransform(ui, other, shape, item, offsetOutBounds$1, otherScale);
1611
+ if (transform) other.setTransform(transform);
1612
+ drawWorldShadow(other, offsetOutBounds$1, shape);
1613
+ if (transform) other.resetTransform();
1614
+ copyBounds = renderBounds;
1598
1615
  if (item.box) {
1599
1616
  other.restore();
1600
1617
  other.save();
1601
1618
  if (worldCanvas) {
1602
- other.copyWorld(other, bounds, nowWorld, "copy");
1619
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
1603
1620
  copyBounds = nowWorld;
1604
1621
  }
1605
1622
  worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
1606
1623
  }
1607
- if (draw.Effect.isTransformShadow(item)) draw.Effect.renderTransformShadow(ui, current, other, copyBounds, item); else core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1624
+ core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1608
1625
  if (end && index < end) other.clearWorld(copyBounds);
1609
1626
  });
1610
1627
  other.recycle(copyBounds);
1611
1628
  }
1612
1629
 
1613
- function getShadowSpread(_ui, shadow) {
1614
- let width = 0;
1615
- 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));
1616
- return width;
1630
+ function getShadowRenderSpread(_ui, shadow) {
1631
+ let top = 0, right = 0, bottom = 0, left = 0, x, y, spread, blur;
1632
+ shadow.forEach(item => {
1633
+ x = item.x || 0, y = item.y || 0, spread = item.spread || 0, blur = (item.blur || 0) * 1.5;
1634
+ top = max(top, spread + blur - y);
1635
+ right = max(right, spread + blur + x);
1636
+ bottom = max(bottom, spread + blur + y);
1637
+ left = max(left, spread + blur - x);
1638
+ });
1639
+ return top === right && right === bottom && bottom === left ? top : [ top, right, bottom, left ];
1617
1640
  }
1618
1641
 
1619
- function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1620
- const {bounds: bounds, shapeBounds: shapeBounds} = shape;
1642
+ function getShadowTransform(ui, canvas, _shape, shadow, outBounds, otherScale, isInnerShaodw) {
1643
+ if (shadow.spread) {
1644
+ const spreadScale = 1 + shadow.spread * 2 / ui.__layout.strokeBounds.width * otherScale * (isInnerShaodw ? -1 : 1);
1645
+ tempMatrix.set().scaleOfOuter({
1646
+ x: (outBounds.x + outBounds.width / 2) * canvas.pixelRatio,
1647
+ y: (outBounds.y + outBounds.height / 2) * canvas.pixelRatio
1648
+ }, spreadScale);
1649
+ return tempMatrix;
1650
+ }
1651
+ return undefined;
1652
+ }
1653
+
1654
+ function drawWorldShadow(canvas, outBounds, shape) {
1655
+ const {shapeBounds: shapeBounds} = shape;
1656
+ let from, to;
1621
1657
  if (core.Platform.fullImageShadow) {
1622
1658
  copy(tempBounds, canvas.bounds);
1623
- tempBounds.x += outBounds.x - shapeBounds.x;
1624
- tempBounds.y += outBounds.y - shapeBounds.y;
1625
- if (spreadScale) {
1626
- const {fitMatrix: fitMatrix} = shape;
1627
- tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1628
- tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1629
- tempBounds.width *= spreadScale;
1630
- tempBounds.height *= spreadScale;
1631
- }
1632
- canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
1659
+ move(tempBounds, outBounds.x - shapeBounds.x, outBounds.y - shapeBounds.y);
1660
+ from = canvas.bounds, to = tempBounds;
1633
1661
  } else {
1634
- if (spreadScale) {
1635
- copy(tempBounds, outBounds);
1636
- tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
1637
- tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
1638
- tempBounds.width *= spreadScale;
1639
- tempBounds.height *= spreadScale;
1640
- }
1641
- canvas.copyWorld(shape.canvas, shapeBounds, spreadScale ? tempBounds : outBounds);
1662
+ from = shapeBounds, to = outBounds;
1642
1663
  }
1664
+ canvas.copyWorld(shape.canvas, from, to);
1643
1665
  }
1644
1666
 
1645
1667
  const {toOffsetOutBounds: toOffsetOutBounds} = core.BoundsHelper;
@@ -1647,13 +1669,13 @@ const {toOffsetOutBounds: toOffsetOutBounds} = core.BoundsHelper;
1647
1669
  const offsetOutBounds = {};
1648
1670
 
1649
1671
  function innerShadow(ui, current, shape) {
1650
- let copyBounds, spreadScale;
1651
- const {__nowWorld: nowWorld, __layout: __layout} = ui;
1672
+ let copyBounds, transform;
1673
+ const {__nowWorld: nowWorld} = ui;
1652
1674
  const {innerShadow: innerShadow} = ui.__;
1653
- const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1675
+ const {worldCanvas: worldCanvas, bounds: bounds, renderBounds: renderBounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1654
1676
  const other = current.getSameCanvas();
1655
1677
  const end = innerShadow.length - 1;
1656
- toOffsetOutBounds(bounds, offsetOutBounds);
1678
+ toOffsetOutBounds(bounds, offsetOutBounds, renderBounds);
1657
1679
  innerShadow.forEach((item, index) => {
1658
1680
  let otherScale = 1;
1659
1681
  if (item.scaleFixed) {
@@ -1662,16 +1684,17 @@ function innerShadow(ui, current, shape) {
1662
1684
  }
1663
1685
  other.save();
1664
1686
  other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
1665
- spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1666
- drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1687
+ transform = getShadowTransform(ui, other, shape, item, offsetOutBounds, otherScale, true);
1688
+ if (transform) other.setTransform(transform);
1689
+ drawWorldShadow(other, offsetOutBounds, shape);
1667
1690
  other.restore();
1668
1691
  if (worldCanvas) {
1669
- other.copyWorld(other, bounds, nowWorld, "copy");
1692
+ other.copyWorld(other, renderBounds, nowWorld, "copy");
1670
1693
  other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
1671
1694
  copyBounds = nowWorld;
1672
1695
  } else {
1673
1696
  other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
1674
- copyBounds = bounds;
1697
+ copyBounds = renderBounds;
1675
1698
  }
1676
1699
  other.fillWorld(copyBounds, draw.ColorConvert.string(item.color), "source-in");
1677
1700
  core.LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
@@ -1680,6 +1703,8 @@ function innerShadow(ui, current, shape) {
1680
1703
  other.recycle(copyBounds);
1681
1704
  }
1682
1705
 
1706
+ const getInnerShadowSpread = getShadowRenderSpread;
1707
+
1683
1708
  function blur(ui, current, origin) {
1684
1709
  const {blur: blur} = ui.__;
1685
1710
  origin.setWorldBlur(blur * ui.__nowWorld.a);
@@ -1694,10 +1719,12 @@ const EffectModule = {
1694
1719
  innerShadow: innerShadow,
1695
1720
  blur: blur,
1696
1721
  backgroundBlur: backgroundBlur,
1697
- getShadowSpread: getShadowSpread,
1722
+ getShadowRenderSpread: getShadowRenderSpread,
1723
+ getShadowTransform: getShadowTransform,
1698
1724
  isTransformShadow(_shadow) {
1699
1725
  return undefined;
1700
- }
1726
+ },
1727
+ getInnerShadowSpread: getInnerShadowSpread
1701
1728
  };
1702
1729
 
1703
1730
  const {excludeRenderBounds: excludeRenderBounds} = core.LeafBoundsHelper;
@@ -1714,6 +1741,7 @@ draw.Group.prototype.__renderMask = function(canvas, options) {
1714
1741
  maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1715
1742
  maskCanvas = contentCanvas = null;
1716
1743
  }
1744
+ if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1717
1745
  maskOpacity = child.__.opacity;
1718
1746
  usedGrayscaleAlpha = false;
1719
1747
  if (mask === "path" || mask === "clipping-path") {
@@ -1731,7 +1759,6 @@ draw.Group.prototype.__renderMask = function(canvas, options) {
1731
1759
  if (!contentCanvas) contentCanvas = getCanvas(canvas);
1732
1760
  child.__render(maskCanvas, options);
1733
1761
  }
1734
- if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1735
1762
  continue;
1736
1763
  }
1737
1764
  const childBlendMode = maskOpacity === 1 && child.__.__blendMode;