lbrnts 0.0.7 → 0.0.9
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 +12 -0
- package/dist/index.js +269 -20
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -91,6 +91,9 @@ interface CutSettingInit {
|
|
|
91
91
|
angle?: number;
|
|
92
92
|
overScanning?: number;
|
|
93
93
|
lineAngle?: number;
|
|
94
|
+
crossHatch?: boolean;
|
|
95
|
+
frequency?: number;
|
|
96
|
+
pulseWidth?: number;
|
|
94
97
|
}
|
|
95
98
|
declare class CutSetting extends LightBurnBaseElement {
|
|
96
99
|
private _type;
|
|
@@ -115,6 +118,9 @@ declare class CutSetting extends LightBurnBaseElement {
|
|
|
115
118
|
private _angle?;
|
|
116
119
|
private _overScanning?;
|
|
117
120
|
private _lineAngle?;
|
|
121
|
+
private _crossHatch?;
|
|
122
|
+
private _frequency?;
|
|
123
|
+
private _pulseWidth?;
|
|
118
124
|
constructor(init?: CutSettingInit);
|
|
119
125
|
get type(): string;
|
|
120
126
|
set type(value: string);
|
|
@@ -160,6 +166,12 @@ declare class CutSetting extends LightBurnBaseElement {
|
|
|
160
166
|
set overScanning(value: number | undefined);
|
|
161
167
|
get lineAngle(): number | undefined;
|
|
162
168
|
set lineAngle(value: number | undefined);
|
|
169
|
+
get crossHatch(): boolean | undefined;
|
|
170
|
+
set crossHatch(value: boolean | undefined);
|
|
171
|
+
get frequency(): number | undefined;
|
|
172
|
+
set frequency(value: number | undefined);
|
|
173
|
+
get pulseWidth(): number | undefined;
|
|
174
|
+
set pulseWidth(value: number | undefined);
|
|
163
175
|
getXmlAttributes(): Record<string, string | number | boolean | undefined>;
|
|
164
176
|
getChildren(): LightBurnBaseElement[];
|
|
165
177
|
static fromXmlJson(node: XmlJsonElement): CutSetting;
|
package/dist/index.js
CHANGED
|
@@ -104,7 +104,7 @@ ${this.toXml()}`;
|
|
|
104
104
|
get [Symbol.toStringTag]() {
|
|
105
105
|
return this.getString();
|
|
106
106
|
}
|
|
107
|
-
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
107
|
+
[/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
|
|
108
108
|
return this.getString();
|
|
109
109
|
}
|
|
110
110
|
// =========================== STATIC METHODS ===========================
|
|
@@ -293,6 +293,9 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
293
293
|
_angle;
|
|
294
294
|
_overScanning;
|
|
295
295
|
_lineAngle;
|
|
296
|
+
_crossHatch;
|
|
297
|
+
_frequency;
|
|
298
|
+
_pulseWidth;
|
|
296
299
|
constructor(init) {
|
|
297
300
|
super();
|
|
298
301
|
this.token = "CutSetting";
|
|
@@ -321,6 +324,9 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
321
324
|
if (init.overScanning !== void 0)
|
|
322
325
|
this._overScanning = init.overScanning;
|
|
323
326
|
if (init.lineAngle !== void 0) this._lineAngle = init.lineAngle;
|
|
327
|
+
if (init.crossHatch !== void 0) this._crossHatch = init.crossHatch;
|
|
328
|
+
if (init.frequency !== void 0) this._frequency = init.frequency;
|
|
329
|
+
if (init.pulseWidth !== void 0) this._pulseWidth = init.pulseWidth;
|
|
324
330
|
}
|
|
325
331
|
}
|
|
326
332
|
get type() {
|
|
@@ -455,6 +461,24 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
455
461
|
set lineAngle(value) {
|
|
456
462
|
this._lineAngle = value;
|
|
457
463
|
}
|
|
464
|
+
get crossHatch() {
|
|
465
|
+
return this._crossHatch;
|
|
466
|
+
}
|
|
467
|
+
set crossHatch(value) {
|
|
468
|
+
this._crossHatch = value;
|
|
469
|
+
}
|
|
470
|
+
get frequency() {
|
|
471
|
+
return this._frequency;
|
|
472
|
+
}
|
|
473
|
+
set frequency(value) {
|
|
474
|
+
this._frequency = value;
|
|
475
|
+
}
|
|
476
|
+
get pulseWidth() {
|
|
477
|
+
return this._pulseWidth;
|
|
478
|
+
}
|
|
479
|
+
set pulseWidth(value) {
|
|
480
|
+
this._pulseWidth = value;
|
|
481
|
+
}
|
|
458
482
|
getXmlAttributes() {
|
|
459
483
|
return {
|
|
460
484
|
type: this._type
|
|
@@ -483,7 +507,10 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
483
507
|
"interval",
|
|
484
508
|
"angle",
|
|
485
509
|
"overScanning",
|
|
486
|
-
"lineAngle"
|
|
510
|
+
"lineAngle",
|
|
511
|
+
"crossHatch",
|
|
512
|
+
"frequency",
|
|
513
|
+
"pulseWidth"
|
|
487
514
|
];
|
|
488
515
|
for (const prop of props) {
|
|
489
516
|
const value = this[`_${prop}`];
|
|
@@ -523,6 +550,9 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
523
550
|
cs.angle = num(getChildValue("angle"), void 0);
|
|
524
551
|
cs.overScanning = num(getChildValue("overScanning"), void 0);
|
|
525
552
|
cs.lineAngle = num(getChildValue("lineAngle"), void 0);
|
|
553
|
+
cs.crossHatch = boolish(getChildValue("crossHatch"), void 0);
|
|
554
|
+
cs.frequency = num(getChildValue("frequency"), void 0);
|
|
555
|
+
cs.pulseWidth = num(getChildValue("pulseWidth"), void 0);
|
|
526
556
|
return cs;
|
|
527
557
|
}
|
|
528
558
|
};
|
|
@@ -535,9 +565,18 @@ var CutSettingPropertyElement = class extends LightBurnBaseElement {
|
|
|
535
565
|
this.propName = propName;
|
|
536
566
|
this.propValue = propValue;
|
|
537
567
|
}
|
|
568
|
+
formatValue(value) {
|
|
569
|
+
if (typeof value === "number") {
|
|
570
|
+
if (value !== 0 && Math.abs(value) < 1e-3) {
|
|
571
|
+
return value.toFixed(9).replace(/\.?0+$/, "");
|
|
572
|
+
}
|
|
573
|
+
return value.toString();
|
|
574
|
+
}
|
|
575
|
+
return String(value);
|
|
576
|
+
}
|
|
538
577
|
toXml(indent = 0) {
|
|
539
578
|
const indentStr = " ".repeat(indent);
|
|
540
|
-
return `${indentStr}<${this.propName} Value="${this.propValue}"/>`;
|
|
579
|
+
return `${indentStr}<${this.propName} Value="${this.formatValue(this.propValue)}"/>`;
|
|
541
580
|
}
|
|
542
581
|
};
|
|
543
582
|
LightBurnBaseElement.register("CutSetting", CutSetting);
|
|
@@ -1238,6 +1277,28 @@ function collectShapes(root) {
|
|
|
1238
1277
|
return out;
|
|
1239
1278
|
}
|
|
1240
1279
|
|
|
1280
|
+
// lib/svg-gen/collect-cut-settings.ts
|
|
1281
|
+
function collectCutSettings(root) {
|
|
1282
|
+
const settings = /* @__PURE__ */ new Map();
|
|
1283
|
+
const processElement = (el) => {
|
|
1284
|
+
if (el instanceof CutSetting && el.index !== void 0) {
|
|
1285
|
+
settings.set(el.index, el);
|
|
1286
|
+
} else if (el instanceof LightBurnProject) {
|
|
1287
|
+
for (const child of el.children) {
|
|
1288
|
+
if (child instanceof CutSetting && child.index !== void 0) {
|
|
1289
|
+
settings.set(child.index, child);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
if (Array.isArray(root)) {
|
|
1295
|
+
root.forEach(processElement);
|
|
1296
|
+
} else {
|
|
1297
|
+
processElement(root);
|
|
1298
|
+
}
|
|
1299
|
+
return settings;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1241
1302
|
// lib/svg-gen/options.ts
|
|
1242
1303
|
var DEFAULT_OPTIONS = {
|
|
1243
1304
|
margin: 10
|
|
@@ -1354,7 +1415,7 @@ var bitmapRenderer = {
|
|
|
1354
1415
|
corners.map((p) => apply(xform, p))
|
|
1355
1416
|
);
|
|
1356
1417
|
},
|
|
1357
|
-
toSvg: (bmp) => {
|
|
1418
|
+
toSvg: (bmp, _cutSettings) => {
|
|
1358
1419
|
const xform = bmp.xform ? arrayToMatrix(bmp.xform) : identity();
|
|
1359
1420
|
const transform = matToSvg(xform);
|
|
1360
1421
|
const w = bmp.w || 0;
|
|
@@ -1372,6 +1433,122 @@ var bitmapRenderer = {
|
|
|
1372
1433
|
}
|
|
1373
1434
|
};
|
|
1374
1435
|
|
|
1436
|
+
// lib/svg-gen/fill-patterns.ts
|
|
1437
|
+
function generateScanLines(bbox, settings, color) {
|
|
1438
|
+
const lines = [];
|
|
1439
|
+
const angleRad = settings.angle * Math.PI / 180;
|
|
1440
|
+
const primaryLines = generateLinesAtAngle(
|
|
1441
|
+
bbox,
|
|
1442
|
+
settings.interval,
|
|
1443
|
+
angleRad,
|
|
1444
|
+
color
|
|
1445
|
+
);
|
|
1446
|
+
lines.push(...primaryLines);
|
|
1447
|
+
if (settings.crossHatch) {
|
|
1448
|
+
const perpAngle = angleRad + Math.PI / 2;
|
|
1449
|
+
const crossLines = generateLinesAtAngle(
|
|
1450
|
+
bbox,
|
|
1451
|
+
settings.interval,
|
|
1452
|
+
perpAngle,
|
|
1453
|
+
color
|
|
1454
|
+
);
|
|
1455
|
+
lines.push(...crossLines);
|
|
1456
|
+
}
|
|
1457
|
+
return lines;
|
|
1458
|
+
}
|
|
1459
|
+
function generateLinesAtAngle(bbox, interval, angle, color) {
|
|
1460
|
+
const lines = [];
|
|
1461
|
+
const diagonal = Math.sqrt(
|
|
1462
|
+
Math.pow(bbox.maxX - bbox.minX, 2) + Math.pow(bbox.maxY - bbox.minY, 2)
|
|
1463
|
+
);
|
|
1464
|
+
const dx = Math.cos(angle);
|
|
1465
|
+
const dy = Math.sin(angle);
|
|
1466
|
+
const px = -Math.sin(angle);
|
|
1467
|
+
const py = Math.cos(angle);
|
|
1468
|
+
const cx = (bbox.minX + bbox.maxX) / 2;
|
|
1469
|
+
const cy = (bbox.minY + bbox.maxY) / 2;
|
|
1470
|
+
const numLines = Math.ceil(diagonal / interval) + 2;
|
|
1471
|
+
for (let i = -numLines / 2; i <= numLines / 2; i++) {
|
|
1472
|
+
const offset = i * interval;
|
|
1473
|
+
const startX = cx + px * offset - dx * diagonal;
|
|
1474
|
+
const startY = cy + py * offset - dy * diagonal;
|
|
1475
|
+
const endX = cx + px * offset + dx * diagonal;
|
|
1476
|
+
const endY = cy + py * offset + dy * diagonal;
|
|
1477
|
+
const clipped = clipLineToBBox(
|
|
1478
|
+
startX,
|
|
1479
|
+
startY,
|
|
1480
|
+
endX,
|
|
1481
|
+
endY,
|
|
1482
|
+
bbox.minX,
|
|
1483
|
+
bbox.minY,
|
|
1484
|
+
bbox.maxX,
|
|
1485
|
+
bbox.maxY
|
|
1486
|
+
);
|
|
1487
|
+
if (clipped) {
|
|
1488
|
+
lines.push(
|
|
1489
|
+
leaf("line", {
|
|
1490
|
+
x1: String(clipped.x1),
|
|
1491
|
+
y1: String(clipped.y1),
|
|
1492
|
+
x2: String(clipped.x2),
|
|
1493
|
+
y2: String(clipped.y2),
|
|
1494
|
+
stroke: color,
|
|
1495
|
+
"stroke-width": "0.1",
|
|
1496
|
+
"stroke-opacity": "0.8"
|
|
1497
|
+
})
|
|
1498
|
+
);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
return lines;
|
|
1502
|
+
}
|
|
1503
|
+
function clipLineToBBox(x1, y1, x2, y2, minX, minY, maxX, maxY) {
|
|
1504
|
+
const INSIDE = 0;
|
|
1505
|
+
const LEFT = 1;
|
|
1506
|
+
const RIGHT = 2;
|
|
1507
|
+
const BOTTOM = 4;
|
|
1508
|
+
const TOP = 8;
|
|
1509
|
+
function computeOutCode(x, y) {
|
|
1510
|
+
let code = INSIDE;
|
|
1511
|
+
if (x < minX) code |= LEFT;
|
|
1512
|
+
else if (x > maxX) code |= RIGHT;
|
|
1513
|
+
if (y < minY) code |= BOTTOM;
|
|
1514
|
+
else if (y > maxY) code |= TOP;
|
|
1515
|
+
return code;
|
|
1516
|
+
}
|
|
1517
|
+
let outcode1 = computeOutCode(x1, y1);
|
|
1518
|
+
let outcode2 = computeOutCode(x2, y2);
|
|
1519
|
+
while (true) {
|
|
1520
|
+
if (!(outcode1 | outcode2)) {
|
|
1521
|
+
return { x1, y1, x2, y2 };
|
|
1522
|
+
} else if (outcode1 & outcode2) {
|
|
1523
|
+
return null;
|
|
1524
|
+
}
|
|
1525
|
+
const outcodeOut = outcode1 ? outcode1 : outcode2;
|
|
1526
|
+
let x, y;
|
|
1527
|
+
if (outcodeOut & TOP) {
|
|
1528
|
+
x = x1 + (x2 - x1) * (maxY - y1) / (y2 - y1);
|
|
1529
|
+
y = maxY;
|
|
1530
|
+
} else if (outcodeOut & BOTTOM) {
|
|
1531
|
+
x = x1 + (x2 - x1) * (minY - y1) / (y2 - y1);
|
|
1532
|
+
y = minY;
|
|
1533
|
+
} else if (outcodeOut & RIGHT) {
|
|
1534
|
+
y = y1 + (y2 - y1) * (maxX - x1) / (x2 - x1);
|
|
1535
|
+
x = maxX;
|
|
1536
|
+
} else {
|
|
1537
|
+
y = y1 + (y2 - y1) * (minX - x1) / (x2 - x1);
|
|
1538
|
+
x = minX;
|
|
1539
|
+
}
|
|
1540
|
+
if (outcodeOut === outcode1) {
|
|
1541
|
+
x1 = x;
|
|
1542
|
+
y1 = y;
|
|
1543
|
+
outcode1 = computeOutCode(x1, y1);
|
|
1544
|
+
} else {
|
|
1545
|
+
x2 = x;
|
|
1546
|
+
y2 = y;
|
|
1547
|
+
outcode2 = computeOutCode(x2, y2);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1375
1552
|
// lib/svg-gen/palette.ts
|
|
1376
1553
|
var LIGHTBURN_COLORS = {
|
|
1377
1554
|
0: "#000000",
|
|
@@ -1448,12 +1625,30 @@ var ellipseRenderer = {
|
|
|
1448
1625
|
extremes.map((p) => apply(xform, p))
|
|
1449
1626
|
);
|
|
1450
1627
|
},
|
|
1451
|
-
toSvg: (el) => {
|
|
1628
|
+
toSvg: (el, cutSettings) => {
|
|
1452
1629
|
const xform = el.xform ? arrayToMatrix(el.xform) : identity();
|
|
1453
1630
|
const transform = matToSvg(xform);
|
|
1454
1631
|
const rx = el.rx || 0;
|
|
1455
1632
|
const ry = el.ry || 0;
|
|
1456
1633
|
const stroke = colorForCutIndex(el.cutIndex);
|
|
1634
|
+
const children = [];
|
|
1635
|
+
const cutSetting = el.cutIndex !== void 0 ? cutSettings.get(el.cutIndex) : void 0;
|
|
1636
|
+
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1637
|
+
if (shouldShowFill && cutSetting) {
|
|
1638
|
+
const localBBox = {
|
|
1639
|
+
minX: -rx,
|
|
1640
|
+
minY: -ry,
|
|
1641
|
+
maxX: rx,
|
|
1642
|
+
maxY: ry
|
|
1643
|
+
};
|
|
1644
|
+
const fillSettings = {
|
|
1645
|
+
interval: cutSetting.interval || 0.1,
|
|
1646
|
+
angle: cutSetting.angle || 0,
|
|
1647
|
+
crossHatch: cutSetting.crossHatch || false
|
|
1648
|
+
};
|
|
1649
|
+
const fillLines = generateScanLines(localBBox, fillSettings, stroke);
|
|
1650
|
+
children.push(...fillLines);
|
|
1651
|
+
}
|
|
1457
1652
|
const child = rx === ry ? leaf("circle", {
|
|
1458
1653
|
cx: "0",
|
|
1459
1654
|
cy: "0",
|
|
@@ -1468,7 +1663,8 @@ var ellipseRenderer = {
|
|
|
1468
1663
|
fill: "none",
|
|
1469
1664
|
stroke
|
|
1470
1665
|
});
|
|
1471
|
-
|
|
1666
|
+
children.push(child);
|
|
1667
|
+
return g({ transform }, children);
|
|
1472
1668
|
}
|
|
1473
1669
|
};
|
|
1474
1670
|
|
|
@@ -1478,10 +1674,10 @@ var groupRenderer = {
|
|
|
1478
1674
|
bbox: (grp) => {
|
|
1479
1675
|
return grp.children.filter((c) => c instanceof ShapeBase).reduce((bb, c) => boxUnion(bb, bboxOfShape(c)), emptyBox());
|
|
1480
1676
|
},
|
|
1481
|
-
toSvg: (grp) => {
|
|
1677
|
+
toSvg: (grp, cutSettings) => {
|
|
1482
1678
|
const xform = grp.xform ? arrayToMatrix(grp.xform) : identity();
|
|
1483
1679
|
const transform = matToSvg(xform);
|
|
1484
|
-
const children = grp.children.filter((c) => c instanceof ShapeBase).map(svgForShape);
|
|
1680
|
+
const children = grp.children.filter((c) => c instanceof ShapeBase).map((c) => svgForShape(c, cutSettings));
|
|
1485
1681
|
return g({ transform }, children);
|
|
1486
1682
|
}
|
|
1487
1683
|
};
|
|
@@ -1494,10 +1690,11 @@ var pathRenderer = {
|
|
|
1494
1690
|
const pts = p.verts.map((v) => apply(xform, { x: v.x, y: v.y }));
|
|
1495
1691
|
return addPts(emptyBox(), pts);
|
|
1496
1692
|
},
|
|
1497
|
-
toSvg: (p) => {
|
|
1693
|
+
toSvg: (p, cutSettings) => {
|
|
1498
1694
|
const xform = p.xform ? arrayToMatrix(p.xform) : identity();
|
|
1499
1695
|
const transform = matToSvg(xform);
|
|
1500
1696
|
const stroke = colorForCutIndex(p.cutIndex);
|
|
1697
|
+
const children = [];
|
|
1501
1698
|
let d = "";
|
|
1502
1699
|
for (let i = 0; i < p.prims.length; i++) {
|
|
1503
1700
|
const prim = p.prims[i];
|
|
@@ -1519,14 +1716,46 @@ var pathRenderer = {
|
|
|
1519
1716
|
if (d.length > 0 && p.isClosed) {
|
|
1520
1717
|
d += " Z";
|
|
1521
1718
|
}
|
|
1522
|
-
|
|
1719
|
+
const cutSetting = p.cutIndex !== void 0 ? cutSettings.get(p.cutIndex) : void 0;
|
|
1720
|
+
const shouldShowFill = p.isClosed && cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1721
|
+
if (shouldShowFill && cutSetting) {
|
|
1722
|
+
const bbox = addPts(
|
|
1723
|
+
emptyBox(),
|
|
1724
|
+
p.verts.map((v) => ({ x: v.x, y: v.y }))
|
|
1725
|
+
);
|
|
1726
|
+
const fillSettings = {
|
|
1727
|
+
interval: cutSetting.interval || 0.1,
|
|
1728
|
+
angle: cutSetting.angle || 0,
|
|
1729
|
+
crossHatch: cutSetting.crossHatch || false
|
|
1730
|
+
};
|
|
1731
|
+
const fillLines = generateScanLines(bbox, fillSettings, stroke);
|
|
1732
|
+
const clipId = `clip-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
1733
|
+
const clipPath = {
|
|
1734
|
+
name: "clipPath",
|
|
1735
|
+
type: "element",
|
|
1736
|
+
value: "",
|
|
1737
|
+
attributes: { id: clipId },
|
|
1738
|
+
children: [leaf("path", { d })]
|
|
1739
|
+
};
|
|
1740
|
+
const clippedGroup = {
|
|
1741
|
+
name: "g",
|
|
1742
|
+
type: "element",
|
|
1743
|
+
value: "",
|
|
1744
|
+
attributes: { "clip-path": `url(#${clipId})` },
|
|
1745
|
+
children: fillLines
|
|
1746
|
+
};
|
|
1747
|
+
children.push(clipPath);
|
|
1748
|
+
children.push(clippedGroup);
|
|
1749
|
+
}
|
|
1750
|
+
children.push(
|
|
1523
1751
|
leaf("path", {
|
|
1524
1752
|
d,
|
|
1525
1753
|
fill: "none",
|
|
1526
1754
|
stroke,
|
|
1527
1755
|
"stroke-width": "0.1"
|
|
1528
1756
|
})
|
|
1529
|
-
|
|
1757
|
+
);
|
|
1758
|
+
return g({ transform }, children);
|
|
1530
1759
|
}
|
|
1531
1760
|
};
|
|
1532
1761
|
|
|
@@ -1548,14 +1777,32 @@ var rectRenderer = {
|
|
|
1548
1777
|
corners.map((p) => apply(xform, p))
|
|
1549
1778
|
);
|
|
1550
1779
|
},
|
|
1551
|
-
toSvg: (rect) => {
|
|
1780
|
+
toSvg: (rect, cutSettings) => {
|
|
1552
1781
|
const xform = rect.xform ? arrayToMatrix(rect.xform) : identity();
|
|
1553
1782
|
const transform = matToSvg(xform);
|
|
1554
1783
|
const w = rect.w || 0;
|
|
1555
1784
|
const h = rect.h || 0;
|
|
1556
1785
|
const cr = rect.cr || 0;
|
|
1557
1786
|
const stroke = colorForCutIndex(rect.cutIndex);
|
|
1558
|
-
|
|
1787
|
+
const children = [];
|
|
1788
|
+
const cutSetting = rect.cutIndex !== void 0 ? cutSettings.get(rect.cutIndex) : void 0;
|
|
1789
|
+
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1790
|
+
if (shouldShowFill && cutSetting) {
|
|
1791
|
+
const localBBox = {
|
|
1792
|
+
minX: 0,
|
|
1793
|
+
minY: 0,
|
|
1794
|
+
maxX: w,
|
|
1795
|
+
maxY: h
|
|
1796
|
+
};
|
|
1797
|
+
const fillSettings = {
|
|
1798
|
+
interval: cutSetting.interval || 0.1,
|
|
1799
|
+
angle: cutSetting.angle || 0,
|
|
1800
|
+
crossHatch: cutSetting.crossHatch || false
|
|
1801
|
+
};
|
|
1802
|
+
const fillLines = generateScanLines(localBBox, fillSettings, stroke);
|
|
1803
|
+
children.push(...fillLines);
|
|
1804
|
+
}
|
|
1805
|
+
children.push(
|
|
1559
1806
|
leaf("rect", {
|
|
1560
1807
|
x: "0",
|
|
1561
1808
|
y: "0",
|
|
@@ -1566,7 +1813,8 @@ var rectRenderer = {
|
|
|
1566
1813
|
fill: "none",
|
|
1567
1814
|
stroke
|
|
1568
1815
|
})
|
|
1569
|
-
|
|
1816
|
+
);
|
|
1817
|
+
return g({ transform }, children);
|
|
1570
1818
|
}
|
|
1571
1819
|
};
|
|
1572
1820
|
|
|
@@ -1586,7 +1834,7 @@ var textRenderer = {
|
|
|
1586
1834
|
apply(xform, { x: 100, y: 50 })
|
|
1587
1835
|
]);
|
|
1588
1836
|
},
|
|
1589
|
-
toSvg: (t) => {
|
|
1837
|
+
toSvg: (t, _cutSettings) => {
|
|
1590
1838
|
const xform = t.xform ? arrayToMatrix(t.xform) : identity();
|
|
1591
1839
|
const transform = matToSvg(xform);
|
|
1592
1840
|
const stroke = colorForCutIndex(t.cutIndex);
|
|
@@ -1620,22 +1868,23 @@ function findRenderer(shape) {
|
|
|
1620
1868
|
function bboxOfShape(shape) {
|
|
1621
1869
|
return findRenderer(shape).bbox(shape);
|
|
1622
1870
|
}
|
|
1623
|
-
function svgForShape(shape) {
|
|
1624
|
-
return findRenderer(shape).toSvg(shape);
|
|
1871
|
+
function svgForShape(shape, cutSettings) {
|
|
1872
|
+
return findRenderer(shape).toSvg(shape, cutSettings);
|
|
1625
1873
|
}
|
|
1626
1874
|
function measure(shapes) {
|
|
1627
1875
|
return shapes.reduce((acc, s) => boxUnion(acc, bboxOfShape(s)), emptyBox());
|
|
1628
1876
|
}
|
|
1629
|
-
function renderAll(shapes) {
|
|
1630
|
-
return shapes.map(svgForShape);
|
|
1877
|
+
function renderAll(shapes, cutSettings) {
|
|
1878
|
+
return shapes.map((s) => svgForShape(s, cutSettings));
|
|
1631
1879
|
}
|
|
1632
1880
|
|
|
1633
1881
|
// lib/svg-gen/index.ts
|
|
1634
1882
|
function generateLightBurnSvg(root, options) {
|
|
1635
1883
|
const shapes = collectShapes(root);
|
|
1884
|
+
const cutSettings = collectCutSettings(root);
|
|
1636
1885
|
const bbox = measure(shapes);
|
|
1637
1886
|
const layout = computeLayout(bbox, options);
|
|
1638
|
-
const nodes = renderAll(shapes);
|
|
1887
|
+
const nodes = renderAll(shapes, cutSettings);
|
|
1639
1888
|
const svgTree = assembleSvg(nodes, layout);
|
|
1640
1889
|
return stringify(svgTree);
|
|
1641
1890
|
}
|