lbrnts 0.0.10 → 0.0.11
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.d.ts +2 -0
- package/dist/index.js +43 -22
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -365,6 +365,8 @@ interface GenerateSvgOptions {
|
|
|
365
365
|
width?: number;
|
|
366
366
|
/** Target height for the SVG. When provided with width, scales the output. */
|
|
367
367
|
height?: number;
|
|
368
|
+
/** Default stroke width for shapes in mm. */
|
|
369
|
+
defaultStrokeWidth?: number;
|
|
368
370
|
}
|
|
369
371
|
|
|
370
372
|
declare function generateLightBurnSvg(root: LightBurnBaseElement | LightBurnBaseElement[], options?: GenerateSvgOptions): string;
|
package/dist/index.js
CHANGED
|
@@ -1301,7 +1301,8 @@ function collectCutSettings(root) {
|
|
|
1301
1301
|
|
|
1302
1302
|
// lib/svg-gen/options.ts
|
|
1303
1303
|
var DEFAULT_OPTIONS = {
|
|
1304
|
-
margin: 10
|
|
1304
|
+
margin: 10,
|
|
1305
|
+
defaultStrokeWidth: 0.1
|
|
1305
1306
|
};
|
|
1306
1307
|
|
|
1307
1308
|
// lib/svg-gen/layout.ts
|
|
@@ -1417,7 +1418,7 @@ var bitmapRenderer = {
|
|
|
1417
1418
|
corners.map((p) => apply(xform, p))
|
|
1418
1419
|
);
|
|
1419
1420
|
},
|
|
1420
|
-
toSvg: (bmp, _cutSettings) => {
|
|
1421
|
+
toSvg: (bmp, _cutSettings, _options) => {
|
|
1421
1422
|
const xform = bmp.xform ? arrayToMatrix(bmp.xform) : identity();
|
|
1422
1423
|
const transform = matToSvg(xform);
|
|
1423
1424
|
const w = bmp.w || 0;
|
|
@@ -1436,14 +1437,15 @@ var bitmapRenderer = {
|
|
|
1436
1437
|
};
|
|
1437
1438
|
|
|
1438
1439
|
// lib/svg-gen/fill-patterns.ts
|
|
1439
|
-
function generateScanLines(bbox, settings, color) {
|
|
1440
|
+
function generateScanLines(bbox, settings, color, strokeWidth) {
|
|
1440
1441
|
const lines = [];
|
|
1441
1442
|
const angleRad = settings.angle * Math.PI / 180;
|
|
1442
1443
|
const primaryLines = generateLinesAtAngle(
|
|
1443
1444
|
bbox,
|
|
1444
1445
|
settings.interval,
|
|
1445
1446
|
angleRad,
|
|
1446
|
-
color
|
|
1447
|
+
color,
|
|
1448
|
+
strokeWidth
|
|
1447
1449
|
);
|
|
1448
1450
|
lines.push(...primaryLines);
|
|
1449
1451
|
if (settings.crossHatch) {
|
|
@@ -1452,13 +1454,14 @@ function generateScanLines(bbox, settings, color) {
|
|
|
1452
1454
|
bbox,
|
|
1453
1455
|
settings.interval,
|
|
1454
1456
|
perpAngle,
|
|
1455
|
-
color
|
|
1457
|
+
color,
|
|
1458
|
+
strokeWidth
|
|
1456
1459
|
);
|
|
1457
1460
|
lines.push(...crossLines);
|
|
1458
1461
|
}
|
|
1459
1462
|
return lines;
|
|
1460
1463
|
}
|
|
1461
|
-
function generateLinesAtAngle(bbox, interval, angle, color) {
|
|
1464
|
+
function generateLinesAtAngle(bbox, interval, angle, color, strokeWidth) {
|
|
1462
1465
|
const lines = [];
|
|
1463
1466
|
const diagonal = Math.sqrt(
|
|
1464
1467
|
Math.pow(bbox.maxX - bbox.minX, 2) + Math.pow(bbox.maxY - bbox.minY, 2)
|
|
@@ -1494,7 +1497,7 @@ function generateLinesAtAngle(bbox, interval, angle, color) {
|
|
|
1494
1497
|
x2: String(clipped.x2),
|
|
1495
1498
|
y2: String(clipped.y2),
|
|
1496
1499
|
stroke: color,
|
|
1497
|
-
"stroke-width":
|
|
1500
|
+
"stroke-width": String(strokeWidth),
|
|
1498
1501
|
"stroke-opacity": "0.8"
|
|
1499
1502
|
})
|
|
1500
1503
|
);
|
|
@@ -1627,7 +1630,7 @@ var ellipseRenderer = {
|
|
|
1627
1630
|
extremes.map((p) => apply(xform, p))
|
|
1628
1631
|
);
|
|
1629
1632
|
},
|
|
1630
|
-
toSvg: (el, cutSettings) => {
|
|
1633
|
+
toSvg: (el, cutSettings, options) => {
|
|
1631
1634
|
const xform = el.xform ? arrayToMatrix(el.xform) : identity();
|
|
1632
1635
|
const transform = matToSvg(xform);
|
|
1633
1636
|
const rx = el.rx || 0;
|
|
@@ -1648,7 +1651,12 @@ var ellipseRenderer = {
|
|
|
1648
1651
|
angle: cutSetting.angle || 0,
|
|
1649
1652
|
crossHatch: cutSetting.crossHatch || false
|
|
1650
1653
|
};
|
|
1651
|
-
const fillLines = generateScanLines(
|
|
1654
|
+
const fillLines = generateScanLines(
|
|
1655
|
+
localBBox,
|
|
1656
|
+
fillSettings,
|
|
1657
|
+
stroke,
|
|
1658
|
+
options.strokeWidth
|
|
1659
|
+
);
|
|
1652
1660
|
children.push(...fillLines);
|
|
1653
1661
|
}
|
|
1654
1662
|
const child = rx === ry ? leaf("circle", {
|
|
@@ -1676,10 +1684,10 @@ var groupRenderer = {
|
|
|
1676
1684
|
bbox: (grp) => {
|
|
1677
1685
|
return grp.children.filter((c) => c instanceof ShapeBase).reduce((bb, c) => boxUnion(bb, bboxOfShape(c)), emptyBox());
|
|
1678
1686
|
},
|
|
1679
|
-
toSvg: (grp, cutSettings) => {
|
|
1687
|
+
toSvg: (grp, cutSettings, options) => {
|
|
1680
1688
|
const xform = grp.xform ? arrayToMatrix(grp.xform) : identity();
|
|
1681
1689
|
const transform = matToSvg(xform);
|
|
1682
|
-
const children = grp.children.filter((c) => c instanceof ShapeBase).map((c) => svgForShape(c, cutSettings));
|
|
1690
|
+
const children = grp.children.filter((c) => c instanceof ShapeBase).map((c) => svgForShape(c, cutSettings, options));
|
|
1683
1691
|
return g({ transform }, children);
|
|
1684
1692
|
}
|
|
1685
1693
|
};
|
|
@@ -1692,7 +1700,7 @@ var pathRenderer = {
|
|
|
1692
1700
|
const pts = p.verts.map((v) => apply(xform, { x: v.x, y: v.y }));
|
|
1693
1701
|
return addPts(emptyBox(), pts);
|
|
1694
1702
|
},
|
|
1695
|
-
toSvg: (p, cutSettings) => {
|
|
1703
|
+
toSvg: (p, cutSettings, options) => {
|
|
1696
1704
|
const xform = p.xform ? arrayToMatrix(p.xform) : identity();
|
|
1697
1705
|
const transform = matToSvg(xform);
|
|
1698
1706
|
const stroke = colorForCutIndex(p.cutIndex);
|
|
@@ -1730,7 +1738,12 @@ var pathRenderer = {
|
|
|
1730
1738
|
angle: cutSetting.angle || 0,
|
|
1731
1739
|
crossHatch: cutSetting.crossHatch || false
|
|
1732
1740
|
};
|
|
1733
|
-
const fillLines = generateScanLines(
|
|
1741
|
+
const fillLines = generateScanLines(
|
|
1742
|
+
bbox,
|
|
1743
|
+
fillSettings,
|
|
1744
|
+
stroke,
|
|
1745
|
+
options.strokeWidth
|
|
1746
|
+
);
|
|
1734
1747
|
const clipId = `clip-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1735
1748
|
const clipPath = {
|
|
1736
1749
|
name: "clipPath",
|
|
@@ -1754,7 +1767,7 @@ var pathRenderer = {
|
|
|
1754
1767
|
d,
|
|
1755
1768
|
fill: "none",
|
|
1756
1769
|
stroke,
|
|
1757
|
-
"stroke-width":
|
|
1770
|
+
"stroke-width": String(options.strokeWidth)
|
|
1758
1771
|
})
|
|
1759
1772
|
);
|
|
1760
1773
|
return g({ transform }, children);
|
|
@@ -1779,7 +1792,7 @@ var rectRenderer = {
|
|
|
1779
1792
|
corners.map((p) => apply(xform, p))
|
|
1780
1793
|
);
|
|
1781
1794
|
},
|
|
1782
|
-
toSvg: (rect, cutSettings) => {
|
|
1795
|
+
toSvg: (rect, cutSettings, options) => {
|
|
1783
1796
|
const xform = rect.xform ? arrayToMatrix(rect.xform) : identity();
|
|
1784
1797
|
const transform = matToSvg(xform);
|
|
1785
1798
|
const w = rect.w || 0;
|
|
@@ -1801,7 +1814,12 @@ var rectRenderer = {
|
|
|
1801
1814
|
angle: cutSetting.angle || 0,
|
|
1802
1815
|
crossHatch: cutSetting.crossHatch || false
|
|
1803
1816
|
};
|
|
1804
|
-
const fillLines = generateScanLines(
|
|
1817
|
+
const fillLines = generateScanLines(
|
|
1818
|
+
localBBox,
|
|
1819
|
+
fillSettings,
|
|
1820
|
+
stroke,
|
|
1821
|
+
options.strokeWidth
|
|
1822
|
+
);
|
|
1805
1823
|
children.push(...fillLines);
|
|
1806
1824
|
}
|
|
1807
1825
|
children.push(
|
|
@@ -1836,7 +1854,7 @@ var textRenderer = {
|
|
|
1836
1854
|
apply(xform, { x: 100, y: 50 })
|
|
1837
1855
|
]);
|
|
1838
1856
|
},
|
|
1839
|
-
toSvg: (t, _cutSettings) => {
|
|
1857
|
+
toSvg: (t, _cutSettings, _options) => {
|
|
1840
1858
|
const xform = t.xform ? arrayToMatrix(t.xform) : identity();
|
|
1841
1859
|
const transform = matToSvg(xform);
|
|
1842
1860
|
const stroke = colorForCutIndex(t.cutIndex);
|
|
@@ -1870,14 +1888,17 @@ function findRenderer(shape) {
|
|
|
1870
1888
|
function bboxOfShape(shape) {
|
|
1871
1889
|
return findRenderer(shape).bbox(shape);
|
|
1872
1890
|
}
|
|
1873
|
-
function svgForShape(shape, cutSettings) {
|
|
1874
|
-
return findRenderer(shape).toSvg(shape, cutSettings);
|
|
1891
|
+
function svgForShape(shape, cutSettings, options) {
|
|
1892
|
+
return findRenderer(shape).toSvg(shape, cutSettings, options);
|
|
1875
1893
|
}
|
|
1876
1894
|
function measure(shapes) {
|
|
1877
1895
|
return shapes.reduce((acc, s) => boxUnion(acc, bboxOfShape(s)), emptyBox());
|
|
1878
1896
|
}
|
|
1879
|
-
function renderAll(shapes, cutSettings) {
|
|
1880
|
-
|
|
1897
|
+
function renderAll(shapes, cutSettings, svgOptions) {
|
|
1898
|
+
const renderOptions = {
|
|
1899
|
+
strokeWidth: svgOptions?.defaultStrokeWidth ?? DEFAULT_OPTIONS.defaultStrokeWidth
|
|
1900
|
+
};
|
|
1901
|
+
return shapes.map((s) => svgForShape(s, cutSettings, renderOptions));
|
|
1881
1902
|
}
|
|
1882
1903
|
|
|
1883
1904
|
// lib/svg-gen/index.ts
|
|
@@ -1886,7 +1907,7 @@ function generateLightBurnSvg(root, options) {
|
|
|
1886
1907
|
const cutSettings = collectCutSettings(root);
|
|
1887
1908
|
const bbox = measure(shapes);
|
|
1888
1909
|
const layout = computeLayout(bbox, options);
|
|
1889
|
-
const nodes = renderAll(shapes, cutSettings);
|
|
1910
|
+
const nodes = renderAll(shapes, cutSettings, options);
|
|
1890
1911
|
const svgTree = assembleSvg(nodes, layout);
|
|
1891
1912
|
return stringify(svgTree);
|
|
1892
1913
|
}
|