circuit-to-svg 0.0.258 → 0.0.260
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 +71 -43
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// lib/pcb/convert-circuit-json-to-pcb-svg.ts
|
|
2
|
+
import { distance } from "circuit-json";
|
|
2
3
|
import { stringify } from "svgson";
|
|
3
4
|
import {
|
|
4
5
|
applyToPoint as applyToPoint31,
|
|
@@ -537,7 +538,8 @@ function createSvgObjectsFromPcbFabricationNoteRect(fabricationNoteRect, ctx) {
|
|
|
537
538
|
color,
|
|
538
539
|
layer = "top",
|
|
539
540
|
pcb_component_id,
|
|
540
|
-
pcb_fabrication_note_rect_id
|
|
541
|
+
pcb_fabrication_note_rect_id,
|
|
542
|
+
corner_radius
|
|
541
543
|
} = fabricationNoteRect;
|
|
542
544
|
if (layerFilter && layer !== layerFilter) return [];
|
|
543
545
|
if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
|
|
@@ -565,6 +567,9 @@ function createSvgObjectsFromPcbFabricationNoteRect(fabricationNoteRect, ctx) {
|
|
|
565
567
|
const baseStrokeWidth = typeof stroke_width === "number" ? stroke_width : 0;
|
|
566
568
|
const transformedStrokeWidth = baseStrokeWidth * Math.abs(transform.a);
|
|
567
569
|
const overlayStrokeColor = color ?? DEFAULT_OVERLAY_STROKE_COLOR;
|
|
570
|
+
const baseCornerRadius = typeof corner_radius === "number" && corner_radius > 0 ? corner_radius : 0;
|
|
571
|
+
const transformedCornerRadiusX = baseCornerRadius * Math.abs(transform.a);
|
|
572
|
+
const transformedCornerRadiusY = baseCornerRadius * Math.abs(transform.d);
|
|
568
573
|
const attributes = {
|
|
569
574
|
x: rectX.toString(),
|
|
570
575
|
y: rectY.toString(),
|
|
@@ -578,6 +583,12 @@ function createSvgObjectsFromPcbFabricationNoteRect(fabricationNoteRect, ctx) {
|
|
|
578
583
|
if (pcb_component_id !== void 0) {
|
|
579
584
|
attributes["data-pcb-component-id"] = pcb_component_id;
|
|
580
585
|
}
|
|
586
|
+
if (transformedCornerRadiusX > 0) {
|
|
587
|
+
attributes.rx = transformedCornerRadiusX.toString();
|
|
588
|
+
}
|
|
589
|
+
if (transformedCornerRadiusY > 0) {
|
|
590
|
+
attributes.ry = transformedCornerRadiusY.toString();
|
|
591
|
+
}
|
|
581
592
|
if (is_filled) {
|
|
582
593
|
attributes.fill = color ?? DEFAULT_OVERLAY_FILL_COLOR;
|
|
583
594
|
} else {
|
|
@@ -1410,7 +1421,8 @@ function createSvgObjectsFromPcbNoteRect(noteRect, ctx) {
|
|
|
1410
1421
|
is_filled,
|
|
1411
1422
|
has_stroke,
|
|
1412
1423
|
is_stroke_dashed,
|
|
1413
|
-
color
|
|
1424
|
+
color,
|
|
1425
|
+
corner_radius
|
|
1414
1426
|
} = noteRect;
|
|
1415
1427
|
if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
|
|
1416
1428
|
console.error("Invalid pcb_note_rect data", { center, width, height });
|
|
@@ -1432,6 +1444,9 @@ function createSvgObjectsFromPcbNoteRect(noteRect, ctx) {
|
|
|
1432
1444
|
const rectHeight = Math.abs(bottomRightY - topLeftY);
|
|
1433
1445
|
const baseStrokeWidth = typeof stroke_width === "number" ? stroke_width : 0;
|
|
1434
1446
|
const transformedStrokeWidth = baseStrokeWidth * Math.abs(transform.a);
|
|
1447
|
+
const baseCornerRadius = typeof corner_radius === "number" && corner_radius > 0 ? corner_radius : 0;
|
|
1448
|
+
const transformedCornerRadiusX = baseCornerRadius * Math.abs(transform.a);
|
|
1449
|
+
const transformedCornerRadiusY = baseCornerRadius * Math.abs(transform.d);
|
|
1435
1450
|
const overlayColor = color ?? DEFAULT_OVERLAY_COLOR2;
|
|
1436
1451
|
const attributes = {
|
|
1437
1452
|
x: rectX.toString(),
|
|
@@ -1443,6 +1458,12 @@ function createSvgObjectsFromPcbNoteRect(noteRect, ctx) {
|
|
|
1443
1458
|
"data-pcb-note-rect-id": noteRect.pcb_note_rect_id,
|
|
1444
1459
|
"data-pcb-layer": "overlay"
|
|
1445
1460
|
};
|
|
1461
|
+
if (transformedCornerRadiusX > 0) {
|
|
1462
|
+
attributes.rx = transformedCornerRadiusX.toString();
|
|
1463
|
+
}
|
|
1464
|
+
if (transformedCornerRadiusY > 0) {
|
|
1465
|
+
attributes.ry = transformedCornerRadiusY.toString();
|
|
1466
|
+
}
|
|
1446
1467
|
if (is_filled) {
|
|
1447
1468
|
attributes.fill = color ?? DEFAULT_FILL_COLOR;
|
|
1448
1469
|
} else {
|
|
@@ -2066,7 +2087,8 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2066
2087
|
stroke_width,
|
|
2067
2088
|
is_filled,
|
|
2068
2089
|
has_stroke,
|
|
2069
|
-
is_stroke_dashed
|
|
2090
|
+
is_stroke_dashed,
|
|
2091
|
+
corner_radius
|
|
2070
2092
|
} = pcbSilkscreenRect;
|
|
2071
2093
|
if (layerFilter && layer !== layerFilter) return [];
|
|
2072
2094
|
if (!center || typeof center.x !== "number" || typeof center.y !== "number" || typeof width !== "number" || typeof height !== "number") {
|
|
@@ -2077,6 +2099,9 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2077
2099
|
center.x,
|
|
2078
2100
|
center.y
|
|
2079
2101
|
]);
|
|
2102
|
+
const baseCornerRadius = typeof corner_radius === "number" && corner_radius > 0 ? corner_radius : 0;
|
|
2103
|
+
const transformedCornerRadiusX = baseCornerRadius * Math.abs(transform.a);
|
|
2104
|
+
const transformedCornerRadiusY = baseCornerRadius * Math.abs(transform.d);
|
|
2080
2105
|
const transformedWidth = width * Math.abs(transform.a);
|
|
2081
2106
|
const transformedHeight = height * Math.abs(transform.d);
|
|
2082
2107
|
const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
|
|
@@ -2091,6 +2116,12 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, ctx) {
|
|
|
2091
2116
|
"data-type": "pcb_silkscreen_rect",
|
|
2092
2117
|
"data-pcb-layer": layer
|
|
2093
2118
|
};
|
|
2119
|
+
if (transformedCornerRadiusX > 0) {
|
|
2120
|
+
attributes.rx = transformedCornerRadiusX.toString();
|
|
2121
|
+
}
|
|
2122
|
+
if (transformedCornerRadiusY > 0) {
|
|
2123
|
+
attributes.ry = transformedCornerRadiusY.toString();
|
|
2124
|
+
}
|
|
2094
2125
|
attributes.fill = is_filled ? color : "none";
|
|
2095
2126
|
let actualHasStroke;
|
|
2096
2127
|
if (has_stroke === void 0) {
|
|
@@ -2902,9 +2933,9 @@ var findNearestPointInNet = (sourcePoint, netId, connectivity, circuitJson) => {
|
|
|
2902
2933
|
if (pos) {
|
|
2903
2934
|
const dx = sourcePoint.x - pos.x;
|
|
2904
2935
|
const dy = sourcePoint.y - pos.y;
|
|
2905
|
-
const
|
|
2906
|
-
if (
|
|
2907
|
-
minDistance =
|
|
2936
|
+
const distance3 = Math.sqrt(dx * dx + dy * dy);
|
|
2937
|
+
if (distance3 > 0 && distance3 < minDistance) {
|
|
2938
|
+
minDistance = distance3;
|
|
2908
2939
|
nearestPoint = pos;
|
|
2909
2940
|
}
|
|
2910
2941
|
}
|
|
@@ -3471,7 +3502,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
3471
3502
|
var package_default = {
|
|
3472
3503
|
name: "circuit-to-svg",
|
|
3473
3504
|
type: "module",
|
|
3474
|
-
version: "0.0.
|
|
3505
|
+
version: "0.0.259",
|
|
3475
3506
|
description: "Convert Circuit JSON to SVG",
|
|
3476
3507
|
main: "dist/index.js",
|
|
3477
3508
|
files: [
|
|
@@ -3495,12 +3526,12 @@ var package_default = {
|
|
|
3495
3526
|
"bun-match-svg": "^0.0.12",
|
|
3496
3527
|
esbuild: "^0.20.2",
|
|
3497
3528
|
"performance-now": "^2.1.0",
|
|
3498
|
-
"circuit-json": "^0.0.
|
|
3529
|
+
"circuit-json": "^0.0.297",
|
|
3499
3530
|
react: "19.1.0",
|
|
3500
3531
|
"react-cosmos": "7.0.0",
|
|
3501
3532
|
"react-cosmos-plugin-vite": "7.0.0",
|
|
3502
3533
|
"react-dom": "19.1.0",
|
|
3503
|
-
tscircuit: "^0.0.
|
|
3534
|
+
tscircuit: "^0.0.827",
|
|
3504
3535
|
tsup: "^8.0.2",
|
|
3505
3536
|
typescript: "^5.4.5",
|
|
3506
3537
|
"vite-tsconfig-paths": "^5.0.1"
|
|
@@ -3640,14 +3671,13 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3640
3671
|
for (const circuitJsonElm of circuitJson) {
|
|
3641
3672
|
if (circuitJsonElm.type === "pcb_panel") {
|
|
3642
3673
|
const panel = circuitJsonElm;
|
|
3643
|
-
const width =
|
|
3644
|
-
const height =
|
|
3674
|
+
const width = distance.parse(panel.width);
|
|
3675
|
+
const height = distance.parse(panel.height);
|
|
3645
3676
|
if (width === void 0 || height === void 0) {
|
|
3646
3677
|
continue;
|
|
3647
3678
|
}
|
|
3648
3679
|
const center = { x: width / 2, y: height / 2 };
|
|
3649
3680
|
updateBounds(center, width, height);
|
|
3650
|
-
updateBoardBounds(center, width, height);
|
|
3651
3681
|
} else if (circuitJsonElm.type === "pcb_board") {
|
|
3652
3682
|
if (circuitJsonElm.outline && Array.isArray(circuitJsonElm.outline) && circuitJsonElm.outline.length >= 3) {
|
|
3653
3683
|
updateBoundsToIncludeOutline(circuitJsonElm.outline);
|
|
@@ -3664,20 +3694,20 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3664
3694
|
circuitJsonElm.height
|
|
3665
3695
|
);
|
|
3666
3696
|
}
|
|
3667
|
-
} else if ("x" in circuitJsonElm && "y" in circuitJsonElm) {
|
|
3668
|
-
updateBounds({ x: circuitJsonElm.x, y: circuitJsonElm.y }, 0, 0);
|
|
3669
3697
|
} else if (circuitJsonElm.type === "pcb_smtpad") {
|
|
3670
3698
|
const pad = circuitJsonElm;
|
|
3671
3699
|
if (pad.shape === "rect" || pad.shape === "rotated_rect" || pad.shape === "pill") {
|
|
3672
3700
|
updateBounds({ x: pad.x, y: pad.y }, pad.width, pad.height);
|
|
3673
3701
|
} else if (pad.shape === "circle") {
|
|
3674
|
-
const radius =
|
|
3702
|
+
const radius = distance.parse(pad.radius);
|
|
3675
3703
|
if (radius !== void 0) {
|
|
3676
3704
|
updateBounds({ x: pad.x, y: pad.y }, radius * 2, radius * 2);
|
|
3677
3705
|
}
|
|
3678
3706
|
} else if (pad.shape === "polygon") {
|
|
3679
3707
|
updateTraceBounds(pad.points);
|
|
3680
3708
|
}
|
|
3709
|
+
} else if ("x" in circuitJsonElm && "y" in circuitJsonElm) {
|
|
3710
|
+
updateBounds({ x: circuitJsonElm.x, y: circuitJsonElm.y }, 0, 0);
|
|
3681
3711
|
} else if ("route" in circuitJsonElm) {
|
|
3682
3712
|
updateTraceBounds(circuitJsonElm.route);
|
|
3683
3713
|
} else if (circuitJsonElm.type === "pcb_note_rect" || circuitJsonElm.type === "pcb_fabrication_note_rect") {
|
|
@@ -3691,7 +3721,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3691
3721
|
if (cutout.shape === "rect") {
|
|
3692
3722
|
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
3693
3723
|
} else if (cutout.shape === "circle") {
|
|
3694
|
-
const radius =
|
|
3724
|
+
const radius = distance.parse(cutout.radius);
|
|
3695
3725
|
if (radius !== void 0) {
|
|
3696
3726
|
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
3697
3727
|
}
|
|
@@ -3854,23 +3884,13 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3854
3884
|
console.error("Error stringifying SVG object:", error);
|
|
3855
3885
|
throw error;
|
|
3856
3886
|
}
|
|
3857
|
-
function toNumeric(value) {
|
|
3858
|
-
if (typeof value === "number") {
|
|
3859
|
-
return Number.isFinite(value) ? value : void 0;
|
|
3860
|
-
}
|
|
3861
|
-
if (typeof value === "string") {
|
|
3862
|
-
const parsed = Number.parseFloat(value);
|
|
3863
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
3864
|
-
}
|
|
3865
|
-
return void 0;
|
|
3866
|
-
}
|
|
3867
3887
|
function updateBounds(center, width, height) {
|
|
3868
3888
|
if (!center) return;
|
|
3869
|
-
const centerX =
|
|
3870
|
-
const centerY =
|
|
3889
|
+
const centerX = distance.parse(center.x);
|
|
3890
|
+
const centerY = distance.parse(center.y);
|
|
3871
3891
|
if (centerX === void 0 || centerY === void 0) return;
|
|
3872
|
-
const numericWidth =
|
|
3873
|
-
const numericHeight =
|
|
3892
|
+
const numericWidth = distance.parse(width) ?? 0;
|
|
3893
|
+
const numericHeight = distance.parse(height) ?? 0;
|
|
3874
3894
|
const halfWidth = numericWidth / 2;
|
|
3875
3895
|
const halfHeight = numericHeight / 2;
|
|
3876
3896
|
minX = Math.min(minX, centerX - halfWidth);
|
|
@@ -3881,11 +3901,11 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3881
3901
|
}
|
|
3882
3902
|
function updateBoardBounds(center, width, height) {
|
|
3883
3903
|
if (!center) return;
|
|
3884
|
-
const centerX =
|
|
3885
|
-
const centerY =
|
|
3904
|
+
const centerX = distance.parse(center.x);
|
|
3905
|
+
const centerY = distance.parse(center.y);
|
|
3886
3906
|
if (centerX === void 0 || centerY === void 0) return;
|
|
3887
|
-
const numericWidth =
|
|
3888
|
-
const numericHeight =
|
|
3907
|
+
const numericWidth = distance.parse(width) ?? 0;
|
|
3908
|
+
const numericHeight = distance.parse(height) ?? 0;
|
|
3889
3909
|
const halfWidth = numericWidth / 2;
|
|
3890
3910
|
const halfHeight = numericHeight / 2;
|
|
3891
3911
|
boardMinX = Math.min(boardMinX, centerX - halfWidth);
|
|
@@ -3898,8 +3918,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3898
3918
|
function updateBoundsToIncludeOutline(outline) {
|
|
3899
3919
|
let updated = false;
|
|
3900
3920
|
for (const point of outline) {
|
|
3901
|
-
const x =
|
|
3902
|
-
const y =
|
|
3921
|
+
const x = distance.parse(point.x);
|
|
3922
|
+
const y = distance.parse(point.y);
|
|
3903
3923
|
if (x === void 0 || y === void 0) continue;
|
|
3904
3924
|
minX = Math.min(minX, x);
|
|
3905
3925
|
minY = Math.min(minY, y);
|
|
@@ -3914,8 +3934,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3914
3934
|
function updateBoardBoundsToIncludeOutline(outline) {
|
|
3915
3935
|
let updated = false;
|
|
3916
3936
|
for (const point of outline) {
|
|
3917
|
-
const x =
|
|
3918
|
-
const y =
|
|
3937
|
+
const x = distance.parse(point.x);
|
|
3938
|
+
const y = distance.parse(point.y);
|
|
3919
3939
|
if (x === void 0 || y === void 0) continue;
|
|
3920
3940
|
boardMinX = Math.min(boardMinX, x);
|
|
3921
3941
|
boardMinY = Math.min(boardMinY, y);
|
|
@@ -3931,8 +3951,8 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3931
3951
|
function updateTraceBounds(route) {
|
|
3932
3952
|
let updated = false;
|
|
3933
3953
|
for (const point of route) {
|
|
3934
|
-
const x =
|
|
3935
|
-
const y =
|
|
3954
|
+
const x = distance.parse(point?.x);
|
|
3955
|
+
const y = distance.parse(point?.y);
|
|
3936
3956
|
if (x === void 0 || y === void 0) continue;
|
|
3937
3957
|
minX = Math.min(minX, x);
|
|
3938
3958
|
minY = Math.min(minY, y);
|
|
@@ -3952,7 +3972,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3952
3972
|
} else if (item.type === "pcb_silkscreen_rect") {
|
|
3953
3973
|
updateBounds(item.center, item.width, item.height);
|
|
3954
3974
|
} else if (item.type === "pcb_silkscreen_circle") {
|
|
3955
|
-
const radius =
|
|
3975
|
+
const radius = distance.parse(item.radius);
|
|
3956
3976
|
if (radius !== void 0) {
|
|
3957
3977
|
updateBounds(item.center, radius * 2, radius * 2);
|
|
3958
3978
|
}
|
|
@@ -3964,7 +3984,7 @@ function convertCircuitJsonToPcbSvg(circuitJson, options) {
|
|
|
3964
3984
|
if (cutout.shape === "rect") {
|
|
3965
3985
|
updateBounds(cutout.center, cutout.width, cutout.height);
|
|
3966
3986
|
} else if (cutout.shape === "circle") {
|
|
3967
|
-
const radius =
|
|
3987
|
+
const radius = distance.parse(cutout.radius);
|
|
3968
3988
|
if (radius !== void 0) {
|
|
3969
3989
|
updateBounds(cutout.center, radius * 2, radius * 2);
|
|
3970
3990
|
}
|
|
@@ -10558,6 +10578,7 @@ function formatNumber2(value) {
|
|
|
10558
10578
|
}
|
|
10559
10579
|
|
|
10560
10580
|
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
10581
|
+
import { distance as distance2 } from "circuit-json";
|
|
10561
10582
|
import { stringify as stringify7 } from "svgson";
|
|
10562
10583
|
import {
|
|
10563
10584
|
applyToPoint as applyToPoint70,
|
|
@@ -10664,7 +10685,7 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
10664
10685
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
10665
10686
|
let maxY = Number.NEGATIVE_INFINITY;
|
|
10666
10687
|
const filteredCircuitJson = circuitJson.filter(
|
|
10667
|
-
(elm) => elm.type === "pcb_board" || elm.type === "pcb_solder_paste" && elm.layer === options.layer
|
|
10688
|
+
(elm) => elm.type === "pcb_board" || elm.type === "pcb_panel" || elm.type === "pcb_solder_paste" && elm.layer === options.layer
|
|
10668
10689
|
);
|
|
10669
10690
|
for (const item of filteredCircuitJson) {
|
|
10670
10691
|
if (item.type === "pcb_board") {
|
|
@@ -10673,6 +10694,13 @@ function convertCircuitJsonToSolderPasteMask(circuitJson, options) {
|
|
|
10673
10694
|
} else if ("center" in item && "width" in item && "height" in item) {
|
|
10674
10695
|
updateBounds(item.center, item.width, item.height);
|
|
10675
10696
|
}
|
|
10697
|
+
} else if (item.type === "pcb_panel") {
|
|
10698
|
+
const panel = item;
|
|
10699
|
+
const width = distance2.parse(panel.width);
|
|
10700
|
+
const height = distance2.parse(panel.height);
|
|
10701
|
+
if (width !== void 0 && height !== void 0) {
|
|
10702
|
+
updateBounds({ x: width / 2, y: height / 2 }, width, height);
|
|
10703
|
+
}
|
|
10676
10704
|
} else if (item.type === "pcb_solder_paste" && "x" in item && "y" in item) {
|
|
10677
10705
|
updateBounds({ x: item.x, y: item.y }, 0, 0);
|
|
10678
10706
|
}
|