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 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 width = maxX - minX;
1319
- const height = maxY - minY;
1320
- const viewBox = `${minX} ${minY} ${width} ${height}`;
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": "0.1",
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(localBBox, fillSettings, stroke);
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(bbox, fillSettings, stroke);
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": "0.1"
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(localBBox, fillSettings, stroke);
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
- return shapes.map((s) => svgForShape(s, cutSettings));
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
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "lbrnts",
3
3
  "main": "dist/index.js",
4
4
  "type": "module",
5
- "version": "0.0.9",
5
+ "version": "0.0.11",
6
6
  "files": [
7
7
  "dist"
8
8
  ],