lbrnts 0.0.15 → 0.0.17
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 +4 -4
- package/dist/index.js +209 -266
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -93,7 +93,7 @@ interface CutSettingInit {
|
|
|
93
93
|
lineAngle?: number;
|
|
94
94
|
crossHatch?: boolean;
|
|
95
95
|
frequency?: number;
|
|
96
|
-
|
|
96
|
+
qPulseWidth?: number;
|
|
97
97
|
}
|
|
98
98
|
declare class CutSetting extends LightBurnBaseElement {
|
|
99
99
|
private _type;
|
|
@@ -120,7 +120,7 @@ declare class CutSetting extends LightBurnBaseElement {
|
|
|
120
120
|
private _lineAngle?;
|
|
121
121
|
private _crossHatch?;
|
|
122
122
|
private _frequency?;
|
|
123
|
-
private
|
|
123
|
+
private _qPulseWidth?;
|
|
124
124
|
constructor(init?: CutSettingInit);
|
|
125
125
|
get type(): string;
|
|
126
126
|
set type(value: string);
|
|
@@ -170,8 +170,8 @@ declare class CutSetting extends LightBurnBaseElement {
|
|
|
170
170
|
set crossHatch(value: boolean | undefined);
|
|
171
171
|
get frequency(): number | undefined;
|
|
172
172
|
set frequency(value: number | undefined);
|
|
173
|
-
get
|
|
174
|
-
set
|
|
173
|
+
get qPulseWidth(): number | undefined;
|
|
174
|
+
set qPulseWidth(value: number | undefined);
|
|
175
175
|
getXmlAttributes(): Record<string, string | number | boolean | undefined>;
|
|
176
176
|
getChildren(): LightBurnBaseElement[];
|
|
177
177
|
static fromXmlJson(node: XmlJsonElement): CutSetting;
|
package/dist/index.js
CHANGED
|
@@ -295,7 +295,7 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
295
295
|
_lineAngle;
|
|
296
296
|
_crossHatch;
|
|
297
297
|
_frequency;
|
|
298
|
-
|
|
298
|
+
_qPulseWidth;
|
|
299
299
|
constructor(init) {
|
|
300
300
|
super();
|
|
301
301
|
this.token = "CutSetting";
|
|
@@ -326,7 +326,7 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
326
326
|
if (init.lineAngle !== void 0) this._lineAngle = init.lineAngle;
|
|
327
327
|
if (init.crossHatch !== void 0) this._crossHatch = init.crossHatch;
|
|
328
328
|
if (init.frequency !== void 0) this._frequency = init.frequency;
|
|
329
|
-
if (init.
|
|
329
|
+
if (init.qPulseWidth !== void 0) this._qPulseWidth = init.qPulseWidth;
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
332
|
get type() {
|
|
@@ -473,11 +473,11 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
473
473
|
set frequency(value) {
|
|
474
474
|
this._frequency = value;
|
|
475
475
|
}
|
|
476
|
-
get
|
|
477
|
-
return this.
|
|
476
|
+
get qPulseWidth() {
|
|
477
|
+
return this._qPulseWidth;
|
|
478
478
|
}
|
|
479
|
-
set
|
|
480
|
-
this.
|
|
479
|
+
set qPulseWidth(value) {
|
|
480
|
+
this._qPulseWidth = value;
|
|
481
481
|
}
|
|
482
482
|
getXmlAttributes() {
|
|
483
483
|
return {
|
|
@@ -510,7 +510,7 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
510
510
|
"lineAngle",
|
|
511
511
|
"crossHatch",
|
|
512
512
|
"frequency",
|
|
513
|
-
"
|
|
513
|
+
"qPulseWidth"
|
|
514
514
|
];
|
|
515
515
|
for (const prop of props) {
|
|
516
516
|
const value = this[`_${prop}`];
|
|
@@ -552,7 +552,7 @@ var CutSetting = class _CutSetting extends LightBurnBaseElement {
|
|
|
552
552
|
cs.lineAngle = num(getChildValue("lineAngle"), void 0);
|
|
553
553
|
cs.crossHatch = boolish(getChildValue("crossHatch"), void 0);
|
|
554
554
|
cs.frequency = num(getChildValue("frequency"), void 0);
|
|
555
|
-
cs.
|
|
555
|
+
cs.qPulseWidth = num(getChildValue("QPulseWidth"), void 0);
|
|
556
556
|
return cs;
|
|
557
557
|
}
|
|
558
558
|
};
|
|
@@ -579,7 +579,8 @@ var CutSettingPropertyElement = class extends LightBurnBaseElement {
|
|
|
579
579
|
}
|
|
580
580
|
toXml(indent = 0) {
|
|
581
581
|
const indentStr = " ".repeat(indent);
|
|
582
|
-
|
|
582
|
+
const tagName = this.propName === "qPulseWidth" ? "QPulseWidth" : this.propName;
|
|
583
|
+
return `${indentStr}<${tagName} Value="${this.formatValue(this.propValue)}"/>`;
|
|
583
584
|
}
|
|
584
585
|
};
|
|
585
586
|
LightBurnBaseElement.register("CutSetting", CutSetting);
|
|
@@ -1255,7 +1256,39 @@ LightBurnBaseElement.register("Shape.Bitmap", ShapeBitmap);
|
|
|
1255
1256
|
import { stringify } from "svgson";
|
|
1256
1257
|
|
|
1257
1258
|
// lib/svg-gen/assemble.ts
|
|
1258
|
-
function assembleSvg(children, layout) {
|
|
1259
|
+
function assembleSvg(children, layout, defs) {
|
|
1260
|
+
const svgChildren = [];
|
|
1261
|
+
if (defs && defs.length > 0) {
|
|
1262
|
+
svgChildren.push({
|
|
1263
|
+
name: "defs",
|
|
1264
|
+
type: "element",
|
|
1265
|
+
value: "",
|
|
1266
|
+
attributes: {},
|
|
1267
|
+
children: defs
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
svgChildren.push({
|
|
1271
|
+
name: "rect",
|
|
1272
|
+
type: "element",
|
|
1273
|
+
value: "",
|
|
1274
|
+
attributes: {
|
|
1275
|
+
x: String(layout.bg.x),
|
|
1276
|
+
y: String(layout.bg.y),
|
|
1277
|
+
width: String(layout.bg.width),
|
|
1278
|
+
height: String(layout.bg.height),
|
|
1279
|
+
fill: "white"
|
|
1280
|
+
},
|
|
1281
|
+
children: []
|
|
1282
|
+
});
|
|
1283
|
+
svgChildren.push({
|
|
1284
|
+
name: "g",
|
|
1285
|
+
type: "element",
|
|
1286
|
+
value: "",
|
|
1287
|
+
attributes: {
|
|
1288
|
+
transform: `matrix(1 0 0 -1 0 ${layout.flipY})`
|
|
1289
|
+
},
|
|
1290
|
+
children
|
|
1291
|
+
});
|
|
1259
1292
|
return {
|
|
1260
1293
|
name: "svg",
|
|
1261
1294
|
type: "element",
|
|
@@ -1267,30 +1300,7 @@ function assembleSvg(children, layout) {
|
|
|
1267
1300
|
viewBox: layout.viewBox,
|
|
1268
1301
|
style: "background-color: white;"
|
|
1269
1302
|
},
|
|
1270
|
-
children:
|
|
1271
|
-
{
|
|
1272
|
-
name: "rect",
|
|
1273
|
-
type: "element",
|
|
1274
|
-
value: "",
|
|
1275
|
-
attributes: {
|
|
1276
|
-
x: String(layout.bg.x),
|
|
1277
|
-
y: String(layout.bg.y),
|
|
1278
|
-
width: String(layout.bg.width),
|
|
1279
|
-
height: String(layout.bg.height),
|
|
1280
|
-
fill: "white"
|
|
1281
|
-
},
|
|
1282
|
-
children: []
|
|
1283
|
-
},
|
|
1284
|
-
{
|
|
1285
|
-
name: "g",
|
|
1286
|
-
type: "element",
|
|
1287
|
-
value: "",
|
|
1288
|
-
attributes: {
|
|
1289
|
-
transform: `matrix(1 0 0 -1 0 ${layout.flipY})`
|
|
1290
|
-
},
|
|
1291
|
-
children
|
|
1292
|
-
}
|
|
1293
|
-
]
|
|
1303
|
+
children: svgChildren
|
|
1294
1304
|
};
|
|
1295
1305
|
}
|
|
1296
1306
|
|
|
@@ -1334,6 +1344,104 @@ function collectCutSettings(root) {
|
|
|
1334
1344
|
return settings;
|
|
1335
1345
|
}
|
|
1336
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
|
+
|
|
1337
1445
|
// lib/svg-gen/options.ts
|
|
1338
1446
|
var DEFAULT_OPTIONS = {
|
|
1339
1447
|
margin: 10,
|
|
@@ -1415,29 +1523,6 @@ function addPts(bb, pts) {
|
|
|
1415
1523
|
return bb;
|
|
1416
1524
|
}
|
|
1417
1525
|
|
|
1418
|
-
// lib/svg-gen/node-helpers.ts
|
|
1419
|
-
var g = (attrs, children = []) => ({
|
|
1420
|
-
name: "g",
|
|
1421
|
-
type: "element",
|
|
1422
|
-
value: "",
|
|
1423
|
-
attributes: attrs,
|
|
1424
|
-
children
|
|
1425
|
-
});
|
|
1426
|
-
var leaf = (name, attrs) => ({
|
|
1427
|
-
name,
|
|
1428
|
-
type: "element",
|
|
1429
|
-
value: "",
|
|
1430
|
-
attributes: attrs,
|
|
1431
|
-
children: []
|
|
1432
|
-
});
|
|
1433
|
-
var textNode = (value) => ({
|
|
1434
|
-
name: "",
|
|
1435
|
-
type: "text",
|
|
1436
|
-
value,
|
|
1437
|
-
attributes: {},
|
|
1438
|
-
children: []
|
|
1439
|
-
});
|
|
1440
|
-
|
|
1441
1526
|
// lib/svg-gen/registry/shape-bitmap.ts
|
|
1442
1527
|
var bitmapRenderer = {
|
|
1443
1528
|
match: (s) => s instanceof ShapeBitmap,
|
|
@@ -1474,124 +1559,6 @@ var bitmapRenderer = {
|
|
|
1474
1559
|
}
|
|
1475
1560
|
};
|
|
1476
1561
|
|
|
1477
|
-
// lib/svg-gen/fill-patterns.ts
|
|
1478
|
-
function generateScanLines(bbox, settings, color, strokeWidth) {
|
|
1479
|
-
const lines = [];
|
|
1480
|
-
const angleRad = settings.angle * Math.PI / 180;
|
|
1481
|
-
const primaryLines = generateLinesAtAngle(
|
|
1482
|
-
bbox,
|
|
1483
|
-
settings.interval,
|
|
1484
|
-
angleRad,
|
|
1485
|
-
color,
|
|
1486
|
-
strokeWidth
|
|
1487
|
-
);
|
|
1488
|
-
lines.push(...primaryLines);
|
|
1489
|
-
if (settings.crossHatch) {
|
|
1490
|
-
const perpAngle = angleRad + Math.PI / 2;
|
|
1491
|
-
const crossLines = generateLinesAtAngle(
|
|
1492
|
-
bbox,
|
|
1493
|
-
settings.interval,
|
|
1494
|
-
perpAngle,
|
|
1495
|
-
color,
|
|
1496
|
-
strokeWidth
|
|
1497
|
-
);
|
|
1498
|
-
lines.push(...crossLines);
|
|
1499
|
-
}
|
|
1500
|
-
return lines;
|
|
1501
|
-
}
|
|
1502
|
-
function generateLinesAtAngle(bbox, interval, angle, color, strokeWidth) {
|
|
1503
|
-
const lines = [];
|
|
1504
|
-
const diagonal = Math.sqrt(
|
|
1505
|
-
Math.pow(bbox.maxX - bbox.minX, 2) + Math.pow(bbox.maxY - bbox.minY, 2)
|
|
1506
|
-
);
|
|
1507
|
-
const dx = Math.cos(angle);
|
|
1508
|
-
const dy = Math.sin(angle);
|
|
1509
|
-
const px = -Math.sin(angle);
|
|
1510
|
-
const py = Math.cos(angle);
|
|
1511
|
-
const cx = (bbox.minX + bbox.maxX) / 2;
|
|
1512
|
-
const cy = (bbox.minY + bbox.maxY) / 2;
|
|
1513
|
-
const numLines = Math.ceil(diagonal / interval) + 2;
|
|
1514
|
-
for (let i = -numLines / 2; i <= numLines / 2; i++) {
|
|
1515
|
-
const offset = i * interval;
|
|
1516
|
-
const startX = cx + px * offset - dx * diagonal;
|
|
1517
|
-
const startY = cy + py * offset - dy * diagonal;
|
|
1518
|
-
const endX = cx + px * offset + dx * diagonal;
|
|
1519
|
-
const endY = cy + py * offset + dy * diagonal;
|
|
1520
|
-
const clipped = clipLineToBBox(
|
|
1521
|
-
startX,
|
|
1522
|
-
startY,
|
|
1523
|
-
endX,
|
|
1524
|
-
endY,
|
|
1525
|
-
bbox.minX,
|
|
1526
|
-
bbox.minY,
|
|
1527
|
-
bbox.maxX,
|
|
1528
|
-
bbox.maxY
|
|
1529
|
-
);
|
|
1530
|
-
if (clipped) {
|
|
1531
|
-
lines.push(
|
|
1532
|
-
leaf("line", {
|
|
1533
|
-
x1: String(clipped.x1),
|
|
1534
|
-
y1: String(clipped.y1),
|
|
1535
|
-
x2: String(clipped.x2),
|
|
1536
|
-
y2: String(clipped.y2),
|
|
1537
|
-
stroke: color,
|
|
1538
|
-
"stroke-width": String(strokeWidth),
|
|
1539
|
-
"stroke-opacity": "0.8"
|
|
1540
|
-
})
|
|
1541
|
-
);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
return lines;
|
|
1545
|
-
}
|
|
1546
|
-
function clipLineToBBox(x1, y1, x2, y2, minX, minY, maxX, maxY) {
|
|
1547
|
-
const INSIDE = 0;
|
|
1548
|
-
const LEFT = 1;
|
|
1549
|
-
const RIGHT = 2;
|
|
1550
|
-
const BOTTOM = 4;
|
|
1551
|
-
const TOP = 8;
|
|
1552
|
-
function computeOutCode(x, y) {
|
|
1553
|
-
let code = INSIDE;
|
|
1554
|
-
if (x < minX) code |= LEFT;
|
|
1555
|
-
else if (x > maxX) code |= RIGHT;
|
|
1556
|
-
if (y < minY) code |= BOTTOM;
|
|
1557
|
-
else if (y > maxY) code |= TOP;
|
|
1558
|
-
return code;
|
|
1559
|
-
}
|
|
1560
|
-
let outcode1 = computeOutCode(x1, y1);
|
|
1561
|
-
let outcode2 = computeOutCode(x2, y2);
|
|
1562
|
-
while (true) {
|
|
1563
|
-
if (!(outcode1 | outcode2)) {
|
|
1564
|
-
return { x1, y1, x2, y2 };
|
|
1565
|
-
} else if (outcode1 & outcode2) {
|
|
1566
|
-
return null;
|
|
1567
|
-
}
|
|
1568
|
-
const outcodeOut = outcode1 ? outcode1 : outcode2;
|
|
1569
|
-
let x, y;
|
|
1570
|
-
if (outcodeOut & TOP) {
|
|
1571
|
-
x = x1 + (x2 - x1) * (maxY - y1) / (y2 - y1);
|
|
1572
|
-
y = maxY;
|
|
1573
|
-
} else if (outcodeOut & BOTTOM) {
|
|
1574
|
-
x = x1 + (x2 - x1) * (minY - y1) / (y2 - y1);
|
|
1575
|
-
y = minY;
|
|
1576
|
-
} else if (outcodeOut & RIGHT) {
|
|
1577
|
-
y = y1 + (y2 - y1) * (maxX - x1) / (x2 - x1);
|
|
1578
|
-
x = maxX;
|
|
1579
|
-
} else {
|
|
1580
|
-
y = y1 + (y2 - y1) * (minX - x1) / (x2 - x1);
|
|
1581
|
-
x = minX;
|
|
1582
|
-
}
|
|
1583
|
-
if (outcodeOut === outcode1) {
|
|
1584
|
-
x1 = x;
|
|
1585
|
-
y1 = y;
|
|
1586
|
-
outcode1 = computeOutCode(x1, y1);
|
|
1587
|
-
} else {
|
|
1588
|
-
x2 = x;
|
|
1589
|
-
y2 = y;
|
|
1590
|
-
outcode2 = computeOutCode(x2, y2);
|
|
1591
|
-
}
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
|
|
1595
1562
|
// lib/svg-gen/palette.ts
|
|
1596
1563
|
var LIGHTBURN_COLORS = {
|
|
1597
1564
|
0: "#000000",
|
|
@@ -1678,26 +1645,31 @@ var ellipseRenderer = {
|
|
|
1678
1645
|
const cutSetting = el.cutIndex !== void 0 ? cutSettings.get(el.cutIndex) : void 0;
|
|
1679
1646
|
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1680
1647
|
if (shouldShowFill && cutSetting) {
|
|
1681
|
-
const localBBox = {
|
|
1682
|
-
minX: -rx,
|
|
1683
|
-
minY: -ry,
|
|
1684
|
-
maxX: rx,
|
|
1685
|
-
maxY: ry
|
|
1686
|
-
};
|
|
1687
1648
|
const fillSettings = {
|
|
1688
1649
|
interval: cutSetting.interval || 0.1,
|
|
1689
1650
|
angle: cutSetting.angle || 0,
|
|
1690
1651
|
crossHatch: cutSetting.crossHatch || false
|
|
1691
1652
|
};
|
|
1692
|
-
const
|
|
1693
|
-
|
|
1694
|
-
fillSettings,
|
|
1695
|
-
stroke,
|
|
1696
|
-
options.strokeWidth
|
|
1653
|
+
const patternId = options.patternRegistry.getOrCreate(
|
|
1654
|
+
fillSettingsToPatternParams(fillSettings, stroke, options.strokeWidth)
|
|
1697
1655
|
);
|
|
1698
|
-
|
|
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);
|
|
1699
1671
|
}
|
|
1700
|
-
const
|
|
1672
|
+
const outlineChild = rx === ry ? leaf("circle", {
|
|
1701
1673
|
cx: "0",
|
|
1702
1674
|
cy: "0",
|
|
1703
1675
|
r: String(rx),
|
|
@@ -1711,7 +1683,7 @@ var ellipseRenderer = {
|
|
|
1711
1683
|
fill: "none",
|
|
1712
1684
|
stroke
|
|
1713
1685
|
});
|
|
1714
|
-
children.push(
|
|
1686
|
+
children.push(outlineChild);
|
|
1715
1687
|
return g({ transform }, children);
|
|
1716
1688
|
}
|
|
1717
1689
|
};
|
|
@@ -1931,44 +1903,26 @@ var groupRenderer = {
|
|
|
1931
1903
|
const cutSetting = cutIndex !== void 0 ? cutSettings.get(cutIndex) : void 0;
|
|
1932
1904
|
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
1933
1905
|
if (shouldShowFill && cutSetting) {
|
|
1934
|
-
const bbox = shapeChildren.reduce(
|
|
1935
|
-
(bb, c) => boxUnion(bb, bboxOfShape(c)),
|
|
1936
|
-
emptyBox()
|
|
1937
|
-
);
|
|
1938
1906
|
const fillSettings = {
|
|
1939
1907
|
interval: cutSetting.interval || 0.1,
|
|
1940
1908
|
angle: cutSetting.angle || 0,
|
|
1941
1909
|
crossHatch: cutSetting.crossHatch || false
|
|
1942
1910
|
};
|
|
1943
|
-
const
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
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
|
+
})
|
|
1948
1925
|
);
|
|
1949
|
-
const clipId = `clip-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
1950
|
-
const clipPath = {
|
|
1951
|
-
name: "clipPath",
|
|
1952
|
-
type: "element",
|
|
1953
|
-
value: "",
|
|
1954
|
-
attributes: { id: clipId },
|
|
1955
|
-
children: [
|
|
1956
|
-
leaf("path", {
|
|
1957
|
-
d: combinedPathData,
|
|
1958
|
-
"fill-rule": "nonzero",
|
|
1959
|
-
"clip-rule": "nonzero"
|
|
1960
|
-
})
|
|
1961
|
-
]
|
|
1962
|
-
};
|
|
1963
|
-
const clippedGroup = {
|
|
1964
|
-
name: "g",
|
|
1965
|
-
type: "element",
|
|
1966
|
-
value: "",
|
|
1967
|
-
attributes: { "clip-path": `url(#${clipId})` },
|
|
1968
|
-
children: fillLines
|
|
1969
|
-
};
|
|
1970
|
-
children2.push(clipPath);
|
|
1971
|
-
children2.push(clippedGroup);
|
|
1972
1926
|
}
|
|
1973
1927
|
children2.push(
|
|
1974
1928
|
leaf("path", {
|
|
@@ -2026,38 +1980,22 @@ var pathRenderer = {
|
|
|
2026
1980
|
const cutSetting = p.cutIndex !== void 0 ? cutSettings.get(p.cutIndex) : void 0;
|
|
2027
1981
|
const shouldShowFill = p.isClosed && cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
2028
1982
|
if (shouldShowFill && cutSetting) {
|
|
2029
|
-
const bbox = addPts(
|
|
2030
|
-
emptyBox(),
|
|
2031
|
-
p.verts.map((v) => ({ x: v.x, y: v.y }))
|
|
2032
|
-
);
|
|
2033
1983
|
const fillSettings = {
|
|
2034
1984
|
interval: cutSetting.interval || 0.1,
|
|
2035
1985
|
angle: cutSetting.angle || 0,
|
|
2036
1986
|
crossHatch: cutSetting.crossHatch || false
|
|
2037
1987
|
};
|
|
2038
|
-
const
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
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
|
+
})
|
|
2043
1998
|
);
|
|
2044
|
-
const clipId = `clip-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2045
|
-
const clipPath = {
|
|
2046
|
-
name: "clipPath",
|
|
2047
|
-
type: "element",
|
|
2048
|
-
value: "",
|
|
2049
|
-
attributes: { id: clipId },
|
|
2050
|
-
children: [leaf("path", { d })]
|
|
2051
|
-
};
|
|
2052
|
-
const clippedGroup = {
|
|
2053
|
-
name: "g",
|
|
2054
|
-
type: "element",
|
|
2055
|
-
value: "",
|
|
2056
|
-
attributes: { "clip-path": `url(#${clipId})` },
|
|
2057
|
-
children: fillLines
|
|
2058
|
-
};
|
|
2059
|
-
children.push(clipPath);
|
|
2060
|
-
children.push(clippedGroup);
|
|
2061
1999
|
}
|
|
2062
2000
|
children.push(
|
|
2063
2001
|
leaf("path", {
|
|
@@ -2102,24 +2040,26 @@ var rectRenderer = {
|
|
|
2102
2040
|
const cutSetting = rect.cutIndex !== void 0 ? cutSettings.get(rect.cutIndex) : void 0;
|
|
2103
2041
|
const shouldShowFill = cutSetting && (cutSetting.type === "Scan" || cutSetting.type === "Scan+Cut");
|
|
2104
2042
|
if (shouldShowFill && cutSetting) {
|
|
2105
|
-
const localBBox = {
|
|
2106
|
-
minX: 0,
|
|
2107
|
-
minY: 0,
|
|
2108
|
-
maxX: w,
|
|
2109
|
-
maxY: h
|
|
2110
|
-
};
|
|
2111
2043
|
const fillSettings = {
|
|
2112
2044
|
interval: cutSetting.interval || 0.1,
|
|
2113
2045
|
angle: cutSetting.angle || 0,
|
|
2114
2046
|
crossHatch: cutSetting.crossHatch || false
|
|
2115
2047
|
};
|
|
2116
|
-
const
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
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
|
+
})
|
|
2121
2062
|
);
|
|
2122
|
-
children.push(...fillLines);
|
|
2123
2063
|
}
|
|
2124
2064
|
children.push(
|
|
2125
2065
|
leaf("rect", {
|
|
@@ -2193,11 +2133,8 @@ function svgForShape(shape, cutSettings, options) {
|
|
|
2193
2133
|
function measure(shapes) {
|
|
2194
2134
|
return shapes.reduce((acc, s) => boxUnion(acc, bboxOfShape(s)), emptyBox());
|
|
2195
2135
|
}
|
|
2196
|
-
function renderAll(shapes, cutSettings,
|
|
2197
|
-
|
|
2198
|
-
strokeWidth: svgOptions?.defaultStrokeWidth ?? DEFAULT_OPTIONS.defaultStrokeWidth
|
|
2199
|
-
};
|
|
2200
|
-
return shapes.map((s) => svgForShape(s, cutSettings, renderOptions));
|
|
2136
|
+
function renderAll(shapes, cutSettings, options) {
|
|
2137
|
+
return shapes.map((s) => svgForShape(s, cutSettings, options));
|
|
2201
2138
|
}
|
|
2202
2139
|
|
|
2203
2140
|
// lib/svg-gen/index.ts
|
|
@@ -2206,8 +2143,14 @@ function generateLightBurnSvg(root, options) {
|
|
|
2206
2143
|
const cutSettings = collectCutSettings(root);
|
|
2207
2144
|
const bbox = measure(shapes);
|
|
2208
2145
|
const layout = computeLayout(bbox, options);
|
|
2209
|
-
const
|
|
2210
|
-
const
|
|
2146
|
+
const patternRegistry = new HatchPatternRegistry();
|
|
2147
|
+
const renderOptions = {
|
|
2148
|
+
strokeWidth: options?.defaultStrokeWidth ?? DEFAULT_OPTIONS.defaultStrokeWidth,
|
|
2149
|
+
patternRegistry
|
|
2150
|
+
};
|
|
2151
|
+
const nodes = renderAll(shapes, cutSettings, renderOptions);
|
|
2152
|
+
const defs = patternRegistry.getPatterns();
|
|
2153
|
+
const svgTree = assembleSvg(nodes, layout, defs);
|
|
2211
2154
|
return stringify(svgTree);
|
|
2212
2155
|
}
|
|
2213
2156
|
export {
|