lbrnts 0.0.9 → 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 +6 -0
- package/dist/index.js +49 -26
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -361,6 +361,12 @@ declare class ShapeBitmap extends ShapeBase {
|
|
|
361
361
|
|
|
362
362
|
interface GenerateSvgOptions {
|
|
363
363
|
margin?: number;
|
|
364
|
+
/** Target width for the SVG. When provided with height, scales the output. */
|
|
365
|
+
width?: number;
|
|
366
|
+
/** Target height for the SVG. When provided with width, scales the output. */
|
|
367
|
+
height?: number;
|
|
368
|
+
/** Default stroke width for shapes in mm. */
|
|
369
|
+
defaultStrokeWidth?: number;
|
|
364
370
|
}
|
|
365
371
|
|
|
366
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
|
|
@@ -1315,16 +1316,18 @@ function computeLayout(bbox, options) {
|
|
|
1315
1316
|
const minY = Math.min(0, bbox.minY) - margin;
|
|
1316
1317
|
const maxX = Math.max(0, bbox.maxX) + margin;
|
|
1317
1318
|
const maxY = Math.max(0, bbox.maxY) + margin;
|
|
1318
|
-
const
|
|
1319
|
-
const
|
|
1320
|
-
const viewBox = `${minX} ${minY} ${
|
|
1319
|
+
const contentWidth = maxX - minX;
|
|
1320
|
+
const contentHeight = maxY - minY;
|
|
1321
|
+
const viewBox = `${minX} ${minY} ${contentWidth} ${contentHeight}`;
|
|
1321
1322
|
const flipY = maxY + minY;
|
|
1323
|
+
const width = options?.width ?? contentWidth;
|
|
1324
|
+
const height = options?.height ?? contentHeight;
|
|
1322
1325
|
return {
|
|
1323
1326
|
viewBox,
|
|
1324
1327
|
width,
|
|
1325
1328
|
height,
|
|
1326
1329
|
flipY,
|
|
1327
|
-
bg: { x: minX, y: minY, width, height }
|
|
1330
|
+
bg: { x: minX, y: minY, width: contentWidth, height: contentHeight }
|
|
1328
1331
|
};
|
|
1329
1332
|
}
|
|
1330
1333
|
|
|
@@ -1415,7 +1418,7 @@ var bitmapRenderer = {
|
|
|
1415
1418
|
corners.map((p) => apply(xform, p))
|
|
1416
1419
|
);
|
|
1417
1420
|
},
|
|
1418
|
-
toSvg: (bmp, _cutSettings) => {
|
|
1421
|
+
toSvg: (bmp, _cutSettings, _options) => {
|
|
1419
1422
|
const xform = bmp.xform ? arrayToMatrix(bmp.xform) : identity();
|
|
1420
1423
|
const transform = matToSvg(xform);
|
|
1421
1424
|
const w = bmp.w || 0;
|
|
@@ -1434,14 +1437,15 @@ var bitmapRenderer = {
|
|
|
1434
1437
|
};
|
|
1435
1438
|
|
|
1436
1439
|
// lib/svg-gen/fill-patterns.ts
|
|
1437
|
-
function generateScanLines(bbox, settings, color) {
|
|
1440
|
+
function generateScanLines(bbox, settings, color, strokeWidth) {
|
|
1438
1441
|
const lines = [];
|
|
1439
1442
|
const angleRad = settings.angle * Math.PI / 180;
|
|
1440
1443
|
const primaryLines = generateLinesAtAngle(
|
|
1441
1444
|
bbox,
|
|
1442
1445
|
settings.interval,
|
|
1443
1446
|
angleRad,
|
|
1444
|
-
color
|
|
1447
|
+
color,
|
|
1448
|
+
strokeWidth
|
|
1445
1449
|
);
|
|
1446
1450
|
lines.push(...primaryLines);
|
|
1447
1451
|
if (settings.crossHatch) {
|
|
@@ -1450,13 +1454,14 @@ function generateScanLines(bbox, settings, color) {
|
|
|
1450
1454
|
bbox,
|
|
1451
1455
|
settings.interval,
|
|
1452
1456
|
perpAngle,
|
|
1453
|
-
color
|
|
1457
|
+
color,
|
|
1458
|
+
strokeWidth
|
|
1454
1459
|
);
|
|
1455
1460
|
lines.push(...crossLines);
|
|
1456
1461
|
}
|
|
1457
1462
|
return lines;
|
|
1458
1463
|
}
|
|
1459
|
-
function generateLinesAtAngle(bbox, interval, angle, color) {
|
|
1464
|
+
function generateLinesAtAngle(bbox, interval, angle, color, strokeWidth) {
|
|
1460
1465
|
const lines = [];
|
|
1461
1466
|
const diagonal = Math.sqrt(
|
|
1462
1467
|
Math.pow(bbox.maxX - bbox.minX, 2) + Math.pow(bbox.maxY - bbox.minY, 2)
|
|
@@ -1492,7 +1497,7 @@ function generateLinesAtAngle(bbox, interval, angle, color) {
|
|
|
1492
1497
|
x2: String(clipped.x2),
|
|
1493
1498
|
y2: String(clipped.y2),
|
|
1494
1499
|
stroke: color,
|
|
1495
|
-
"stroke-width":
|
|
1500
|
+
"stroke-width": String(strokeWidth),
|
|
1496
1501
|
"stroke-opacity": "0.8"
|
|
1497
1502
|
})
|
|
1498
1503
|
);
|
|
@@ -1625,7 +1630,7 @@ var ellipseRenderer = {
|
|
|
1625
1630
|
extremes.map((p) => apply(xform, p))
|
|
1626
1631
|
);
|
|
1627
1632
|
},
|
|
1628
|
-
toSvg: (el, cutSettings) => {
|
|
1633
|
+
toSvg: (el, cutSettings, options) => {
|
|
1629
1634
|
const xform = el.xform ? arrayToMatrix(el.xform) : identity();
|
|
1630
1635
|
const transform = matToSvg(xform);
|
|
1631
1636
|
const rx = el.rx || 0;
|
|
@@ -1646,7 +1651,12 @@ var ellipseRenderer = {
|
|
|
1646
1651
|
angle: cutSetting.angle || 0,
|
|
1647
1652
|
crossHatch: cutSetting.crossHatch || false
|
|
1648
1653
|
};
|
|
1649
|
-
const fillLines = generateScanLines(
|
|
1654
|
+
const fillLines = generateScanLines(
|
|
1655
|
+
localBBox,
|
|
1656
|
+
fillSettings,
|
|
1657
|
+
stroke,
|
|
1658
|
+
options.strokeWidth
|
|
1659
|
+
);
|
|
1650
1660
|
children.push(...fillLines);
|
|
1651
1661
|
}
|
|
1652
1662
|
const child = rx === ry ? leaf("circle", {
|
|
@@ -1674,10 +1684,10 @@ var groupRenderer = {
|
|
|
1674
1684
|
bbox: (grp) => {
|
|
1675
1685
|
return grp.children.filter((c) => c instanceof ShapeBase).reduce((bb, c) => boxUnion(bb, bboxOfShape(c)), emptyBox());
|
|
1676
1686
|
},
|
|
1677
|
-
toSvg: (grp, cutSettings) => {
|
|
1687
|
+
toSvg: (grp, cutSettings, options) => {
|
|
1678
1688
|
const xform = grp.xform ? arrayToMatrix(grp.xform) : identity();
|
|
1679
1689
|
const transform = matToSvg(xform);
|
|
1680
|
-
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));
|
|
1681
1691
|
return g({ transform }, children);
|
|
1682
1692
|
}
|
|
1683
1693
|
};
|
|
@@ -1690,7 +1700,7 @@ var pathRenderer = {
|
|
|
1690
1700
|
const pts = p.verts.map((v) => apply(xform, { x: v.x, y: v.y }));
|
|
1691
1701
|
return addPts(emptyBox(), pts);
|
|
1692
1702
|
},
|
|
1693
|
-
toSvg: (p, cutSettings) => {
|
|
1703
|
+
toSvg: (p, cutSettings, options) => {
|
|
1694
1704
|
const xform = p.xform ? arrayToMatrix(p.xform) : identity();
|
|
1695
1705
|
const transform = matToSvg(xform);
|
|
1696
1706
|
const stroke = colorForCutIndex(p.cutIndex);
|
|
@@ -1728,7 +1738,12 @@ var pathRenderer = {
|
|
|
1728
1738
|
angle: cutSetting.angle || 0,
|
|
1729
1739
|
crossHatch: cutSetting.crossHatch || false
|
|
1730
1740
|
};
|
|
1731
|
-
const fillLines = generateScanLines(
|
|
1741
|
+
const fillLines = generateScanLines(
|
|
1742
|
+
bbox,
|
|
1743
|
+
fillSettings,
|
|
1744
|
+
stroke,
|
|
1745
|
+
options.strokeWidth
|
|
1746
|
+
);
|
|
1732
1747
|
const clipId = `clip-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1733
1748
|
const clipPath = {
|
|
1734
1749
|
name: "clipPath",
|
|
@@ -1752,7 +1767,7 @@ var pathRenderer = {
|
|
|
1752
1767
|
d,
|
|
1753
1768
|
fill: "none",
|
|
1754
1769
|
stroke,
|
|
1755
|
-
"stroke-width":
|
|
1770
|
+
"stroke-width": String(options.strokeWidth)
|
|
1756
1771
|
})
|
|
1757
1772
|
);
|
|
1758
1773
|
return g({ transform }, children);
|
|
@@ -1777,7 +1792,7 @@ var rectRenderer = {
|
|
|
1777
1792
|
corners.map((p) => apply(xform, p))
|
|
1778
1793
|
);
|
|
1779
1794
|
},
|
|
1780
|
-
toSvg: (rect, cutSettings) => {
|
|
1795
|
+
toSvg: (rect, cutSettings, options) => {
|
|
1781
1796
|
const xform = rect.xform ? arrayToMatrix(rect.xform) : identity();
|
|
1782
1797
|
const transform = matToSvg(xform);
|
|
1783
1798
|
const w = rect.w || 0;
|
|
@@ -1799,7 +1814,12 @@ var rectRenderer = {
|
|
|
1799
1814
|
angle: cutSetting.angle || 0,
|
|
1800
1815
|
crossHatch: cutSetting.crossHatch || false
|
|
1801
1816
|
};
|
|
1802
|
-
const fillLines = generateScanLines(
|
|
1817
|
+
const fillLines = generateScanLines(
|
|
1818
|
+
localBBox,
|
|
1819
|
+
fillSettings,
|
|
1820
|
+
stroke,
|
|
1821
|
+
options.strokeWidth
|
|
1822
|
+
);
|
|
1803
1823
|
children.push(...fillLines);
|
|
1804
1824
|
}
|
|
1805
1825
|
children.push(
|
|
@@ -1834,7 +1854,7 @@ var textRenderer = {
|
|
|
1834
1854
|
apply(xform, { x: 100, y: 50 })
|
|
1835
1855
|
]);
|
|
1836
1856
|
},
|
|
1837
|
-
toSvg: (t, _cutSettings) => {
|
|
1857
|
+
toSvg: (t, _cutSettings, _options) => {
|
|
1838
1858
|
const xform = t.xform ? arrayToMatrix(t.xform) : identity();
|
|
1839
1859
|
const transform = matToSvg(xform);
|
|
1840
1860
|
const stroke = colorForCutIndex(t.cutIndex);
|
|
@@ -1868,14 +1888,17 @@ function findRenderer(shape) {
|
|
|
1868
1888
|
function bboxOfShape(shape) {
|
|
1869
1889
|
return findRenderer(shape).bbox(shape);
|
|
1870
1890
|
}
|
|
1871
|
-
function svgForShape(shape, cutSettings) {
|
|
1872
|
-
return findRenderer(shape).toSvg(shape, cutSettings);
|
|
1891
|
+
function svgForShape(shape, cutSettings, options) {
|
|
1892
|
+
return findRenderer(shape).toSvg(shape, cutSettings, options);
|
|
1873
1893
|
}
|
|
1874
1894
|
function measure(shapes) {
|
|
1875
1895
|
return shapes.reduce((acc, s) => boxUnion(acc, bboxOfShape(s)), emptyBox());
|
|
1876
1896
|
}
|
|
1877
|
-
function renderAll(shapes, cutSettings) {
|
|
1878
|
-
|
|
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));
|
|
1879
1902
|
}
|
|
1880
1903
|
|
|
1881
1904
|
// lib/svg-gen/index.ts
|
|
@@ -1884,7 +1907,7 @@ function generateLightBurnSvg(root, options) {
|
|
|
1884
1907
|
const cutSettings = collectCutSettings(root);
|
|
1885
1908
|
const bbox = measure(shapes);
|
|
1886
1909
|
const layout = computeLayout(bbox, options);
|
|
1887
|
-
const nodes = renderAll(shapes, cutSettings);
|
|
1910
|
+
const nodes = renderAll(shapes, cutSettings, options);
|
|
1888
1911
|
const svgTree = assembleSvg(nodes, layout);
|
|
1889
1912
|
return stringify(svgTree);
|
|
1890
1913
|
}
|