@effing/canvas 0.21.0 → 0.22.0
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/index.js +403 -112
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -880,37 +880,133 @@ function drawBorders(ctx, x, y, width, height, style, borderRadius) {
|
|
|
880
880
|
}
|
|
881
881
|
return;
|
|
882
882
|
}
|
|
883
|
-
if (
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
883
|
+
if (hasRoundedCorners) {
|
|
884
|
+
const maxR = Math.min(width, height) / 2;
|
|
885
|
+
const tl = Math.min(borderRadius.topLeft, maxR);
|
|
886
|
+
const tr = Math.min(borderRadius.topRight, maxR);
|
|
887
|
+
const br = Math.min(borderRadius.bottomRight, maxR);
|
|
888
|
+
const bl = Math.min(borderRadius.bottomLeft, maxR);
|
|
889
|
+
const top = y + tw / 2;
|
|
890
|
+
const right = x + width - rw / 2;
|
|
891
|
+
const bottom = y + height - bw / 2;
|
|
892
|
+
const left = x + lw / 2;
|
|
893
|
+
const eTL = Math.max(0, tl - Math.max(tw, lw) / 2);
|
|
894
|
+
const eTR = Math.max(0, tr - Math.max(tw, rw) / 2);
|
|
895
|
+
const eBR = Math.max(0, br - Math.max(bw, rw) / 2);
|
|
896
|
+
const eBL = Math.max(0, bl - Math.max(bw, lw) / 2);
|
|
897
|
+
if (tw > 0) {
|
|
898
|
+
ctx.strokeStyle = tc;
|
|
899
|
+
ctx.lineWidth = tw;
|
|
900
|
+
ctx.beginPath();
|
|
901
|
+
if (eTL > 0 && lw === 0) {
|
|
902
|
+
ctx.moveTo(left, top + eTL);
|
|
903
|
+
ctx.arcTo(left, top, left + eTL, top, eTL);
|
|
904
|
+
} else if (eTL > 0) {
|
|
905
|
+
ctx.moveTo(left + eTL, top);
|
|
906
|
+
} else {
|
|
907
|
+
ctx.moveTo(x, top);
|
|
908
|
+
}
|
|
909
|
+
if (eTR > 0) {
|
|
910
|
+
ctx.lineTo(right - eTR, top);
|
|
911
|
+
ctx.arcTo(right, top, right, top + eTR, eTR);
|
|
912
|
+
} else {
|
|
913
|
+
ctx.lineTo(x + width, top);
|
|
914
|
+
}
|
|
915
|
+
ctx.stroke();
|
|
916
|
+
}
|
|
917
|
+
if (rw > 0) {
|
|
918
|
+
ctx.strokeStyle = rc;
|
|
919
|
+
ctx.lineWidth = rw;
|
|
920
|
+
ctx.beginPath();
|
|
921
|
+
if (eTR > 0 && tw === 0) {
|
|
922
|
+
ctx.moveTo(right - eTR, top);
|
|
923
|
+
ctx.arcTo(right, top, right, top + eTR, eTR);
|
|
924
|
+
} else if (eTR > 0) {
|
|
925
|
+
ctx.moveTo(right, top + eTR);
|
|
926
|
+
} else {
|
|
927
|
+
ctx.moveTo(right, y);
|
|
928
|
+
}
|
|
929
|
+
if (eBR > 0) {
|
|
930
|
+
ctx.lineTo(right, bottom - eBR);
|
|
931
|
+
ctx.arcTo(right, bottom, right - eBR, bottom, eBR);
|
|
932
|
+
} else {
|
|
933
|
+
ctx.lineTo(right, y + height);
|
|
934
|
+
}
|
|
935
|
+
ctx.stroke();
|
|
936
|
+
}
|
|
937
|
+
if (bw > 0) {
|
|
938
|
+
ctx.strokeStyle = bc;
|
|
939
|
+
ctx.lineWidth = bw;
|
|
940
|
+
ctx.beginPath();
|
|
941
|
+
if (eBR > 0 && rw === 0) {
|
|
942
|
+
ctx.moveTo(right, bottom - eBR);
|
|
943
|
+
ctx.arcTo(right, bottom, right - eBR, bottom, eBR);
|
|
944
|
+
} else if (eBR > 0) {
|
|
945
|
+
ctx.moveTo(right - eBR, bottom);
|
|
946
|
+
} else {
|
|
947
|
+
ctx.moveTo(x + width, bottom);
|
|
948
|
+
}
|
|
949
|
+
if (eBL > 0) {
|
|
950
|
+
ctx.lineTo(left + eBL, bottom);
|
|
951
|
+
ctx.arcTo(left, bottom, left, bottom - eBL, eBL);
|
|
952
|
+
} else {
|
|
953
|
+
ctx.lineTo(x, bottom);
|
|
954
|
+
}
|
|
955
|
+
ctx.stroke();
|
|
956
|
+
}
|
|
957
|
+
if (lw > 0) {
|
|
958
|
+
ctx.strokeStyle = lc;
|
|
959
|
+
ctx.lineWidth = lw;
|
|
960
|
+
ctx.beginPath();
|
|
961
|
+
if (eBL > 0 && bw === 0) {
|
|
962
|
+
ctx.moveTo(left + eBL, bottom);
|
|
963
|
+
ctx.arcTo(left, bottom, left, bottom - eBL, eBL);
|
|
964
|
+
} else if (eBL > 0) {
|
|
965
|
+
ctx.moveTo(left, bottom - eBL);
|
|
966
|
+
} else {
|
|
967
|
+
ctx.moveTo(left, y + height);
|
|
968
|
+
}
|
|
969
|
+
if (eTL > 0) {
|
|
970
|
+
ctx.lineTo(left, top + eTL);
|
|
971
|
+
ctx.arcTo(left, top, left + eTL, top, eTL);
|
|
972
|
+
} else {
|
|
973
|
+
ctx.lineTo(left, y);
|
|
974
|
+
}
|
|
975
|
+
ctx.stroke();
|
|
976
|
+
}
|
|
977
|
+
} else {
|
|
978
|
+
if (tw > 0) {
|
|
979
|
+
ctx.strokeStyle = tc;
|
|
980
|
+
ctx.lineWidth = tw;
|
|
981
|
+
ctx.beginPath();
|
|
982
|
+
ctx.moveTo(x, y + tw / 2);
|
|
983
|
+
ctx.lineTo(x + width, y + tw / 2);
|
|
984
|
+
ctx.stroke();
|
|
985
|
+
}
|
|
986
|
+
if (rw > 0) {
|
|
987
|
+
ctx.strokeStyle = rc;
|
|
988
|
+
ctx.lineWidth = rw;
|
|
989
|
+
ctx.beginPath();
|
|
990
|
+
ctx.moveTo(x + width - rw / 2, y);
|
|
991
|
+
ctx.lineTo(x + width - rw / 2, y + height);
|
|
992
|
+
ctx.stroke();
|
|
993
|
+
}
|
|
994
|
+
if (bw > 0) {
|
|
995
|
+
ctx.strokeStyle = bc;
|
|
996
|
+
ctx.lineWidth = bw;
|
|
997
|
+
ctx.beginPath();
|
|
998
|
+
ctx.moveTo(x, y + height - bw / 2);
|
|
999
|
+
ctx.lineTo(x + width, y + height - bw / 2);
|
|
1000
|
+
ctx.stroke();
|
|
1001
|
+
}
|
|
1002
|
+
if (lw > 0) {
|
|
1003
|
+
ctx.strokeStyle = lc;
|
|
1004
|
+
ctx.lineWidth = lw;
|
|
1005
|
+
ctx.beginPath();
|
|
1006
|
+
ctx.moveTo(x + lw / 2, y);
|
|
1007
|
+
ctx.lineTo(x + lw / 2, y + height);
|
|
1008
|
+
ctx.stroke();
|
|
1009
|
+
}
|
|
914
1010
|
}
|
|
915
1011
|
}
|
|
916
1012
|
function drawBoxShadow(ctx, x, y, width, height, boxShadow, borderRadius) {
|
|
@@ -958,18 +1054,24 @@ function collectDefs(children) {
|
|
|
958
1054
|
const clips = /* @__PURE__ */ new Map();
|
|
959
1055
|
const gradients = /* @__PURE__ */ new Map();
|
|
960
1056
|
const masks = /* @__PURE__ */ new Map();
|
|
1057
|
+
const filters = /* @__PURE__ */ new Map();
|
|
1058
|
+
function insertDef(def) {
|
|
1059
|
+
const id = def.props.id;
|
|
1060
|
+
if (!id) return;
|
|
1061
|
+
if (def.type === "clipPath") clips.set(id, normalizeChildren(def));
|
|
1062
|
+
else if (def.type === "mask") masks.set(id, normalizeChildren(def));
|
|
1063
|
+
else if (def.type === "filter") filters.set(id, def);
|
|
1064
|
+
else if (def.type === "radialGradient" || def.type === "linearGradient")
|
|
1065
|
+
gradients.set(id, def);
|
|
1066
|
+
}
|
|
961
1067
|
for (const child of children) {
|
|
962
|
-
if (child.type
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
if (def.type === "clipPath") clips.set(id, normalizeChildren(def));
|
|
967
|
-
else if (def.type === "mask") masks.set(id, normalizeChildren(def));
|
|
968
|
-
else if (def.type === "radialGradient" || def.type === "linearGradient")
|
|
969
|
-
gradients.set(id, def);
|
|
1068
|
+
if (child.type === "defs") {
|
|
1069
|
+
for (const def of normalizeChildren(child)) insertDef(def);
|
|
1070
|
+
} else {
|
|
1071
|
+
insertDef(child);
|
|
970
1072
|
}
|
|
971
1073
|
}
|
|
972
|
-
return { clips, gradients, masks };
|
|
1074
|
+
return { clips, gradients, masks, filters };
|
|
973
1075
|
}
|
|
974
1076
|
function parseUrlRef(value) {
|
|
975
1077
|
if (typeof value !== "string") return void 0;
|
|
@@ -1353,21 +1455,177 @@ function drawSvgContainer(ctx, node, x, y, width, height) {
|
|
|
1353
1455
|
var EMPTY_DEFS = {
|
|
1354
1456
|
clips: /* @__PURE__ */ new Map(),
|
|
1355
1457
|
gradients: /* @__PURE__ */ new Map(),
|
|
1356
|
-
masks: /* @__PURE__ */ new Map()
|
|
1458
|
+
masks: /* @__PURE__ */ new Map(),
|
|
1459
|
+
filters: /* @__PURE__ */ new Map()
|
|
1357
1460
|
};
|
|
1461
|
+
function applyFeOffset(input, dx, dy, w, h) {
|
|
1462
|
+
const [canvas, ctx] = acquireOffscreen(w, h);
|
|
1463
|
+
ctx.drawImage(input, dx, dy);
|
|
1464
|
+
return canvas;
|
|
1465
|
+
}
|
|
1466
|
+
function applyFeGaussianBlur(input, stdDeviation, w, h) {
|
|
1467
|
+
const [canvas, ctx] = acquireOffscreen(w, h);
|
|
1468
|
+
ctx.filter = `blur(${stdDeviation}px)`;
|
|
1469
|
+
ctx.drawImage(input, 0, 0);
|
|
1470
|
+
ctx.filter = "none";
|
|
1471
|
+
return canvas;
|
|
1472
|
+
}
|
|
1473
|
+
function applyFeColorMatrix(input, type, values, w, h) {
|
|
1474
|
+
const [canvas, ctx] = acquireOffscreen(w, h);
|
|
1475
|
+
ctx.drawImage(input, 0, 0);
|
|
1476
|
+
if (type === "matrix" && values) {
|
|
1477
|
+
const m = values.trim().split(/[\s,]+/).map(Number);
|
|
1478
|
+
if (m.length >= 20) {
|
|
1479
|
+
const imageData = ctx.getImageData(0, 0, w, h);
|
|
1480
|
+
const d = imageData.data;
|
|
1481
|
+
for (let i = 0; i < d.length; i += 4) {
|
|
1482
|
+
const r = d[i];
|
|
1483
|
+
const g = d[i + 1];
|
|
1484
|
+
const b = d[i + 2];
|
|
1485
|
+
const a = d[i + 3];
|
|
1486
|
+
d[i] = Math.min(
|
|
1487
|
+
255,
|
|
1488
|
+
Math.max(
|
|
1489
|
+
0,
|
|
1490
|
+
m[0] * r + m[1] * g + m[2] * b + m[3] * a + m[4] * 255
|
|
1491
|
+
)
|
|
1492
|
+
);
|
|
1493
|
+
d[i + 1] = Math.min(
|
|
1494
|
+
255,
|
|
1495
|
+
Math.max(
|
|
1496
|
+
0,
|
|
1497
|
+
m[5] * r + m[6] * g + m[7] * b + m[8] * a + m[9] * 255
|
|
1498
|
+
)
|
|
1499
|
+
);
|
|
1500
|
+
d[i + 2] = Math.min(
|
|
1501
|
+
255,
|
|
1502
|
+
Math.max(
|
|
1503
|
+
0,
|
|
1504
|
+
m[10] * r + m[11] * g + m[12] * b + m[13] * a + m[14] * 255
|
|
1505
|
+
)
|
|
1506
|
+
);
|
|
1507
|
+
d[i + 3] = Math.min(
|
|
1508
|
+
255,
|
|
1509
|
+
Math.max(
|
|
1510
|
+
0,
|
|
1511
|
+
m[15] * r + m[16] * g + m[17] * b + m[18] * a + m[19] * 255
|
|
1512
|
+
)
|
|
1513
|
+
);
|
|
1514
|
+
}
|
|
1515
|
+
ctx.putImageData(imageData, 0, 0);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
return canvas;
|
|
1519
|
+
}
|
|
1520
|
+
function applyFeBlend(in1, in2, mode, w, h) {
|
|
1521
|
+
const modeMap = {
|
|
1522
|
+
normal: "source-over",
|
|
1523
|
+
multiply: "multiply",
|
|
1524
|
+
screen: "screen",
|
|
1525
|
+
darken: "darken",
|
|
1526
|
+
lighten: "lighten",
|
|
1527
|
+
overlay: "overlay"
|
|
1528
|
+
};
|
|
1529
|
+
const [canvas, ctx] = acquireOffscreen(w, h);
|
|
1530
|
+
ctx.drawImage(in2, 0, 0);
|
|
1531
|
+
ctx.globalCompositeOperation = modeMap[mode] ?? "source-over";
|
|
1532
|
+
ctx.drawImage(in1, 0, 0);
|
|
1533
|
+
ctx.globalCompositeOperation = "source-over";
|
|
1534
|
+
return canvas;
|
|
1535
|
+
}
|
|
1536
|
+
function extractSourceAlpha(input, w, h) {
|
|
1537
|
+
const [canvas, ctx] = acquireOffscreen(w, h);
|
|
1538
|
+
ctx.fillStyle = "black";
|
|
1539
|
+
ctx.fillRect(0, 0, w, h);
|
|
1540
|
+
ctx.globalCompositeOperation = "destination-in";
|
|
1541
|
+
ctx.drawImage(input, 0, 0);
|
|
1542
|
+
ctx.globalCompositeOperation = "source-over";
|
|
1543
|
+
return canvas;
|
|
1544
|
+
}
|
|
1545
|
+
function applyFilter(filterDef, sourceGraphic, w, h) {
|
|
1546
|
+
const buffers = /* @__PURE__ */ new Map();
|
|
1547
|
+
buffers.set("SourceGraphic", sourceGraphic);
|
|
1548
|
+
let sourceAlpha;
|
|
1549
|
+
const getSourceAlpha = () => {
|
|
1550
|
+
if (!sourceAlpha) {
|
|
1551
|
+
sourceAlpha = extractSourceAlpha(sourceGraphic, w, h);
|
|
1552
|
+
buffers.set("SourceAlpha", sourceAlpha);
|
|
1553
|
+
}
|
|
1554
|
+
return sourceAlpha;
|
|
1555
|
+
};
|
|
1556
|
+
const children = normalizeChildren(filterDef);
|
|
1557
|
+
let lastResult = sourceGraphic;
|
|
1558
|
+
for (const prim of children) {
|
|
1559
|
+
const p = prim.props;
|
|
1560
|
+
const inName = p.in ?? "";
|
|
1561
|
+
const resolve = (name) => {
|
|
1562
|
+
if (name === "SourceAlpha") return getSourceAlpha();
|
|
1563
|
+
return buffers.get(name) ?? lastResult;
|
|
1564
|
+
};
|
|
1565
|
+
const input = inName ? resolve(inName) : lastResult;
|
|
1566
|
+
let output;
|
|
1567
|
+
switch (prim.type) {
|
|
1568
|
+
case "feOffset":
|
|
1569
|
+
output = applyFeOffset(
|
|
1570
|
+
input,
|
|
1571
|
+
Number(p.dx ?? 0),
|
|
1572
|
+
Number(p.dy ?? 0),
|
|
1573
|
+
w,
|
|
1574
|
+
h
|
|
1575
|
+
);
|
|
1576
|
+
break;
|
|
1577
|
+
case "feGaussianBlur": {
|
|
1578
|
+
const std = Number(p.stdDeviation ?? 0);
|
|
1579
|
+
output = std > 0 ? applyFeGaussianBlur(input, std, w, h) : input;
|
|
1580
|
+
break;
|
|
1581
|
+
}
|
|
1582
|
+
case "feColorMatrix":
|
|
1583
|
+
output = applyFeColorMatrix(
|
|
1584
|
+
input,
|
|
1585
|
+
p.type ?? "matrix",
|
|
1586
|
+
p.values,
|
|
1587
|
+
w,
|
|
1588
|
+
h
|
|
1589
|
+
);
|
|
1590
|
+
break;
|
|
1591
|
+
case "feBlend": {
|
|
1592
|
+
const in2Name = p.in2 ?? "";
|
|
1593
|
+
const in2 = in2Name ? resolve(in2Name) : lastResult;
|
|
1594
|
+
output = applyFeBlend(input, in2, p.mode ?? "normal", w, h);
|
|
1595
|
+
break;
|
|
1596
|
+
}
|
|
1597
|
+
default:
|
|
1598
|
+
output = input;
|
|
1599
|
+
break;
|
|
1600
|
+
}
|
|
1601
|
+
const resultName = p.result;
|
|
1602
|
+
if (resultName) buffers.set(resultName, output);
|
|
1603
|
+
lastResult = output;
|
|
1604
|
+
}
|
|
1605
|
+
return lastResult;
|
|
1606
|
+
}
|
|
1358
1607
|
function drawSvgChild(ctx, child, inheritedFill, color, defs = EMPTY_DEFS, vbW = 0, vbH = 0) {
|
|
1359
1608
|
const { type } = child;
|
|
1360
1609
|
const props = mergeStyleIntoProps(child.props);
|
|
1361
|
-
if (type === "defs" || type === "clipPath" || type === "mask")
|
|
1610
|
+
if (type === "defs" || type === "clipPath" || type === "mask" || type === "filter")
|
|
1611
|
+
return;
|
|
1612
|
+
const transform = type !== "g" ? props.transform : void 0;
|
|
1613
|
+
if (transform) {
|
|
1614
|
+
ctx.save();
|
|
1615
|
+
applySvgTransform(ctx, transform);
|
|
1616
|
+
}
|
|
1362
1617
|
const clipRef = parseUrlRef(props.clipPath ?? props["clip-path"]);
|
|
1363
1618
|
const clipShapes = clipRef ? defs.clips.get(clipRef) : void 0;
|
|
1364
1619
|
const clipPath = clipShapes ? buildClipPath(clipShapes, vbW, vbH) : void 0;
|
|
1365
1620
|
const maskRef = parseUrlRef(props.mask);
|
|
1366
1621
|
const maskShapes = maskRef ? defs.masks.get(maskRef) : void 0;
|
|
1622
|
+
const filterRef = parseUrlRef(props.filter);
|
|
1623
|
+
const filterDef = filterRef ? defs.filters.get(filterRef) : void 0;
|
|
1367
1624
|
if (clipPath) ctx.save();
|
|
1368
1625
|
if (clipPath) ctx.clip(clipPath);
|
|
1626
|
+
const needsOffscreen = maskShapes || filterDef;
|
|
1369
1627
|
let elemCanvas;
|
|
1370
|
-
const targetCtx =
|
|
1628
|
+
const targetCtx = needsOffscreen ? (() => {
|
|
1371
1629
|
const [c, cCtx] = acquireOffscreen(Math.ceil(vbW), Math.ceil(vbH));
|
|
1372
1630
|
elemCanvas = c;
|
|
1373
1631
|
return cCtx;
|
|
@@ -1398,22 +1656,36 @@ function drawSvgChild(ctx, child, inheritedFill, color, defs = EMPTY_DEFS, vbW =
|
|
|
1398
1656
|
drawGroup(targetCtx, child, inheritedFill, color, defs, vbW, vbH);
|
|
1399
1657
|
break;
|
|
1400
1658
|
}
|
|
1401
|
-
if (
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1659
|
+
if (needsOffscreen && elemCanvas) {
|
|
1660
|
+
if (maskShapes) {
|
|
1661
|
+
const [maskCanvas, maskCtx] = acquireOffscreen(
|
|
1662
|
+
Math.ceil(vbW),
|
|
1663
|
+
Math.ceil(vbH)
|
|
1664
|
+
);
|
|
1665
|
+
for (const shape of maskShapes) {
|
|
1666
|
+
drawSvgChild(maskCtx, shape, "white", "white", defs, vbW, vbH);
|
|
1667
|
+
}
|
|
1668
|
+
targetCtx.globalCompositeOperation = "destination-in";
|
|
1669
|
+
targetCtx.drawImage(maskCanvas, 0, 0);
|
|
1670
|
+
targetCtx.globalCompositeOperation = "source-over";
|
|
1671
|
+
releaseOffscreen(maskCanvas);
|
|
1672
|
+
}
|
|
1673
|
+
if (filterDef) {
|
|
1674
|
+
const filteredCanvas = applyFilter(
|
|
1675
|
+
filterDef,
|
|
1676
|
+
elemCanvas,
|
|
1677
|
+
Math.ceil(vbW),
|
|
1678
|
+
Math.ceil(vbH)
|
|
1679
|
+
);
|
|
1680
|
+
ctx.drawImage(filteredCanvas, 0, 0);
|
|
1681
|
+
if (filteredCanvas !== elemCanvas) releaseOffscreen(filteredCanvas);
|
|
1682
|
+
} else {
|
|
1683
|
+
ctx.drawImage(elemCanvas, 0, 0);
|
|
1684
|
+
}
|
|
1414
1685
|
releaseOffscreen(elemCanvas);
|
|
1415
1686
|
}
|
|
1416
1687
|
if (clipPath) ctx.restore();
|
|
1688
|
+
if (transform) ctx.restore();
|
|
1417
1689
|
}
|
|
1418
1690
|
function drawPath(ctx, props, inheritedFill, color, defs) {
|
|
1419
1691
|
const d = props.d;
|
|
@@ -1600,14 +1872,34 @@ function parsePoints(value) {
|
|
|
1600
1872
|
function applyFillAndStroke(ctx, props, path, inheritedFill, color, defs, bbox) {
|
|
1601
1873
|
const fill = resolveCurrentColor(props.fill, color) ?? inheritedFill;
|
|
1602
1874
|
const fillRule = props.fillRule ?? props["fill-rule"];
|
|
1875
|
+
const fillOpacity = Number(props.fillOpacity ?? props["fill-opacity"] ?? 1);
|
|
1603
1876
|
const fillRef = parseUrlRef(fill);
|
|
1604
1877
|
if (fillRef) {
|
|
1605
1878
|
const gradientDef = defs.gradients.get(fillRef);
|
|
1606
1879
|
if (gradientDef) {
|
|
1607
|
-
|
|
1880
|
+
if (fillOpacity < 1) {
|
|
1881
|
+
ctx.save();
|
|
1882
|
+
ctx.globalAlpha *= fillOpacity;
|
|
1883
|
+
fillWithSvgGradient(
|
|
1884
|
+
ctx,
|
|
1885
|
+
gradientDef,
|
|
1886
|
+
bbox,
|
|
1887
|
+
path,
|
|
1888
|
+
fillRule ?? "nonzero"
|
|
1889
|
+
);
|
|
1890
|
+
ctx.restore();
|
|
1891
|
+
} else {
|
|
1892
|
+
fillWithSvgGradient(
|
|
1893
|
+
ctx,
|
|
1894
|
+
gradientDef,
|
|
1895
|
+
bbox,
|
|
1896
|
+
path,
|
|
1897
|
+
fillRule ?? "nonzero"
|
|
1898
|
+
);
|
|
1899
|
+
}
|
|
1608
1900
|
}
|
|
1609
1901
|
} else if (fill !== "none") {
|
|
1610
|
-
ctx.fillStyle = fill;
|
|
1902
|
+
ctx.fillStyle = applyOpacity(fill, fillOpacity);
|
|
1611
1903
|
ctx.fill(path, fillRule ?? "nonzero");
|
|
1612
1904
|
}
|
|
1613
1905
|
applyStroke(ctx, props, path, color, defs, bbox);
|
|
@@ -1615,6 +1907,9 @@ function applyFillAndStroke(ctx, props, path, inheritedFill, color, defs, bbox)
|
|
|
1615
1907
|
function applyStroke(ctx, props, path, color, defs, bbox) {
|
|
1616
1908
|
const stroke = resolveCurrentColor(props.stroke, color);
|
|
1617
1909
|
if (!stroke || stroke === "none") return;
|
|
1910
|
+
const strokeOpacity = Number(
|
|
1911
|
+
props.strokeOpacity ?? props["stroke-opacity"] ?? 1
|
|
1912
|
+
);
|
|
1618
1913
|
ctx.lineWidth = Number(props.strokeWidth ?? props["stroke-width"] ?? 1);
|
|
1619
1914
|
ctx.lineCap = props.strokeLinecap ?? props["stroke-linecap"] ?? "butt";
|
|
1620
1915
|
ctx.lineJoin = props.strokeLinejoin ?? props["stroke-linejoin"] ?? "miter";
|
|
@@ -1622,11 +1917,18 @@ function applyStroke(ctx, props, path, color, defs, bbox) {
|
|
|
1622
1917
|
if (strokeRef) {
|
|
1623
1918
|
const gradientDef = defs.gradients.get(strokeRef);
|
|
1624
1919
|
if (gradientDef) {
|
|
1625
|
-
|
|
1920
|
+
if (strokeOpacity < 1) {
|
|
1921
|
+
ctx.save();
|
|
1922
|
+
ctx.globalAlpha *= strokeOpacity;
|
|
1923
|
+
strokeWithSvgGradient(ctx, gradientDef, bbox, path);
|
|
1924
|
+
ctx.restore();
|
|
1925
|
+
} else {
|
|
1926
|
+
strokeWithSvgGradient(ctx, gradientDef, bbox, path);
|
|
1927
|
+
}
|
|
1626
1928
|
return;
|
|
1627
1929
|
}
|
|
1628
1930
|
}
|
|
1629
|
-
ctx.strokeStyle = stroke;
|
|
1931
|
+
ctx.strokeStyle = applyOpacity(stroke, strokeOpacity);
|
|
1630
1932
|
ctx.stroke(path);
|
|
1631
1933
|
}
|
|
1632
1934
|
|
|
@@ -2081,10 +2383,14 @@ async function drawNodeCore(ctx, node, parentX, parentY, offsetX, offsetY, debug
|
|
|
2081
2383
|
const paddingLeft = resolveBoxValue(style.paddingLeft, width);
|
|
2082
2384
|
const paddingRight = resolveBoxValue(style.paddingRight, width);
|
|
2083
2385
|
const paddingBottom = resolveBoxValue(style.paddingBottom, width);
|
|
2084
|
-
const
|
|
2085
|
-
const
|
|
2086
|
-
const
|
|
2087
|
-
const
|
|
2386
|
+
const borderTopW = resolveBoxValue(style.borderTopWidth, width);
|
|
2387
|
+
const borderLeftW = resolveBoxValue(style.borderLeftWidth, width);
|
|
2388
|
+
const borderRightW = resolveBoxValue(style.borderRightWidth, width);
|
|
2389
|
+
const borderBottomW = resolveBoxValue(style.borderBottomWidth, width);
|
|
2390
|
+
const imgX = x + paddingLeft + borderLeftW;
|
|
2391
|
+
const imgY = y + paddingTop + borderTopW;
|
|
2392
|
+
const imgW = width - paddingLeft - paddingRight - borderLeftW - borderRightW;
|
|
2393
|
+
const imgH = height - paddingTop - paddingBottom - borderTopW - borderBottomW;
|
|
2088
2394
|
if (!isClipped) {
|
|
2089
2395
|
const borderRadius = getBorderRadiusFromStyle(style, width, height);
|
|
2090
2396
|
if (hasRadius(borderRadius)) {
|
|
@@ -2325,23 +2631,32 @@ function expandStyle(raw, fontFamilies) {
|
|
|
2325
2631
|
}
|
|
2326
2632
|
if (style.flex !== void 0) {
|
|
2327
2633
|
const val = String(style.flex);
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
if (
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2634
|
+
if (val === "none") {
|
|
2635
|
+
if (style.flexGrow === void 0) style.flexGrow = 0;
|
|
2636
|
+
if (style.flexShrink === void 0) style.flexShrink = 0;
|
|
2637
|
+
if (style.flexBasis === void 0) style.flexBasis = "auto";
|
|
2638
|
+
} else {
|
|
2639
|
+
const parts = val.split(/\s+/);
|
|
2640
|
+
if (parts.length === 1) {
|
|
2641
|
+
const n = parseFloat(parts[0]);
|
|
2642
|
+
if (!isNaN(n)) {
|
|
2643
|
+
if (style.flexGrow === void 0) style.flexGrow = n;
|
|
2644
|
+
if (style.flexShrink === void 0) style.flexShrink = 1;
|
|
2645
|
+
if (style.flexBasis === void 0) style.flexBasis = 0;
|
|
2646
|
+
}
|
|
2647
|
+
} else if (parts.length === 2) {
|
|
2648
|
+
if (style.flexGrow === void 0)
|
|
2649
|
+
style.flexGrow = parseFloat(parts[0]);
|
|
2650
|
+
if (style.flexShrink === void 0)
|
|
2651
|
+
style.flexShrink = parseFloat(parts[1]);
|
|
2652
|
+
} else if (parts.length >= 3) {
|
|
2653
|
+
if (style.flexGrow === void 0)
|
|
2654
|
+
style.flexGrow = parseFloat(parts[0]);
|
|
2655
|
+
if (style.flexShrink === void 0)
|
|
2656
|
+
style.flexShrink = parseFloat(parts[1]);
|
|
2657
|
+
if (style.flexBasis === void 0)
|
|
2658
|
+
style.flexBasis = parseValue(parts[2]);
|
|
2335
2659
|
}
|
|
2336
|
-
} else if (parts.length === 2) {
|
|
2337
|
-
if (style.flexGrow === void 0) style.flexGrow = parseFloat(parts[0]);
|
|
2338
|
-
if (style.flexShrink === void 0)
|
|
2339
|
-
style.flexShrink = parseFloat(parts[1]);
|
|
2340
|
-
} else if (parts.length >= 3) {
|
|
2341
|
-
if (style.flexGrow === void 0) style.flexGrow = parseFloat(parts[0]);
|
|
2342
|
-
if (style.flexShrink === void 0)
|
|
2343
|
-
style.flexShrink = parseFloat(parts[1]);
|
|
2344
|
-
if (style.flexBasis === void 0) style.flexBasis = parseValue(parts[2]);
|
|
2345
2660
|
}
|
|
2346
2661
|
delete style.flex;
|
|
2347
2662
|
}
|
|
@@ -2853,36 +3168,6 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
|
|
|
2853
3168
|
yogaNode
|
|
2854
3169
|
};
|
|
2855
3170
|
}
|
|
2856
|
-
if (Array.isArray(element)) {
|
|
2857
|
-
const style2 = resolveStyle(void 0, parentStyle);
|
|
2858
|
-
const children2 = [];
|
|
2859
|
-
for (let i = 0; i < element.length; i++) {
|
|
2860
|
-
const child = element[i];
|
|
2861
|
-
if (child === null || child === void 0 || typeof child === "boolean")
|
|
2862
|
-
continue;
|
|
2863
|
-
const childYogaNode = createYogaNode();
|
|
2864
|
-
yogaNode.insertChild(childYogaNode, children2.length);
|
|
2865
|
-
children2.push(
|
|
2866
|
-
await buildNode(
|
|
2867
|
-
child,
|
|
2868
|
-
style2,
|
|
2869
|
-
childYogaNode,
|
|
2870
|
-
viewportWidth,
|
|
2871
|
-
viewportHeight,
|
|
2872
|
-
ctx,
|
|
2873
|
-
emojiEnabled,
|
|
2874
|
-
fontFamilies
|
|
2875
|
-
)
|
|
2876
|
-
);
|
|
2877
|
-
}
|
|
2878
|
-
return {
|
|
2879
|
-
type: "div",
|
|
2880
|
-
style: style2,
|
|
2881
|
-
children: children2,
|
|
2882
|
-
props: {},
|
|
2883
|
-
yogaNode
|
|
2884
|
-
};
|
|
2885
|
-
}
|
|
2886
3171
|
const el = element;
|
|
2887
3172
|
const type = el.type;
|
|
2888
3173
|
if (typeof type === "function") {
|
|
@@ -2983,9 +3268,15 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
|
|
|
2983
3268
|
emojiEnabled
|
|
2984
3269
|
);
|
|
2985
3270
|
childYogaNode.setMeasureFunc(measureFunc);
|
|
2986
|
-
|
|
3271
|
+
const jc = style.justifyContent;
|
|
3272
|
+
if (!jc || jc === "flex-start") {
|
|
3273
|
+
childYogaNode.setFlexGrow(1);
|
|
3274
|
+
}
|
|
2987
3275
|
childYogaNode.setFlexShrink(1);
|
|
2988
3276
|
yogaNode.insertChild(childYogaNode, 0);
|
|
3277
|
+
if (style.flexShrink === void 0) {
|
|
3278
|
+
yogaNode.setFlexShrink(1);
|
|
3279
|
+
}
|
|
2989
3280
|
return {
|
|
2990
3281
|
type: tagName,
|
|
2991
3282
|
style,
|
|
@@ -3006,7 +3297,7 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
|
|
|
3006
3297
|
const children = [];
|
|
3007
3298
|
const rawChildren = props.children;
|
|
3008
3299
|
if (rawChildren !== void 0 && rawChildren !== null) {
|
|
3009
|
-
const childArray = Array.isArray(rawChildren) ? rawChildren : [rawChildren];
|
|
3300
|
+
const childArray = Array.isArray(rawChildren) ? rawChildren.flat(Infinity) : [rawChildren];
|
|
3010
3301
|
for (const child of childArray) {
|
|
3011
3302
|
if (child === null || child === void 0 || typeof child === "boolean")
|
|
3012
3303
|
continue;
|