lbrnts 0.0.18 → 0.0.19
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 +44 -249
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1322,126 +1322,6 @@ function collectShapes(root) {
|
|
|
1322
1322
|
return out;
|
|
1323
1323
|
}
|
|
1324
1324
|
|
|
1325
|
-
// lib/svg-gen/collect-cut-settings.ts
|
|
1326
|
-
function collectCutSettings(root) {
|
|
1327
|
-
const settings = /* @__PURE__ */ new Map();
|
|
1328
|
-
const processElement = (el) => {
|
|
1329
|
-
if (el instanceof CutSetting && el.index !== void 0) {
|
|
1330
|
-
settings.set(el.index, el);
|
|
1331
|
-
} else if (el instanceof LightBurnProject) {
|
|
1332
|
-
for (const child of el.children) {
|
|
1333
|
-
if (child instanceof CutSetting && child.index !== void 0) {
|
|
1334
|
-
settings.set(child.index, child);
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
};
|
|
1339
|
-
if (Array.isArray(root)) {
|
|
1340
|
-
root.forEach(processElement);
|
|
1341
|
-
} else {
|
|
1342
|
-
processElement(root);
|
|
1343
|
-
}
|
|
1344
|
-
return settings;
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
// lib/svg-gen/node-helpers.ts
|
|
1348
|
-
var g = (attrs, children = []) => ({
|
|
1349
|
-
name: "g",
|
|
1350
|
-
type: "element",
|
|
1351
|
-
value: "",
|
|
1352
|
-
attributes: attrs,
|
|
1353
|
-
children
|
|
1354
|
-
});
|
|
1355
|
-
var leaf = (name, attrs) => ({
|
|
1356
|
-
name,
|
|
1357
|
-
type: "element",
|
|
1358
|
-
value: "",
|
|
1359
|
-
attributes: attrs,
|
|
1360
|
-
children: []
|
|
1361
|
-
});
|
|
1362
|
-
var textNode = (value) => ({
|
|
1363
|
-
name: "",
|
|
1364
|
-
type: "text",
|
|
1365
|
-
value,
|
|
1366
|
-
attributes: {},
|
|
1367
|
-
children: []
|
|
1368
|
-
});
|
|
1369
|
-
|
|
1370
|
-
// lib/svg-gen/fill-patterns.ts
|
|
1371
|
-
function generatePatternId(params) {
|
|
1372
|
-
const opacity = params.opacity ?? 0.8;
|
|
1373
|
-
const safeColor = encodeURIComponent(params.color).replace(
|
|
1374
|
-
/[^a-zA-Z0-9]/g,
|
|
1375
|
-
"_"
|
|
1376
|
-
);
|
|
1377
|
-
return `hatch-${params.interval.toFixed(4)}-${params.angleDeg}-${params.crossHatch}-${safeColor}-${params.strokeWidth.toFixed(4)}-${opacity.toFixed(2)}`;
|
|
1378
|
-
}
|
|
1379
|
-
function createHatchPattern(params) {
|
|
1380
|
-
const { interval, angleDeg, crossHatch, color, strokeWidth } = params;
|
|
1381
|
-
const opacity = params.opacity ?? 0.8;
|
|
1382
|
-
const id = generatePatternId(params);
|
|
1383
|
-
let d = `M ${-interval} 0 L ${interval} 0`;
|
|
1384
|
-
if (crossHatch) {
|
|
1385
|
-
d += ` M 0 ${-interval} L 0 ${interval}`;
|
|
1386
|
-
}
|
|
1387
|
-
return {
|
|
1388
|
-
name: "pattern",
|
|
1389
|
-
type: "element",
|
|
1390
|
-
value: "",
|
|
1391
|
-
attributes: {
|
|
1392
|
-
id,
|
|
1393
|
-
patternUnits: "userSpaceOnUse",
|
|
1394
|
-
width: String(interval),
|
|
1395
|
-
height: String(interval),
|
|
1396
|
-
patternTransform: `rotate(${angleDeg})`
|
|
1397
|
-
},
|
|
1398
|
-
children: [
|
|
1399
|
-
leaf("path", {
|
|
1400
|
-
d,
|
|
1401
|
-
stroke: color,
|
|
1402
|
-
"stroke-width": String(strokeWidth),
|
|
1403
|
-
"stroke-opacity": String(opacity)
|
|
1404
|
-
})
|
|
1405
|
-
]
|
|
1406
|
-
};
|
|
1407
|
-
}
|
|
1408
|
-
var HatchPatternRegistry = class {
|
|
1409
|
-
patterns = /* @__PURE__ */ new Map();
|
|
1410
|
-
/**
|
|
1411
|
-
* Get or create a pattern for the given parameters.
|
|
1412
|
-
* @returns The pattern ID to use in fill="url(#id)"
|
|
1413
|
-
*/
|
|
1414
|
-
getOrCreate(params) {
|
|
1415
|
-
const id = generatePatternId(params);
|
|
1416
|
-
if (!this.patterns.has(id)) {
|
|
1417
|
-
this.patterns.set(id, createHatchPattern(params));
|
|
1418
|
-
}
|
|
1419
|
-
return id;
|
|
1420
|
-
}
|
|
1421
|
-
/**
|
|
1422
|
-
* Get all registered patterns for the <defs> section.
|
|
1423
|
-
*/
|
|
1424
|
-
getPatterns() {
|
|
1425
|
-
return Array.from(this.patterns.values());
|
|
1426
|
-
}
|
|
1427
|
-
/**
|
|
1428
|
-
* Check if any patterns have been registered.
|
|
1429
|
-
*/
|
|
1430
|
-
hasPatterns() {
|
|
1431
|
-
return this.patterns.size > 0;
|
|
1432
|
-
}
|
|
1433
|
-
};
|
|
1434
|
-
function fillSettingsToPatternParams(settings, color, strokeWidth, opacity) {
|
|
1435
|
-
return {
|
|
1436
|
-
interval: settings.interval,
|
|
1437
|
-
angleDeg: settings.angle,
|
|
1438
|
-
crossHatch: settings.crossHatch,
|
|
1439
|
-
color,
|
|
1440
|
-
strokeWidth,
|
|
1441
|
-
opacity
|
|
1442
|
-
};
|
|
1443
|
-
}
|
|
1444
|
-
|
|
1445
1325
|
// lib/svg-gen/options.ts
|
|
1446
1326
|
var DEFAULT_OPTIONS = {
|
|
1447
1327
|
margin: 10,
|
|
@@ -1523,6 +1403,29 @@ function addPts(bb, pts) {
|
|
|
1523
1403
|
return bb;
|
|
1524
1404
|
}
|
|
1525
1405
|
|
|
1406
|
+
// lib/svg-gen/node-helpers.ts
|
|
1407
|
+
var g = (attrs, children = []) => ({
|
|
1408
|
+
name: "g",
|
|
1409
|
+
type: "element",
|
|
1410
|
+
value: "",
|
|
1411
|
+
attributes: attrs,
|
|
1412
|
+
children
|
|
1413
|
+
});
|
|
1414
|
+
var leaf = (name, attrs) => ({
|
|
1415
|
+
name,
|
|
1416
|
+
type: "element",
|
|
1417
|
+
value: "",
|
|
1418
|
+
attributes: attrs,
|
|
1419
|
+
children: []
|
|
1420
|
+
});
|
|
1421
|
+
var textNode = (value) => ({
|
|
1422
|
+
name: "",
|
|
1423
|
+
type: "text",
|
|
1424
|
+
value,
|
|
1425
|
+
attributes: {},
|
|
1426
|
+
children: []
|
|
1427
|
+
});
|
|
1428
|
+
|
|
1526
1429
|
// lib/svg-gen/registry/shape-bitmap.ts
|
|
1527
1430
|
var bitmapRenderer = {
|
|
1528
1431
|
match: (s) => s instanceof ShapeBitmap,
|
|
@@ -1541,7 +1444,7 @@ var bitmapRenderer = {
|
|
|
1541
1444
|
corners.map((p) => apply(xform, p))
|
|
1542
1445
|
);
|
|
1543
1446
|
},
|
|
1544
|
-
toSvg: (bmp,
|
|
1447
|
+
toSvg: (bmp, _options) => {
|
|
1545
1448
|
const xform = bmp.xform ? arrayToMatrix(bmp.xform) : identity();
|
|
1546
1449
|
const transform = matToSvg(xform);
|
|
1547
1450
|
const w = bmp.w || 0;
|
|
@@ -1635,40 +1538,12 @@ var ellipseRenderer = {
|
|
|
1635
1538
|
extremes.map((p) => apply(xform, p))
|
|
1636
1539
|
);
|
|
1637
1540
|
},
|
|
1638
|
-
toSvg: (el,
|
|
1541
|
+
toSvg: (el, options) => {
|
|
1639
1542
|
const xform = el.xform ? arrayToMatrix(el.xform) : identity();
|
|
1640
1543
|
const transform = matToSvg(xform);
|
|
1641
1544
|
const rx = el.rx || 0;
|
|
1642
1545
|
const ry = el.ry || 0;
|
|
1643
1546
|
const stroke = colorForCutIndex(el.cutIndex);
|
|
1644
|
-
const children = [];
|
|
1645
|
-
const cutSetting = el.cutIndex !== void 0 ? cutSettings.get(el.cutIndex) : void 0;
|
|
1646
|
-
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1647
|
-
if (shouldShowFill && cutSetting) {
|
|
1648
|
-
const fillSettings = {
|
|
1649
|
-
interval: cutSetting.interval || 0.1,
|
|
1650
|
-
angle: cutSetting.angle || 0,
|
|
1651
|
-
crossHatch: cutSetting.crossHatch || false
|
|
1652
|
-
};
|
|
1653
|
-
const patternId = options.patternRegistry.getOrCreate(
|
|
1654
|
-
fillSettingsToPatternParams(fillSettings, stroke, options.strokeWidth)
|
|
1655
|
-
);
|
|
1656
|
-
const fillChild = rx === ry ? leaf("circle", {
|
|
1657
|
-
cx: "0",
|
|
1658
|
-
cy: "0",
|
|
1659
|
-
r: String(rx),
|
|
1660
|
-
fill: `url(#${patternId})`,
|
|
1661
|
-
stroke: "none"
|
|
1662
|
-
}) : leaf("ellipse", {
|
|
1663
|
-
cx: "0",
|
|
1664
|
-
cy: "0",
|
|
1665
|
-
rx: String(rx),
|
|
1666
|
-
ry: String(ry),
|
|
1667
|
-
fill: `url(#${patternId})`,
|
|
1668
|
-
stroke: "none"
|
|
1669
|
-
});
|
|
1670
|
-
children.push(fillChild);
|
|
1671
|
-
}
|
|
1672
1547
|
const outlineChild = rx === ry ? leaf("circle", {
|
|
1673
1548
|
cx: "0",
|
|
1674
1549
|
cy: "0",
|
|
@@ -1683,8 +1558,7 @@ var ellipseRenderer = {
|
|
|
1683
1558
|
fill: "none",
|
|
1684
1559
|
stroke
|
|
1685
1560
|
});
|
|
1686
|
-
|
|
1687
|
-
return g({ transform }, children);
|
|
1561
|
+
return g({ transform }, [outlineChild]);
|
|
1688
1562
|
}
|
|
1689
1563
|
};
|
|
1690
1564
|
|
|
@@ -1879,7 +1753,7 @@ var groupRenderer = {
|
|
|
1879
1753
|
bbox: (grp) => {
|
|
1880
1754
|
return grp.children.filter((c) => c instanceof ShapeBase).reduce((bb, c) => boxUnion(bb, bboxOfShape(c)), emptyBox());
|
|
1881
1755
|
},
|
|
1882
|
-
toSvg: (grp,
|
|
1756
|
+
toSvg: (grp, options) => {
|
|
1883
1757
|
const groupMatrix = grp.xform ? arrayToMatrix(grp.xform) : identity();
|
|
1884
1758
|
const transform = matToSvg(groupMatrix);
|
|
1885
1759
|
const shapeChildren = grp.children.filter(
|
|
@@ -1896,35 +1770,10 @@ var groupRenderer = {
|
|
|
1896
1770
|
}
|
|
1897
1771
|
if (pathDataParts.length > 0) {
|
|
1898
1772
|
const combinedPathData = pathDataParts.join(" ");
|
|
1899
|
-
const children2 = [];
|
|
1900
1773
|
const firstChild = shapeChildren[0];
|
|
1901
1774
|
const cutIndex = firstChild.cutIndex;
|
|
1902
1775
|
const stroke = colorForCutIndex(cutIndex);
|
|
1903
|
-
const
|
|
1904
|
-
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1905
|
-
if (shouldShowFill && cutSetting) {
|
|
1906
|
-
const fillSettings = {
|
|
1907
|
-
interval: cutSetting.interval || 0.1,
|
|
1908
|
-
angle: cutSetting.angle || 0,
|
|
1909
|
-
crossHatch: cutSetting.crossHatch || false
|
|
1910
|
-
};
|
|
1911
|
-
const patternId = options.patternRegistry.getOrCreate(
|
|
1912
|
-
fillSettingsToPatternParams(
|
|
1913
|
-
fillSettings,
|
|
1914
|
-
stroke,
|
|
1915
|
-
options.strokeWidth
|
|
1916
|
-
)
|
|
1917
|
-
);
|
|
1918
|
-
children2.push(
|
|
1919
|
-
leaf("path", {
|
|
1920
|
-
d: combinedPathData,
|
|
1921
|
-
fill: `url(#${patternId})`,
|
|
1922
|
-
"fill-rule": "nonzero",
|
|
1923
|
-
stroke: "none"
|
|
1924
|
-
})
|
|
1925
|
-
);
|
|
1926
|
-
}
|
|
1927
|
-
children2.push(
|
|
1776
|
+
const children2 = [
|
|
1928
1777
|
leaf("path", {
|
|
1929
1778
|
d: combinedPathData,
|
|
1930
1779
|
fill: "none",
|
|
@@ -1932,13 +1781,11 @@ var groupRenderer = {
|
|
|
1932
1781
|
stroke,
|
|
1933
1782
|
"stroke-width": String(options.strokeWidth)
|
|
1934
1783
|
})
|
|
1935
|
-
|
|
1784
|
+
];
|
|
1936
1785
|
return g({}, children2);
|
|
1937
1786
|
}
|
|
1938
1787
|
}
|
|
1939
|
-
const children = shapeChildren.map(
|
|
1940
|
-
(c) => svgForShape(c, cutSettings, options)
|
|
1941
|
-
);
|
|
1788
|
+
const children = shapeChildren.map((c) => svgForShape(c, options));
|
|
1942
1789
|
return g({ transform }, children);
|
|
1943
1790
|
}
|
|
1944
1791
|
};
|
|
@@ -1951,11 +1798,10 @@ var pathRenderer = {
|
|
|
1951
1798
|
const pts = p.verts.map((v) => apply(xform, { x: v.x, y: v.y }));
|
|
1952
1799
|
return addPts(emptyBox(), pts);
|
|
1953
1800
|
},
|
|
1954
|
-
toSvg: (p,
|
|
1801
|
+
toSvg: (p, options) => {
|
|
1955
1802
|
const xform = p.xform ? arrayToMatrix(p.xform) : identity();
|
|
1956
1803
|
const transform = matToSvg(xform);
|
|
1957
1804
|
const stroke = colorForCutIndex(p.cutIndex);
|
|
1958
|
-
const children = [];
|
|
1959
1805
|
let d = "";
|
|
1960
1806
|
for (let i = 0; i < p.prims.length; i++) {
|
|
1961
1807
|
const prim = p.prims[i];
|
|
@@ -1977,27 +1823,7 @@ var pathRenderer = {
|
|
|
1977
1823
|
if (d.length > 0 && p.isClosed) {
|
|
1978
1824
|
d += " Z";
|
|
1979
1825
|
}
|
|
1980
|
-
|
|
1981
|
-
const shouldShowFill = p.isClosed && cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1982
|
-
if (shouldShowFill && cutSetting) {
|
|
1983
|
-
const fillSettings = {
|
|
1984
|
-
interval: cutSetting.interval || 0.1,
|
|
1985
|
-
angle: cutSetting.angle || 0,
|
|
1986
|
-
crossHatch: cutSetting.crossHatch || false
|
|
1987
|
-
};
|
|
1988
|
-
const patternId = options.patternRegistry.getOrCreate(
|
|
1989
|
-
fillSettingsToPatternParams(fillSettings, stroke, options.strokeWidth)
|
|
1990
|
-
);
|
|
1991
|
-
children.push(
|
|
1992
|
-
leaf("path", {
|
|
1993
|
-
d,
|
|
1994
|
-
fill: `url(#${patternId})`,
|
|
1995
|
-
"fill-rule": "nonzero",
|
|
1996
|
-
stroke: "none"
|
|
1997
|
-
})
|
|
1998
|
-
);
|
|
1999
|
-
}
|
|
2000
|
-
children.push(
|
|
1826
|
+
return g({ transform }, [
|
|
2001
1827
|
leaf("path", {
|
|
2002
1828
|
d,
|
|
2003
1829
|
fill: "none",
|
|
@@ -2006,8 +1832,7 @@ var pathRenderer = {
|
|
|
2006
1832
|
"stroke-linecap": "round",
|
|
2007
1833
|
"stroke-linejoin": "round"
|
|
2008
1834
|
})
|
|
2009
|
-
);
|
|
2010
|
-
return g({ transform }, children);
|
|
1835
|
+
]);
|
|
2011
1836
|
}
|
|
2012
1837
|
};
|
|
2013
1838
|
|
|
@@ -2029,39 +1854,14 @@ var rectRenderer = {
|
|
|
2029
1854
|
corners.map((p) => apply(xform, p))
|
|
2030
1855
|
);
|
|
2031
1856
|
},
|
|
2032
|
-
toSvg: (rect,
|
|
1857
|
+
toSvg: (rect, options) => {
|
|
2033
1858
|
const xform = rect.xform ? arrayToMatrix(rect.xform) : identity();
|
|
2034
1859
|
const transform = matToSvg(xform);
|
|
2035
1860
|
const w = rect.w || 0;
|
|
2036
1861
|
const h = rect.h || 0;
|
|
2037
1862
|
const cr = rect.cr || 0;
|
|
2038
1863
|
const stroke = colorForCutIndex(rect.cutIndex);
|
|
2039
|
-
|
|
2040
|
-
const cutSetting = rect.cutIndex !== void 0 ? cutSettings.get(rect.cutIndex) : void 0;
|
|
2041
|
-
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
2042
|
-
if (shouldShowFill && cutSetting) {
|
|
2043
|
-
const fillSettings = {
|
|
2044
|
-
interval: cutSetting.interval || 0.1,
|
|
2045
|
-
angle: cutSetting.angle || 0,
|
|
2046
|
-
crossHatch: cutSetting.crossHatch || false
|
|
2047
|
-
};
|
|
2048
|
-
const patternId = options.patternRegistry.getOrCreate(
|
|
2049
|
-
fillSettingsToPatternParams(fillSettings, stroke, options.strokeWidth)
|
|
2050
|
-
);
|
|
2051
|
-
children.push(
|
|
2052
|
-
leaf("rect", {
|
|
2053
|
-
x: "0",
|
|
2054
|
-
y: "0",
|
|
2055
|
-
width: String(w),
|
|
2056
|
-
height: String(h),
|
|
2057
|
-
rx: String(cr),
|
|
2058
|
-
ry: String(cr),
|
|
2059
|
-
fill: `url(#${patternId})`,
|
|
2060
|
-
stroke: "none"
|
|
2061
|
-
})
|
|
2062
|
-
);
|
|
2063
|
-
}
|
|
2064
|
-
children.push(
|
|
1864
|
+
return g({ transform }, [
|
|
2065
1865
|
leaf("rect", {
|
|
2066
1866
|
x: "0",
|
|
2067
1867
|
y: "0",
|
|
@@ -2072,8 +1872,7 @@ var rectRenderer = {
|
|
|
2072
1872
|
fill: "none",
|
|
2073
1873
|
stroke
|
|
2074
1874
|
})
|
|
2075
|
-
);
|
|
2076
|
-
return g({ transform }, children);
|
|
1875
|
+
]);
|
|
2077
1876
|
}
|
|
2078
1877
|
};
|
|
2079
1878
|
|
|
@@ -2093,7 +1892,7 @@ var textRenderer = {
|
|
|
2093
1892
|
apply(xform, { x: 100, y: 50 })
|
|
2094
1893
|
]);
|
|
2095
1894
|
},
|
|
2096
|
-
toSvg: (t,
|
|
1895
|
+
toSvg: (t, _options) => {
|
|
2097
1896
|
const xform = t.xform ? arrayToMatrix(t.xform) : identity();
|
|
2098
1897
|
const transform = matToSvg(xform);
|
|
2099
1898
|
const stroke = colorForCutIndex(t.cutIndex);
|
|
@@ -2127,30 +1926,26 @@ function findRenderer(shape) {
|
|
|
2127
1926
|
function bboxOfShape(shape) {
|
|
2128
1927
|
return findRenderer(shape).bbox(shape);
|
|
2129
1928
|
}
|
|
2130
|
-
function svgForShape(shape,
|
|
2131
|
-
return findRenderer(shape).toSvg(shape,
|
|
1929
|
+
function svgForShape(shape, options) {
|
|
1930
|
+
return findRenderer(shape).toSvg(shape, options);
|
|
2132
1931
|
}
|
|
2133
1932
|
function measure(shapes) {
|
|
2134
1933
|
return shapes.reduce((acc, s) => boxUnion(acc, bboxOfShape(s)), emptyBox());
|
|
2135
1934
|
}
|
|
2136
|
-
function renderAll(shapes,
|
|
2137
|
-
return shapes.map((s) => svgForShape(s,
|
|
1935
|
+
function renderAll(shapes, options) {
|
|
1936
|
+
return shapes.map((s) => svgForShape(s, options));
|
|
2138
1937
|
}
|
|
2139
1938
|
|
|
2140
1939
|
// lib/svg-gen/index.ts
|
|
2141
1940
|
function generateLightBurnSvg(root, options) {
|
|
2142
1941
|
const shapes = collectShapes(root);
|
|
2143
|
-
const cutSettings = collectCutSettings(root);
|
|
2144
1942
|
const bbox = measure(shapes);
|
|
2145
1943
|
const layout = computeLayout(bbox, options);
|
|
2146
|
-
const patternRegistry = new HatchPatternRegistry();
|
|
2147
1944
|
const renderOptions = {
|
|
2148
|
-
strokeWidth: options?.defaultStrokeWidth ?? DEFAULT_OPTIONS.defaultStrokeWidth
|
|
2149
|
-
patternRegistry
|
|
1945
|
+
strokeWidth: options?.defaultStrokeWidth ?? DEFAULT_OPTIONS.defaultStrokeWidth
|
|
2150
1946
|
};
|
|
2151
|
-
const nodes = renderAll(shapes,
|
|
2152
|
-
const
|
|
2153
|
-
const svgTree = assembleSvg(nodes, layout, defs);
|
|
1947
|
+
const nodes = renderAll(shapes, renderOptions);
|
|
1948
|
+
const svgTree = assembleSvg(nodes, layout, []);
|
|
2154
1949
|
return stringify(svgTree);
|
|
2155
1950
|
}
|
|
2156
1951
|
export {
|