circuit-to-svg 0.0.252 → 0.0.254
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.js +114 -38
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1444,14 +1444,23 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1444
1444
|
const scaledOuterHeight = hole.outer_height * Math.abs(transform.a);
|
|
1445
1445
|
const scaledHoleWidth = hole.hole_width * Math.abs(transform.a);
|
|
1446
1446
|
const scaledHoleHeight = hole.hole_height * Math.abs(transform.a);
|
|
1447
|
-
const outerRadiusX = scaledOuterWidth / 2;
|
|
1448
|
-
const outerRadiusY = scaledOuterHeight / 2;
|
|
1449
|
-
const innerRadiusX = scaledHoleWidth / 2;
|
|
1450
|
-
const innerRadiusY = scaledHoleHeight / 2;
|
|
1451
|
-
const straightLength = scaledOuterHeight - scaledOuterWidth;
|
|
1452
1447
|
const rotation = hole.ccw_rotation || 0;
|
|
1453
1448
|
const outerTransform = rotation ? `translate(${x} ${y}) rotate(${-rotation})` : `translate(${x} ${y})`;
|
|
1454
1449
|
const innerTransform = rotation ? `translate(${x} ${y}) rotate(${-rotation})` : `translate(${x} ${y})`;
|
|
1450
|
+
const createPillPath = (width, height) => {
|
|
1451
|
+
if (width > height) {
|
|
1452
|
+
const radius = height / 2;
|
|
1453
|
+
const straightLength = width - 2 * radius;
|
|
1454
|
+
return `M${-width / 2 + radius},${-radius} h${straightLength} a${radius},${radius} 0 0 1 0,${height} h${-straightLength} a${radius},${radius} 0 0 1 0,${-height} z`;
|
|
1455
|
+
} else if (height > width) {
|
|
1456
|
+
const radius = width / 2;
|
|
1457
|
+
const straightLength = height - 2 * radius;
|
|
1458
|
+
return `M${radius},${-height / 2 + radius} v${straightLength} a${radius},${radius} 0 0 1 ${-width},0 v${-straightLength} a${radius},${radius} 0 0 1 ${width},0 z`;
|
|
1459
|
+
} else {
|
|
1460
|
+
const radius = width / 2;
|
|
1461
|
+
return `M${-radius},0 a${radius},${radius} 0 0 1 ${width},0 a${radius},${radius} 0 0 1 ${-width},0 z`;
|
|
1462
|
+
}
|
|
1463
|
+
};
|
|
1455
1464
|
return [
|
|
1456
1465
|
{
|
|
1457
1466
|
name: "g",
|
|
@@ -1468,7 +1477,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1468
1477
|
attributes: {
|
|
1469
1478
|
class: "pcb-hole-outer",
|
|
1470
1479
|
fill: colorMap2.copper.top,
|
|
1471
|
-
d:
|
|
1480
|
+
d: createPillPath(scaledOuterWidth, scaledOuterHeight),
|
|
1472
1481
|
transform: outerTransform,
|
|
1473
1482
|
"data-type": "pcb_plated_hole",
|
|
1474
1483
|
"data-pcb-layer": copperLayer
|
|
@@ -1483,7 +1492,7 @@ function createSvgObjectsFromPcbPlatedHole(hole, ctx) {
|
|
|
1483
1492
|
attributes: {
|
|
1484
1493
|
class: "pcb-hole-inner",
|
|
1485
1494
|
fill: colorMap2.drill,
|
|
1486
|
-
d:
|
|
1495
|
+
d: createPillPath(scaledHoleWidth, scaledHoleHeight),
|
|
1487
1496
|
transform: innerTransform,
|
|
1488
1497
|
"data-type": "pcb_plated_hole_drill",
|
|
1489
1498
|
"data-pcb-layer": "drill"
|
|
@@ -3339,7 +3348,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
3339
3348
|
var package_default = {
|
|
3340
3349
|
name: "circuit-to-svg",
|
|
3341
3350
|
type: "module",
|
|
3342
|
-
version: "0.0.
|
|
3351
|
+
version: "0.0.253",
|
|
3343
3352
|
description: "Convert Circuit JSON to SVG",
|
|
3344
3353
|
main: "dist/index.js",
|
|
3345
3354
|
files: [
|
|
@@ -3499,15 +3508,20 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3499
3508
|
let minY = Number.POSITIVE_INFINITY;
|
|
3500
3509
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
3501
3510
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
3511
|
+
let hasBounds = false;
|
|
3502
3512
|
let boardMinX = Number.POSITIVE_INFINITY;
|
|
3503
3513
|
let boardMinY = Number.POSITIVE_INFINITY;
|
|
3504
3514
|
let boardMaxX = Number.NEGATIVE_INFINITY;
|
|
3505
3515
|
let boardMaxY = Number.NEGATIVE_INFINITY;
|
|
3516
|
+
let hasBoardBounds = false;
|
|
3506
3517
|
for (const circuitJsonElm of circuitJson) {
|
|
3507
3518
|
if (circuitJsonElm.type === "pcb_panel") {
|
|
3508
3519
|
const panel = circuitJsonElm;
|
|
3509
|
-
const width =
|
|
3510
|
-
const height =
|
|
3520
|
+
const width = toNumeric(panel.width);
|
|
3521
|
+
const height = toNumeric(panel.height);
|
|
3522
|
+
if (width === void 0 || height === void 0) {
|
|
3523
|
+
continue;
|
|
3524
|
+
}
|
|
3511
3525
|
const center = { x: width / 2, y: height / 2 };
|
|
3512
3526
|
updateBounds(center, width, height);
|
|
3513
3527
|
updateBoardBounds(center, width, height);
|
|
@@ -3534,7 +3548,10 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3534
3548
|
if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
|
|
3535
3549
|
updateBounds({ x: pad.x, y: pad.y }, pad.width, pad.height);
|
|
3536
3550
|
} else if (pad.shape === "circle") {
|
|
3537
|
-
|
|
3551
|
+
const radius = toNumeric(pad.radius);
|
|
3552
|
+
if (radius !== void 0) {
|
|
3553
|
+
updateBounds({ x: pad.x, y: pad.y }, radius * 2, radius * 2);
|
|
3554
|
+
}
|
|
3538
3555
|
} else if (pad.shape === "polygon") {
|
|
3539
3556
|
updateTraceBounds(pad.points);
|
|
3540
3557
|
}
|
|
@@ -3551,7 +3568,10 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3551
3568
|
if (cutout.shape === "rect") {
|
|
3552
3569
|
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
3553
3570
|
} else if (cutout.shape === "circle") {
|
|
3554
|
-
|
|
3571
|
+
const radius = toNumeric(cutout.radius);
|
|
3572
|
+
if (radius !== void 0) {
|
|
3573
|
+
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
3574
|
+
}
|
|
3555
3575
|
} else if (cutout.shape === "polygon") {
|
|
3556
3576
|
updateTraceBounds(cutout.points);
|
|
3557
3577
|
}
|
|
@@ -3711,44 +3731,94 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3711
3731
|
console.error("Error stringifying SVG object:", error);
|
|
3712
3732
|
throw error;
|
|
3713
3733
|
}
|
|
3734
|
+
function toNumeric(value) {
|
|
3735
|
+
if (typeof value === "number") {
|
|
3736
|
+
return Number.isFinite(value) ? value : void 0;
|
|
3737
|
+
}
|
|
3738
|
+
if (typeof value === "string") {
|
|
3739
|
+
const parsed = Number.parseFloat(value);
|
|
3740
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
3741
|
+
}
|
|
3742
|
+
return void 0;
|
|
3743
|
+
}
|
|
3714
3744
|
function updateBounds(center, width, height) {
|
|
3715
|
-
|
|
3716
|
-
const
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3745
|
+
if (!center) return;
|
|
3746
|
+
const centerX = toNumeric(center.x);
|
|
3747
|
+
const centerY = toNumeric(center.y);
|
|
3748
|
+
if (centerX === void 0 || centerY === void 0) return;
|
|
3749
|
+
const numericWidth = toNumeric(width) ?? 0;
|
|
3750
|
+
const numericHeight = toNumeric(height) ?? 0;
|
|
3751
|
+
const halfWidth = numericWidth / 2;
|
|
3752
|
+
const halfHeight = numericHeight / 2;
|
|
3753
|
+
minX = Math.min(minX, centerX - halfWidth);
|
|
3754
|
+
minY = Math.min(minY, centerY - halfHeight);
|
|
3755
|
+
maxX = Math.max(maxX, centerX + halfWidth);
|
|
3756
|
+
maxY = Math.max(maxY, centerY + halfHeight);
|
|
3757
|
+
hasBounds = true;
|
|
3721
3758
|
}
|
|
3722
3759
|
function updateBoardBounds(center, width, height) {
|
|
3723
|
-
|
|
3724
|
-
const
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3760
|
+
if (!center) return;
|
|
3761
|
+
const centerX = toNumeric(center.x);
|
|
3762
|
+
const centerY = toNumeric(center.y);
|
|
3763
|
+
if (centerX === void 0 || centerY === void 0) return;
|
|
3764
|
+
const numericWidth = toNumeric(width) ?? 0;
|
|
3765
|
+
const numericHeight = toNumeric(height) ?? 0;
|
|
3766
|
+
const halfWidth = numericWidth / 2;
|
|
3767
|
+
const halfHeight = numericHeight / 2;
|
|
3768
|
+
boardMinX = Math.min(boardMinX, centerX - halfWidth);
|
|
3769
|
+
boardMinY = Math.min(boardMinY, centerY - halfHeight);
|
|
3770
|
+
boardMaxX = Math.max(boardMaxX, centerX + halfWidth);
|
|
3771
|
+
boardMaxY = Math.max(boardMaxY, centerY + halfHeight);
|
|
3772
|
+
hasBounds = true;
|
|
3773
|
+
hasBoardBounds = true;
|
|
3729
3774
|
}
|
|
3730
3775
|
function updateBoundsToIncludeOutline(outline) {
|
|
3776
|
+
let updated = false;
|
|
3731
3777
|
for (const point of outline) {
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3778
|
+
const x = toNumeric(point.x);
|
|
3779
|
+
const y = toNumeric(point.y);
|
|
3780
|
+
if (x === void 0 || y === void 0) continue;
|
|
3781
|
+
minX = Math.min(minX, x);
|
|
3782
|
+
minY = Math.min(minY, y);
|
|
3783
|
+
maxX = Math.max(maxX, x);
|
|
3784
|
+
maxY = Math.max(maxY, y);
|
|
3785
|
+
updated = true;
|
|
3786
|
+
}
|
|
3787
|
+
if (updated) {
|
|
3788
|
+
hasBounds = true;
|
|
3736
3789
|
}
|
|
3737
3790
|
}
|
|
3738
3791
|
function updateBoardBoundsToIncludeOutline(outline) {
|
|
3792
|
+
let updated = false;
|
|
3739
3793
|
for (const point of outline) {
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3794
|
+
const x = toNumeric(point.x);
|
|
3795
|
+
const y = toNumeric(point.y);
|
|
3796
|
+
if (x === void 0 || y === void 0) continue;
|
|
3797
|
+
boardMinX = Math.min(boardMinX, x);
|
|
3798
|
+
boardMinY = Math.min(boardMinY, y);
|
|
3799
|
+
boardMaxX = Math.max(boardMaxX, x);
|
|
3800
|
+
boardMaxY = Math.max(boardMaxY, y);
|
|
3801
|
+
updated = true;
|
|
3802
|
+
}
|
|
3803
|
+
if (updated) {
|
|
3804
|
+
hasBounds = true;
|
|
3805
|
+
hasBoardBounds = true;
|
|
3744
3806
|
}
|
|
3745
3807
|
}
|
|
3746
3808
|
function updateTraceBounds(route) {
|
|
3809
|
+
let updated = false;
|
|
3747
3810
|
for (const point of route) {
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3811
|
+
const x = toNumeric(point?.x);
|
|
3812
|
+
const y = toNumeric(point?.y);
|
|
3813
|
+
if (x === void 0 || y === void 0) continue;
|
|
3814
|
+
minX = Math.min(minX, x);
|
|
3815
|
+
minY = Math.min(minY, y);
|
|
3816
|
+
maxX = Math.max(maxX, x);
|
|
3817
|
+
maxY = Math.max(maxY, y);
|
|
3818
|
+
updated = true;
|
|
3819
|
+
}
|
|
3820
|
+
if (updated) {
|
|
3821
|
+
hasBounds = true;
|
|
3752
3822
|
}
|
|
3753
3823
|
}
|
|
3754
3824
|
function updateSilkscreenBounds(item) {
|
|
@@ -3759,7 +3829,10 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3759
3829
|
} else if (item.type === "pcb_silkscreen_rect") {
|
|
3760
3830
|
updateBounds(item.center, item.width, item.height);
|
|
3761
3831
|
} else if (item.type === "pcb_silkscreen_circle") {
|
|
3762
|
-
|
|
3832
|
+
const radius = toNumeric(item.radius);
|
|
3833
|
+
if (radius !== void 0) {
|
|
3834
|
+
updateBounds(item.center, radius * 2, radius * 2);
|
|
3835
|
+
}
|
|
3763
3836
|
} else if (item.type === "pcb_silkscreen_line") {
|
|
3764
3837
|
updateBounds({ x: item.x1, y: item.y1 }, 0, 0);
|
|
3765
3838
|
updateBounds({ x: item.x2, y: item.y2 }, 0, 0);
|
|
@@ -3768,7 +3841,10 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3768
3841
|
if (cutout.shape === "rect") {
|
|
3769
3842
|
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
3770
3843
|
} else if (cutout.shape === "circle") {
|
|
3771
|
-
|
|
3844
|
+
const radius = toNumeric(cutout.radius);
|
|
3845
|
+
if (radius !== void 0) {
|
|
3846
|
+
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
3847
|
+
}
|
|
3772
3848
|
} else if (cutout.shape === "polygon") {
|
|
3773
3849
|
updateTraceBounds(cutout.points);
|
|
3774
3850
|
}
|