@effing/canvas 0.1.0 → 0.18.1
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 +404 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ function renderLottieFrame(ctx, animation, frame) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// src/jsx/draw/index.ts
|
|
24
|
-
import { loadImage as loadImage3 } from "@napi-rs/canvas";
|
|
24
|
+
import { createCanvas as createCanvas2, loadImage as loadImage3 } from "@napi-rs/canvas";
|
|
25
25
|
|
|
26
26
|
// src/jsx/language.ts
|
|
27
27
|
function isEmoji(char) {
|
|
@@ -948,9 +948,9 @@ function applyStroke(ctx, props, path) {
|
|
|
948
948
|
const stroke = props.stroke;
|
|
949
949
|
if (!stroke || stroke === "none") return;
|
|
950
950
|
ctx.strokeStyle = stroke;
|
|
951
|
-
ctx.lineWidth = Number(props.strokeWidth ?? 1);
|
|
952
|
-
ctx.lineCap = props.strokeLinecap ?? "butt";
|
|
953
|
-
ctx.lineJoin = props.strokeLinejoin ?? "miter";
|
|
951
|
+
ctx.lineWidth = Number(props.strokeWidth ?? props["stroke-width"] ?? 1);
|
|
952
|
+
ctx.lineCap = props.strokeLinecap ?? props["stroke-linecap"] ?? "butt";
|
|
953
|
+
ctx.lineJoin = props.strokeLinejoin ?? props["stroke-linejoin"] ?? "miter";
|
|
954
954
|
ctx.stroke(path);
|
|
955
955
|
}
|
|
956
956
|
|
|
@@ -1168,6 +1168,34 @@ function drawTextDecoration(ctx, seg, offsetX, offsetY) {
|
|
|
1168
1168
|
}
|
|
1169
1169
|
|
|
1170
1170
|
// src/jsx/draw/index.ts
|
|
1171
|
+
var canvasPool = /* @__PURE__ */ new Map();
|
|
1172
|
+
function acquireOffscreen(w, h) {
|
|
1173
|
+
const key = `${w}x${h}`;
|
|
1174
|
+
const stack = canvasPool.get(key);
|
|
1175
|
+
if (stack) {
|
|
1176
|
+
while (stack.length > 0) {
|
|
1177
|
+
const ref = stack.pop();
|
|
1178
|
+
const canvas2 = ref.deref();
|
|
1179
|
+
if (canvas2) {
|
|
1180
|
+
const ctx = canvas2.getContext("2d");
|
|
1181
|
+
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
1182
|
+
ctx.clearRect(0, 0, w, h);
|
|
1183
|
+
return [canvas2, ctx];
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
const canvas = createCanvas2(w, h);
|
|
1188
|
+
return [canvas, canvas.getContext("2d")];
|
|
1189
|
+
}
|
|
1190
|
+
function releaseOffscreen(canvas) {
|
|
1191
|
+
const key = `${canvas.width}x${canvas.height}`;
|
|
1192
|
+
let stack = canvasPool.get(key);
|
|
1193
|
+
if (!stack) {
|
|
1194
|
+
stack = [];
|
|
1195
|
+
canvasPool.set(key, stack);
|
|
1196
|
+
}
|
|
1197
|
+
stack.push(new WeakRef(canvas));
|
|
1198
|
+
}
|
|
1171
1199
|
async function drawNode(ctx, node, parentX, parentY, debug, emojiStyle) {
|
|
1172
1200
|
const x = parentX + node.x;
|
|
1173
1201
|
const y = parentY + node.y;
|
|
@@ -1175,6 +1203,61 @@ async function drawNode(ctx, node, parentX, parentY, debug, emojiStyle) {
|
|
|
1175
1203
|
if (style.display === "none") return;
|
|
1176
1204
|
const opacity = style.opacity ?? 1;
|
|
1177
1205
|
if (opacity <= 0) return;
|
|
1206
|
+
const scaleInfo = style.transform ? extractScale(style.transform) : null;
|
|
1207
|
+
if (scaleInfo && (scaleInfo.sx !== 1 || scaleInfo.sy !== 1)) {
|
|
1208
|
+
const sx = scaleInfo.sx;
|
|
1209
|
+
const sy = scaleInfo.sy;
|
|
1210
|
+
const transformWithoutScale = scaleInfo.remaining;
|
|
1211
|
+
const qx = Math.max(1, Math.ceil(Math.abs(sx)));
|
|
1212
|
+
const qy = Math.max(1, Math.ceil(Math.abs(sy)));
|
|
1213
|
+
const bufW = Math.ceil((width + 2) * qx);
|
|
1214
|
+
const bufH = Math.ceil((height + 2) * qy);
|
|
1215
|
+
if (bufW > 0 && bufH > 0) {
|
|
1216
|
+
const [offscreen, offCtx] = acquireOffscreen(bufW, bufH);
|
|
1217
|
+
offCtx.save();
|
|
1218
|
+
offCtx.scale(qx, qy);
|
|
1219
|
+
await drawNodeInner(
|
|
1220
|
+
offCtx,
|
|
1221
|
+
node,
|
|
1222
|
+
parentX,
|
|
1223
|
+
parentY,
|
|
1224
|
+
1 - x,
|
|
1225
|
+
1 - y,
|
|
1226
|
+
debug,
|
|
1227
|
+
emojiStyle,
|
|
1228
|
+
transformWithoutScale
|
|
1229
|
+
);
|
|
1230
|
+
offCtx.restore();
|
|
1231
|
+
ctx.save();
|
|
1232
|
+
if (opacity < 1) {
|
|
1233
|
+
ctx.globalAlpha *= opacity;
|
|
1234
|
+
}
|
|
1235
|
+
let ox = x + width / 2;
|
|
1236
|
+
let oy = y + height / 2;
|
|
1237
|
+
if (style.transformOrigin) {
|
|
1238
|
+
const parts = style.transformOrigin.split(/\s+/);
|
|
1239
|
+
ox = resolveOrigin(parts[0], x, width);
|
|
1240
|
+
oy = resolveOrigin(parts[1], y, height);
|
|
1241
|
+
}
|
|
1242
|
+
ctx.translate(ox, oy);
|
|
1243
|
+
ctx.scale(sx, sy);
|
|
1244
|
+
ctx.translate(-ox, -oy);
|
|
1245
|
+
ctx.drawImage(
|
|
1246
|
+
offscreen,
|
|
1247
|
+
0,
|
|
1248
|
+
0,
|
|
1249
|
+
bufW,
|
|
1250
|
+
bufH,
|
|
1251
|
+
x - 1,
|
|
1252
|
+
y - 1,
|
|
1253
|
+
width + 2,
|
|
1254
|
+
height + 2
|
|
1255
|
+
);
|
|
1256
|
+
releaseOffscreen(offscreen);
|
|
1257
|
+
ctx.restore();
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1178
1261
|
ctx.save();
|
|
1179
1262
|
if (opacity < 1) {
|
|
1180
1263
|
ctx.globalAlpha *= opacity;
|
|
@@ -1344,6 +1427,193 @@ async function drawNode(ctx, node, parentX, parentY, debug, emojiStyle) {
|
|
|
1344
1427
|
}
|
|
1345
1428
|
ctx.restore();
|
|
1346
1429
|
}
|
|
1430
|
+
function extractScale(transform) {
|
|
1431
|
+
const scaleMatch = transform.match(/\b(scale|scaleX|scaleY)\(([^)]+)\)/);
|
|
1432
|
+
if (!scaleMatch) return null;
|
|
1433
|
+
const [fullMatch, name, args] = scaleMatch;
|
|
1434
|
+
const values = args.split(",").map((s) => s.trim());
|
|
1435
|
+
const sx = name === "scaleY" ? 1 : parseFloat(values[0]);
|
|
1436
|
+
const sy = name === "scaleX" ? 1 : parseFloat(values[name === "scale" ? 1 : 0] ?? String(sx));
|
|
1437
|
+
const remaining = transform.replace(fullMatch, "").trim();
|
|
1438
|
+
return { sx, sy, remaining };
|
|
1439
|
+
}
|
|
1440
|
+
async function drawNodeInner(ctx, node, parentX, parentY, offsetX, offsetY, debug, emojiStyle, overrideTransform) {
|
|
1441
|
+
const x = parentX + node.x + offsetX;
|
|
1442
|
+
const y = parentY + node.y + offsetY;
|
|
1443
|
+
const { width, height, style } = node;
|
|
1444
|
+
if (style.display === "none") return;
|
|
1445
|
+
const opacity = style.opacity ?? 1;
|
|
1446
|
+
if (opacity <= 0) return;
|
|
1447
|
+
ctx.save();
|
|
1448
|
+
if (opacity < 1) {
|
|
1449
|
+
ctx.globalAlpha *= opacity;
|
|
1450
|
+
}
|
|
1451
|
+
if (style.filter) {
|
|
1452
|
+
ctx.filter = style.filter;
|
|
1453
|
+
}
|
|
1454
|
+
const transformToApply = overrideTransform !== void 0 ? overrideTransform : style.transform;
|
|
1455
|
+
if (transformToApply) {
|
|
1456
|
+
applyTransform(
|
|
1457
|
+
ctx,
|
|
1458
|
+
transformToApply,
|
|
1459
|
+
x,
|
|
1460
|
+
y,
|
|
1461
|
+
width,
|
|
1462
|
+
height,
|
|
1463
|
+
style.transformOrigin
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
const isClipped = style.overflow === "hidden" || style.overflowX === "hidden" || style.overflowY === "hidden";
|
|
1467
|
+
if (isClipped) {
|
|
1468
|
+
const borderRadius = getBorderRadiusFromStyle(style);
|
|
1469
|
+
applyClip(ctx, x, y, width, height, borderRadius);
|
|
1470
|
+
}
|
|
1471
|
+
if (style.backgroundColor || style.borderTopWidth || style.borderRightWidth || style.borderBottomWidth || style.borderLeftWidth || style.boxShadow) {
|
|
1472
|
+
drawRect(ctx, x, y, width, height, style);
|
|
1473
|
+
}
|
|
1474
|
+
if (style.backgroundImage) {
|
|
1475
|
+
const gradient = createGradientFromCSS(
|
|
1476
|
+
ctx,
|
|
1477
|
+
style.backgroundImage,
|
|
1478
|
+
x,
|
|
1479
|
+
y,
|
|
1480
|
+
width,
|
|
1481
|
+
height
|
|
1482
|
+
);
|
|
1483
|
+
if (gradient) {
|
|
1484
|
+
ctx.fillStyle = gradient;
|
|
1485
|
+
const borderRadius = getBorderRadiusFromStyle(style);
|
|
1486
|
+
if (borderRadius.topLeft > 0 || borderRadius.topRight > 0 || borderRadius.bottomRight > 0 || borderRadius.bottomLeft > 0) {
|
|
1487
|
+
ctx.beginPath();
|
|
1488
|
+
roundedRect(
|
|
1489
|
+
ctx,
|
|
1490
|
+
x,
|
|
1491
|
+
y,
|
|
1492
|
+
width,
|
|
1493
|
+
height,
|
|
1494
|
+
borderRadius.topLeft,
|
|
1495
|
+
borderRadius.topRight,
|
|
1496
|
+
borderRadius.bottomRight,
|
|
1497
|
+
borderRadius.bottomLeft
|
|
1498
|
+
);
|
|
1499
|
+
ctx.fill();
|
|
1500
|
+
} else {
|
|
1501
|
+
ctx.fillRect(x, y, width, height);
|
|
1502
|
+
}
|
|
1503
|
+
} else {
|
|
1504
|
+
const urlMatch = style.backgroundImage.match(/url\(["']?(.*?)["']?\)/);
|
|
1505
|
+
if (urlMatch) {
|
|
1506
|
+
const borderRadius = getBorderRadiusFromStyle(style);
|
|
1507
|
+
const hasRadius2 = borderRadius.topLeft > 0 || borderRadius.topRight > 0 || borderRadius.bottomRight > 0 || borderRadius.bottomLeft > 0;
|
|
1508
|
+
if (hasRadius2) {
|
|
1509
|
+
applyClip(ctx, x, y, width, height, borderRadius);
|
|
1510
|
+
}
|
|
1511
|
+
const image = await loadImage3(urlMatch[1]);
|
|
1512
|
+
const bgSize = style.backgroundSize;
|
|
1513
|
+
if (bgSize === "cover") {
|
|
1514
|
+
const r = computeCover(
|
|
1515
|
+
image.width,
|
|
1516
|
+
image.height,
|
|
1517
|
+
x,
|
|
1518
|
+
y,
|
|
1519
|
+
width,
|
|
1520
|
+
height
|
|
1521
|
+
);
|
|
1522
|
+
ctx.drawImage(image, r.sx, r.sy, r.sw, r.sh, r.dx, r.dy, r.dw, r.dh);
|
|
1523
|
+
} else {
|
|
1524
|
+
let tileW, tileH;
|
|
1525
|
+
if (bgSize === "contain") {
|
|
1526
|
+
const r = computeContain(
|
|
1527
|
+
image.width,
|
|
1528
|
+
image.height,
|
|
1529
|
+
0,
|
|
1530
|
+
0,
|
|
1531
|
+
width,
|
|
1532
|
+
height
|
|
1533
|
+
);
|
|
1534
|
+
tileW = r.dw;
|
|
1535
|
+
tileH = r.dh;
|
|
1536
|
+
} else if (bgSize === "100% 100%") {
|
|
1537
|
+
tileW = width;
|
|
1538
|
+
tileH = height;
|
|
1539
|
+
} else {
|
|
1540
|
+
tileW = image.width;
|
|
1541
|
+
tileH = image.height;
|
|
1542
|
+
}
|
|
1543
|
+
for (let ty = y; ty < y + height; ty += tileH) {
|
|
1544
|
+
for (let tx = x; tx < x + width; tx += tileW) {
|
|
1545
|
+
ctx.drawImage(image, tx, ty, tileW, tileH);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
if (debug) {
|
|
1553
|
+
ctx.strokeStyle = "rgba(255, 0, 0, 0.5)";
|
|
1554
|
+
ctx.lineWidth = 1;
|
|
1555
|
+
ctx.strokeRect(x, y, width, height);
|
|
1556
|
+
}
|
|
1557
|
+
if (node.textContent !== void 0 && node.textContent !== "") {
|
|
1558
|
+
const paddingTop = toNumber2(style.paddingTop);
|
|
1559
|
+
const paddingLeft = toNumber2(style.paddingLeft);
|
|
1560
|
+
const paddingRight = toNumber2(style.paddingRight);
|
|
1561
|
+
const borderTopW = toNumber2(style.borderTopWidth);
|
|
1562
|
+
const borderLeftW = toNumber2(style.borderLeftWidth);
|
|
1563
|
+
const borderRightW = toNumber2(style.borderRightWidth);
|
|
1564
|
+
const contentX = x + paddingLeft + borderLeftW;
|
|
1565
|
+
const contentY = y + paddingTop + borderTopW;
|
|
1566
|
+
const contentWidth = width - paddingLeft - paddingRight - borderLeftW - borderRightW;
|
|
1567
|
+
const textLayout = layoutText(
|
|
1568
|
+
node.textContent,
|
|
1569
|
+
style,
|
|
1570
|
+
contentWidth,
|
|
1571
|
+
ctx,
|
|
1572
|
+
!!emojiStyle
|
|
1573
|
+
);
|
|
1574
|
+
await drawText(
|
|
1575
|
+
ctx,
|
|
1576
|
+
textLayout.segments,
|
|
1577
|
+
contentX,
|
|
1578
|
+
contentY,
|
|
1579
|
+
style.textShadow,
|
|
1580
|
+
emojiStyle
|
|
1581
|
+
);
|
|
1582
|
+
}
|
|
1583
|
+
if (node.type === "img" && node.props.src) {
|
|
1584
|
+
const paddingTop = toNumber2(style.paddingTop);
|
|
1585
|
+
const paddingLeft = toNumber2(style.paddingLeft);
|
|
1586
|
+
const paddingRight = toNumber2(style.paddingRight);
|
|
1587
|
+
const paddingBottom = toNumber2(style.paddingBottom);
|
|
1588
|
+
const imgX = x + paddingLeft;
|
|
1589
|
+
const imgY = y + paddingTop;
|
|
1590
|
+
const imgW = width - paddingLeft - paddingRight;
|
|
1591
|
+
const imgH = height - paddingTop - paddingBottom;
|
|
1592
|
+
if (!isClipped) {
|
|
1593
|
+
const borderRadius = getBorderRadiusFromStyle(style);
|
|
1594
|
+
if (borderRadius.topLeft > 0 || borderRadius.topRight > 0 || borderRadius.bottomRight > 0 || borderRadius.bottomLeft > 0) {
|
|
1595
|
+
applyClip(ctx, imgX, imgY, imgW, imgH, borderRadius);
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
await drawImage(
|
|
1599
|
+
ctx,
|
|
1600
|
+
node.props.src,
|
|
1601
|
+
imgX,
|
|
1602
|
+
imgY,
|
|
1603
|
+
imgW,
|
|
1604
|
+
imgH,
|
|
1605
|
+
style
|
|
1606
|
+
);
|
|
1607
|
+
}
|
|
1608
|
+
if (node.type === "svg") {
|
|
1609
|
+
drawSvgContainer(ctx, node, x, y, width, height);
|
|
1610
|
+
} else {
|
|
1611
|
+
for (const child of node.children) {
|
|
1612
|
+
await drawNodeInner(ctx, child, x, y, 0, 0, debug, emojiStyle, void 0);
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
ctx.restore();
|
|
1616
|
+
}
|
|
1347
1617
|
function applyTransform(ctx, transform, x, y, width, height, transformOrigin) {
|
|
1348
1618
|
let ox = x + width / 2;
|
|
1349
1619
|
let oy = y + height / 2;
|
|
@@ -1643,6 +1913,99 @@ function resolveStyle(rawStyle, parentStyle) {
|
|
|
1643
1913
|
}
|
|
1644
1914
|
return style;
|
|
1645
1915
|
}
|
|
1916
|
+
var DIMENSION_PROPS = [
|
|
1917
|
+
"width",
|
|
1918
|
+
"height",
|
|
1919
|
+
"minWidth",
|
|
1920
|
+
"minHeight",
|
|
1921
|
+
"maxWidth",
|
|
1922
|
+
"maxHeight",
|
|
1923
|
+
"top",
|
|
1924
|
+
"right",
|
|
1925
|
+
"bottom",
|
|
1926
|
+
"left",
|
|
1927
|
+
"marginTop",
|
|
1928
|
+
"marginRight",
|
|
1929
|
+
"marginBottom",
|
|
1930
|
+
"marginLeft",
|
|
1931
|
+
"paddingTop",
|
|
1932
|
+
"paddingRight",
|
|
1933
|
+
"paddingBottom",
|
|
1934
|
+
"paddingLeft",
|
|
1935
|
+
"rowGap",
|
|
1936
|
+
"columnGap",
|
|
1937
|
+
"flexBasis"
|
|
1938
|
+
];
|
|
1939
|
+
function resolveUnit(value, viewportWidth, viewportHeight, fontSize, rootFontSize) {
|
|
1940
|
+
if (value.endsWith("%") || value === "auto") return value;
|
|
1941
|
+
if (value.endsWith("vmin")) {
|
|
1942
|
+
const n = parseFloat(value);
|
|
1943
|
+
return isNaN(n) ? value : n / 100 * Math.min(viewportWidth, viewportHeight);
|
|
1944
|
+
}
|
|
1945
|
+
if (value.endsWith("vmax")) {
|
|
1946
|
+
const n = parseFloat(value);
|
|
1947
|
+
return isNaN(n) ? value : n / 100 * Math.max(viewportWidth, viewportHeight);
|
|
1948
|
+
}
|
|
1949
|
+
if (value.endsWith("vw")) {
|
|
1950
|
+
const n = parseFloat(value);
|
|
1951
|
+
return isNaN(n) ? value : n / 100 * viewportWidth;
|
|
1952
|
+
}
|
|
1953
|
+
if (value.endsWith("vh")) {
|
|
1954
|
+
const n = parseFloat(value);
|
|
1955
|
+
return isNaN(n) ? value : n / 100 * viewportHeight;
|
|
1956
|
+
}
|
|
1957
|
+
if (value.endsWith("rem")) {
|
|
1958
|
+
const n = parseFloat(value);
|
|
1959
|
+
return isNaN(n) ? value : n * rootFontSize;
|
|
1960
|
+
}
|
|
1961
|
+
if (value.endsWith("em")) {
|
|
1962
|
+
const n = parseFloat(value);
|
|
1963
|
+
return isNaN(n) ? value : n * fontSize;
|
|
1964
|
+
}
|
|
1965
|
+
if (value.endsWith("px")) {
|
|
1966
|
+
const n = parseFloat(value);
|
|
1967
|
+
return isNaN(n) ? value : n;
|
|
1968
|
+
}
|
|
1969
|
+
if (value.endsWith("pt")) {
|
|
1970
|
+
const n = parseFloat(value);
|
|
1971
|
+
return isNaN(n) ? value : n * (96 / 72);
|
|
1972
|
+
}
|
|
1973
|
+
if (value.endsWith("pc")) {
|
|
1974
|
+
const n = parseFloat(value);
|
|
1975
|
+
return isNaN(n) ? value : n * 16;
|
|
1976
|
+
}
|
|
1977
|
+
if (value.endsWith("in")) {
|
|
1978
|
+
const n = parseFloat(value);
|
|
1979
|
+
return isNaN(n) ? value : n * 96;
|
|
1980
|
+
}
|
|
1981
|
+
if (value.endsWith("cm")) {
|
|
1982
|
+
const n = parseFloat(value);
|
|
1983
|
+
return isNaN(n) ? value : n * (96 / 2.54);
|
|
1984
|
+
}
|
|
1985
|
+
if (value.endsWith("mm")) {
|
|
1986
|
+
const n = parseFloat(value);
|
|
1987
|
+
return isNaN(n) ? value : n * (96 / 25.4);
|
|
1988
|
+
}
|
|
1989
|
+
return value;
|
|
1990
|
+
}
|
|
1991
|
+
function resolveUnits(style, viewportWidth, viewportHeight, rootFontSize = DEFAULT_STYLE.fontSize) {
|
|
1992
|
+
const fontSize = typeof style.fontSize === "number" ? style.fontSize : rootFontSize;
|
|
1993
|
+
for (const prop of DIMENSION_PROPS) {
|
|
1994
|
+
const value = style[prop];
|
|
1995
|
+
if (typeof value !== "string") continue;
|
|
1996
|
+
const resolved = resolveUnit(
|
|
1997
|
+
value,
|
|
1998
|
+
viewportWidth,
|
|
1999
|
+
viewportHeight,
|
|
2000
|
+
fontSize,
|
|
2001
|
+
rootFontSize
|
|
2002
|
+
);
|
|
2003
|
+
if (resolved !== value) {
|
|
2004
|
+
style[prop] = resolved;
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
return style;
|
|
2008
|
+
}
|
|
1646
2009
|
|
|
1647
2010
|
// src/jsx/yoga.ts
|
|
1648
2011
|
import Yoga, {
|
|
@@ -1837,6 +2200,8 @@ function buildLayoutTree(element, containerWidth, containerHeight, ctx, emojiEna
|
|
|
1837
2200
|
element,
|
|
1838
2201
|
DEFAULT_STYLE,
|
|
1839
2202
|
rootYogaNode,
|
|
2203
|
+
containerWidth,
|
|
2204
|
+
containerHeight,
|
|
1840
2205
|
ctx,
|
|
1841
2206
|
emojiEnabled
|
|
1842
2207
|
);
|
|
@@ -1847,7 +2212,7 @@ function buildLayoutTree(element, containerWidth, containerHeight, ctx, emojiEna
|
|
|
1847
2212
|
freeYogaNode(rootYogaNode);
|
|
1848
2213
|
return layoutTree;
|
|
1849
2214
|
}
|
|
1850
|
-
function buildNode(element, parentStyle, yogaNode, ctx, emojiEnabled) {
|
|
2215
|
+
function buildNode(element, parentStyle, yogaNode, viewportWidth, viewportHeight, ctx, emojiEnabled) {
|
|
1851
2216
|
if (element === null || element === void 0 || typeof element === "boolean") {
|
|
1852
2217
|
return {
|
|
1853
2218
|
type: "empty",
|
|
@@ -1880,7 +2245,17 @@ function buildNode(element, parentStyle, yogaNode, ctx, emojiEnabled) {
|
|
|
1880
2245
|
continue;
|
|
1881
2246
|
const childYogaNode = createYogaNode();
|
|
1882
2247
|
yogaNode.insertChild(childYogaNode, children2.length);
|
|
1883
|
-
children2.push(
|
|
2248
|
+
children2.push(
|
|
2249
|
+
buildNode(
|
|
2250
|
+
child,
|
|
2251
|
+
style2,
|
|
2252
|
+
childYogaNode,
|
|
2253
|
+
viewportWidth,
|
|
2254
|
+
viewportHeight,
|
|
2255
|
+
ctx,
|
|
2256
|
+
emojiEnabled
|
|
2257
|
+
)
|
|
2258
|
+
);
|
|
1884
2259
|
}
|
|
1885
2260
|
return {
|
|
1886
2261
|
type: "div",
|
|
@@ -1896,12 +2271,21 @@ function buildNode(element, parentStyle, yogaNode, ctx, emojiEnabled) {
|
|
|
1896
2271
|
const rendered = type(
|
|
1897
2272
|
el.props ?? {}
|
|
1898
2273
|
);
|
|
1899
|
-
return buildNode(
|
|
2274
|
+
return buildNode(
|
|
2275
|
+
rendered,
|
|
2276
|
+
parentStyle,
|
|
2277
|
+
yogaNode,
|
|
2278
|
+
viewportWidth,
|
|
2279
|
+
viewportHeight,
|
|
2280
|
+
ctx,
|
|
2281
|
+
emojiEnabled
|
|
2282
|
+
);
|
|
1900
2283
|
}
|
|
1901
2284
|
const props = el.props ?? {};
|
|
1902
2285
|
const rawStyle = props.style ?? {};
|
|
1903
2286
|
const expanded = expandStyle(rawStyle);
|
|
1904
2287
|
const style = resolveStyle(expanded, parentStyle);
|
|
2288
|
+
resolveUnits(style, viewportWidth, viewportHeight);
|
|
1905
2289
|
const tagName = String(type);
|
|
1906
2290
|
if (tagName === "svg") {
|
|
1907
2291
|
if (props.width != null && style.width === void 0)
|
|
@@ -1976,7 +2360,17 @@ function buildNode(element, parentStyle, yogaNode, ctx, emojiEnabled) {
|
|
|
1976
2360
|
continue;
|
|
1977
2361
|
const childYogaNode = createYogaNode();
|
|
1978
2362
|
yogaNode.insertChild(childYogaNode, children.length);
|
|
1979
|
-
children.push(
|
|
2363
|
+
children.push(
|
|
2364
|
+
buildNode(
|
|
2365
|
+
child,
|
|
2366
|
+
style,
|
|
2367
|
+
childYogaNode,
|
|
2368
|
+
viewportWidth,
|
|
2369
|
+
viewportHeight,
|
|
2370
|
+
ctx,
|
|
2371
|
+
emojiEnabled
|
|
2372
|
+
)
|
|
2373
|
+
);
|
|
1980
2374
|
}
|
|
1981
2375
|
}
|
|
1982
2376
|
return {
|
|
@@ -2047,7 +2441,7 @@ async function renderReactElement(ctx, element, options) {
|
|
|
2047
2441
|
}
|
|
2048
2442
|
|
|
2049
2443
|
// src/index.ts
|
|
2050
|
-
function
|
|
2444
|
+
function createCanvas3(width, height) {
|
|
2051
2445
|
const canvas = _createCanvas(width, height);
|
|
2052
2446
|
const origEncode = canvas.encode.bind(canvas);
|
|
2053
2447
|
canvas.encode = (async (...args) => Buffer.from(await origEncode(...args)));
|
|
@@ -2058,7 +2452,7 @@ export {
|
|
|
2058
2452
|
GlobalFonts2 as GlobalFonts,
|
|
2059
2453
|
Image,
|
|
2060
2454
|
LottieAnimation,
|
|
2061
|
-
|
|
2455
|
+
createCanvas3 as createCanvas,
|
|
2062
2456
|
loadImage4 as loadImage,
|
|
2063
2457
|
loadLottie,
|
|
2064
2458
|
registerFont,
|