circuit-to-svg 0.0.124 → 0.0.126
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 +14 -7
- package/dist/index.js +271 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { AnyCircuitElement } from 'circuit-json';
|
|
2
2
|
|
|
3
|
-
interface Options$
|
|
3
|
+
interface Options$3 {
|
|
4
4
|
width?: number;
|
|
5
5
|
height?: number;
|
|
6
6
|
shouldDrawErrors?: boolean;
|
|
7
7
|
shouldDrawRatsNest?: boolean;
|
|
8
8
|
}
|
|
9
|
-
declare function convertCircuitJsonToPcbSvg(soup: AnyCircuitElement[], options?: Options$
|
|
9
|
+
declare function convertCircuitJsonToPcbSvg(soup: AnyCircuitElement[], options?: Options$3): string;
|
|
10
10
|
/**
|
|
11
11
|
* @deprecated use `convertCircuitJsonToPcbSvg` instead
|
|
12
12
|
*/
|
|
13
13
|
declare const circuitJsonToPcbSvg: typeof convertCircuitJsonToPcbSvg;
|
|
14
14
|
|
|
15
|
-
interface Options$
|
|
15
|
+
interface Options$2 {
|
|
16
16
|
width?: number;
|
|
17
17
|
height?: number;
|
|
18
18
|
}
|
|
19
|
-
declare function convertCircuitJsonToAssemblySvg(soup: AnyCircuitElement[], options?: Options$
|
|
19
|
+
declare function convertCircuitJsonToAssemblySvg(soup: AnyCircuitElement[], options?: Options$2): string;
|
|
20
20
|
|
|
21
21
|
declare const colorMap: {
|
|
22
22
|
"3d_viewer": {
|
|
@@ -181,7 +181,7 @@ type ColorMap = typeof colorMap;
|
|
|
181
181
|
type ColorOverrides = {
|
|
182
182
|
schematic?: Partial<ColorMap["schematic"]>;
|
|
183
183
|
};
|
|
184
|
-
interface Options {
|
|
184
|
+
interface Options$1 {
|
|
185
185
|
colorOverrides?: ColorOverrides;
|
|
186
186
|
width?: number;
|
|
187
187
|
height?: number;
|
|
@@ -195,10 +195,17 @@ interface Options {
|
|
|
195
195
|
label: string;
|
|
196
196
|
}>;
|
|
197
197
|
}
|
|
198
|
-
declare function convertCircuitJsonToSchematicSvg(circuitJson: AnyCircuitElement[], options?: Options): string;
|
|
198
|
+
declare function convertCircuitJsonToSchematicSvg(circuitJson: AnyCircuitElement[], options?: Options$1): string;
|
|
199
199
|
/**
|
|
200
200
|
* @deprecated use `convertCircuitJsonToSchematicSvg` instead
|
|
201
201
|
*/
|
|
202
202
|
declare const circuitJsonToSchematicSvg: typeof convertCircuitJsonToSchematicSvg;
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
interface Options {
|
|
205
|
+
layer: "top" | "bottom";
|
|
206
|
+
width?: number;
|
|
207
|
+
height?: number;
|
|
208
|
+
}
|
|
209
|
+
declare function convertCircuitJsonToSolderPasteMask(soup: AnyCircuitElement[], options: Options): string;
|
|
210
|
+
|
|
211
|
+
export { type ColorMap, type ColorOverrides, circuitJsonToPcbSvg, circuitJsonToSchematicSvg, convertCircuitJsonToAssemblySvg, convertCircuitJsonToPcbSvg, convertCircuitJsonToSchematicSvg, convertCircuitJsonToSolderPasteMask };
|
package/dist/index.js
CHANGED
|
@@ -578,7 +578,8 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
|
|
|
578
578
|
text,
|
|
579
579
|
font_size = 1,
|
|
580
580
|
layer = "top",
|
|
581
|
-
ccw_rotation = 0
|
|
581
|
+
ccw_rotation = 0,
|
|
582
|
+
anchor_alignment = "center"
|
|
582
583
|
} = pcbSilkscreenText;
|
|
583
584
|
if (!anchor_position || typeof anchor_position.x !== "number" || typeof anchor_position.y !== "number") {
|
|
584
585
|
console.error("Invalid anchor_position:", anchor_position);
|
|
@@ -589,6 +590,33 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
|
|
|
589
590
|
anchor_position.y
|
|
590
591
|
]);
|
|
591
592
|
const transformedFontSize = font_size * Math.abs(transform.a);
|
|
593
|
+
let textAnchor = "middle";
|
|
594
|
+
let dominantBaseline = "central";
|
|
595
|
+
let dx = 0;
|
|
596
|
+
let dy = 0;
|
|
597
|
+
switch (anchor_alignment) {
|
|
598
|
+
case "top_left":
|
|
599
|
+
textAnchor = "start";
|
|
600
|
+
dominantBaseline = "text-before-edge";
|
|
601
|
+
break;
|
|
602
|
+
case "top_right":
|
|
603
|
+
textAnchor = "end";
|
|
604
|
+
dominantBaseline = "text-before-edge";
|
|
605
|
+
break;
|
|
606
|
+
case "bottom_left":
|
|
607
|
+
textAnchor = "start";
|
|
608
|
+
dominantBaseline = "text-after-edge";
|
|
609
|
+
break;
|
|
610
|
+
case "bottom_right":
|
|
611
|
+
textAnchor = "end";
|
|
612
|
+
dominantBaseline = "text-after-edge";
|
|
613
|
+
break;
|
|
614
|
+
case "center":
|
|
615
|
+
default:
|
|
616
|
+
textAnchor = "middle";
|
|
617
|
+
dominantBaseline = "central";
|
|
618
|
+
break;
|
|
619
|
+
}
|
|
592
620
|
const textTransform = compose2(
|
|
593
621
|
translate2(transformedX, transformedY),
|
|
594
622
|
rotate2(ccw_rotation * Math.PI / 180),
|
|
@@ -601,11 +629,13 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
|
|
|
601
629
|
attributes: {
|
|
602
630
|
x: "0",
|
|
603
631
|
y: "0",
|
|
632
|
+
dx: dx.toString(),
|
|
633
|
+
dy: dy.toString(),
|
|
604
634
|
fill: color,
|
|
605
635
|
"font-family": "Arial, sans-serif",
|
|
606
636
|
"font-size": transformedFontSize.toString(),
|
|
607
|
-
"text-anchor":
|
|
608
|
-
"dominant-baseline":
|
|
637
|
+
"text-anchor": textAnchor,
|
|
638
|
+
"dominant-baseline": dominantBaseline,
|
|
609
639
|
transform: matrixToString2(textTransform),
|
|
610
640
|
class: `pcb-silkscreen-text pcb-silkscreen-${layer}`,
|
|
611
641
|
"data-pcb-silkscreen-text-id": pcbSilkscreenText.pcb_component_id,
|
|
@@ -773,6 +803,13 @@ var LAYER_NAME_TO_COLOR = {
|
|
|
773
803
|
function layerNameToColor(layerName) {
|
|
774
804
|
return LAYER_NAME_TO_COLOR[layerName] ?? "white";
|
|
775
805
|
}
|
|
806
|
+
var SOLDER_PASTE_LAYER_NAME_TO_COLOR = {
|
|
807
|
+
bottom: "rgb(105, 105, 105)",
|
|
808
|
+
top: "rgb(105, 105, 105)"
|
|
809
|
+
};
|
|
810
|
+
function solderPasteLayerNameToColor(layerName) {
|
|
811
|
+
return SOLDER_PASTE_LAYER_NAME_TO_COLOR[layerName] ?? "rgb(105, 105, 105)";
|
|
812
|
+
}
|
|
776
813
|
|
|
777
814
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-trace.ts
|
|
778
815
|
function createSvgObjectsFromPcbTrace(trace, transform) {
|
|
@@ -4093,8 +4130,8 @@ var ninePointAnchorToDominantBaseline = {
|
|
|
4093
4130
|
middle_bottom: "hanging"
|
|
4094
4131
|
};
|
|
4095
4132
|
function getTextOffsets(pathRotation, transform) {
|
|
4096
|
-
const
|
|
4097
|
-
const baseOffset =
|
|
4133
|
+
const scale9 = Math.abs(transform.a);
|
|
4134
|
+
const baseOffset = scale9 * 0.1;
|
|
4098
4135
|
const rotationOffsetMap = {
|
|
4099
4136
|
"0": { x: baseOffset * 0.8, y: -baseOffset },
|
|
4100
4137
|
// Left
|
|
@@ -4248,8 +4285,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
|
|
|
4248
4285
|
} else if (textValue === "{VAL}") {
|
|
4249
4286
|
textValue = "";
|
|
4250
4287
|
}
|
|
4251
|
-
const
|
|
4252
|
-
const baseOffset =
|
|
4288
|
+
const scale9 = Math.abs(realToScreenTransform.a);
|
|
4289
|
+
const baseOffset = scale9 * 0.1;
|
|
4253
4290
|
const rotationOffset = getTextOffsets(pathRotation, realToScreenTransform);
|
|
4254
4291
|
const offsetScreenPos = {
|
|
4255
4292
|
x: screenTextPos.x + rotationOffset.x,
|
|
@@ -4659,11 +4696,237 @@ function convertCircuitJsonToSchematicSvg(circuitJson, options) {
|
|
|
4659
4696
|
return stringify3(svgObject);
|
|
4660
4697
|
}
|
|
4661
4698
|
var circuitJsonToSchematicSvg = convertCircuitJsonToSchematicSvg;
|
|
4699
|
+
|
|
4700
|
+
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
4701
|
+
import { stringify as stringify4 } from "svgson";
|
|
4702
|
+
import {
|
|
4703
|
+
applyToPoint as applyToPoint38,
|
|
4704
|
+
compose as compose10,
|
|
4705
|
+
scale as scale8,
|
|
4706
|
+
translate as translate10
|
|
4707
|
+
} from "transformation-matrix";
|
|
4708
|
+
|
|
4709
|
+
// lib/pcb/svg-object-fns/convert-circuit-json-to-solder-paste-mask.ts
|
|
4710
|
+
import { applyToPoint as applyToPoint37 } from "transformation-matrix";
|
|
4711
|
+
function createSvgObjectsFromSolderPaste(solderPaste, transform) {
|
|
4712
|
+
const [x, y] = applyToPoint37(transform, [solderPaste.x, solderPaste.y]);
|
|
4713
|
+
if (solderPaste.shape === "rect" || solderPaste.shape === "rotated_rect") {
|
|
4714
|
+
const width = solderPaste.width * Math.abs(transform.a);
|
|
4715
|
+
const height = solderPaste.height * Math.abs(transform.d);
|
|
4716
|
+
if (solderPaste.shape === "rotated_rect" && solderPaste.ccw_rotation) {
|
|
4717
|
+
return [
|
|
4718
|
+
{
|
|
4719
|
+
name: "rect",
|
|
4720
|
+
type: "element",
|
|
4721
|
+
attributes: {
|
|
4722
|
+
class: "pcb-solder-paste",
|
|
4723
|
+
fill: solderPasteLayerNameToColor(solderPaste.layer),
|
|
4724
|
+
x: (-width / 2).toString(),
|
|
4725
|
+
y: (-height / 2).toString(),
|
|
4726
|
+
width: width.toString(),
|
|
4727
|
+
height: height.toString(),
|
|
4728
|
+
transform: `translate(${x} ${y}) rotate(${-solderPaste.ccw_rotation})`
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
];
|
|
4732
|
+
}
|
|
4733
|
+
return [
|
|
4734
|
+
{
|
|
4735
|
+
name: "rect",
|
|
4736
|
+
type: "element",
|
|
4737
|
+
attributes: {
|
|
4738
|
+
class: "pcb-solder-paste",
|
|
4739
|
+
fill: solderPasteLayerNameToColor(solderPaste.layer),
|
|
4740
|
+
x: (x - width / 2).toString(),
|
|
4741
|
+
y: (y - height / 2).toString(),
|
|
4742
|
+
width: width.toString(),
|
|
4743
|
+
height: height.toString()
|
|
4744
|
+
}
|
|
4745
|
+
}
|
|
4746
|
+
];
|
|
4747
|
+
}
|
|
4748
|
+
if (solderPaste.shape === "pill") {
|
|
4749
|
+
const width = solderPaste.width * Math.abs(transform.a);
|
|
4750
|
+
const height = solderPaste.height * Math.abs(transform.d);
|
|
4751
|
+
const radius = solderPaste.radius * Math.abs(transform.a);
|
|
4752
|
+
return [
|
|
4753
|
+
{
|
|
4754
|
+
name: "rect",
|
|
4755
|
+
type: "element",
|
|
4756
|
+
attributes: {
|
|
4757
|
+
class: "pcb-solder-paste",
|
|
4758
|
+
fill: solderPasteLayerNameToColor(solderPaste.layer),
|
|
4759
|
+
x: (x - width / 2).toString(),
|
|
4760
|
+
y: (y - height / 2).toString(),
|
|
4761
|
+
width: width.toString(),
|
|
4762
|
+
height: height.toString(),
|
|
4763
|
+
rx: radius.toString()
|
|
4764
|
+
}
|
|
4765
|
+
}
|
|
4766
|
+
];
|
|
4767
|
+
}
|
|
4768
|
+
if (solderPaste.shape === "circle") {
|
|
4769
|
+
const radius = solderPaste.radius * Math.abs(transform.a);
|
|
4770
|
+
return [
|
|
4771
|
+
{
|
|
4772
|
+
name: "circle",
|
|
4773
|
+
type: "element",
|
|
4774
|
+
attributes: {
|
|
4775
|
+
class: "pcb-solder-paste",
|
|
4776
|
+
fill: solderPasteLayerNameToColor(solderPaste.layer),
|
|
4777
|
+
cx: x.toString(),
|
|
4778
|
+
cy: y.toString(),
|
|
4779
|
+
r: radius.toString()
|
|
4780
|
+
}
|
|
4781
|
+
}
|
|
4782
|
+
];
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
|
|
4786
|
+
// lib/pcb/convert-circuit-json-to-solder-paste-mask.ts
|
|
4787
|
+
var OBJECT_ORDER3 = [
|
|
4788
|
+
"pcb_board",
|
|
4789
|
+
"pcb_solder_paste"
|
|
4790
|
+
];
|
|
4791
|
+
function convertCircuitJsonToSolderPasteMask(soup, options) {
|
|
4792
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
4793
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
4794
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
4795
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
4796
|
+
const filteredSoup = soup.filter(
|
|
4797
|
+
(elm) => elm.type === "pcb_board" || elm.type === "pcb_solder_paste" && elm.layer === options.layer
|
|
4798
|
+
);
|
|
4799
|
+
for (const item of filteredSoup) {
|
|
4800
|
+
if (item.type === "pcb_board") {
|
|
4801
|
+
if (item.outline && Array.isArray(item.outline) && item.outline.length >= 3) {
|
|
4802
|
+
updateBoundsToIncludeOutline(item.outline);
|
|
4803
|
+
} else if ("center" in item && "width" in item && "height" in item) {
|
|
4804
|
+
updateBounds(item.center, item.width, item.height);
|
|
4805
|
+
}
|
|
4806
|
+
} else if (item.type === "pcb_solder_paste" && "x" in item && "y" in item) {
|
|
4807
|
+
updateBounds({ x: item.x, y: item.y }, 0, 0);
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
const padding = 1;
|
|
4811
|
+
const circuitWidth = maxX - minX + 2 * padding;
|
|
4812
|
+
const circuitHeight = maxY - minY + 2 * padding;
|
|
4813
|
+
const svgWidth = options.width ?? 800;
|
|
4814
|
+
const svgHeight = options.height ?? 600;
|
|
4815
|
+
const scaleX = svgWidth / circuitWidth;
|
|
4816
|
+
const scaleY = svgHeight / circuitHeight;
|
|
4817
|
+
const scaleFactor = Math.min(scaleX, scaleY);
|
|
4818
|
+
const offsetX = (svgWidth - circuitWidth * scaleFactor) / 2;
|
|
4819
|
+
const offsetY = (svgHeight - circuitHeight * scaleFactor) / 2;
|
|
4820
|
+
const transform = compose10(
|
|
4821
|
+
translate10(
|
|
4822
|
+
offsetX - minX * scaleFactor + padding * scaleFactor,
|
|
4823
|
+
svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
|
|
4824
|
+
),
|
|
4825
|
+
scale8(scaleFactor, -scaleFactor)
|
|
4826
|
+
// Flip in y-direction
|
|
4827
|
+
);
|
|
4828
|
+
const svgObjects = filteredSoup.sort(
|
|
4829
|
+
(a, b) => (OBJECT_ORDER3.indexOf(b.type) ?? 9999) - (OBJECT_ORDER3.indexOf(a.type) ?? 9999)
|
|
4830
|
+
).flatMap((item) => createSvgObjects3(item, transform));
|
|
4831
|
+
const svgObject = {
|
|
4832
|
+
name: "svg",
|
|
4833
|
+
type: "element",
|
|
4834
|
+
attributes: {
|
|
4835
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4836
|
+
width: svgWidth.toString(),
|
|
4837
|
+
height: svgHeight.toString()
|
|
4838
|
+
},
|
|
4839
|
+
value: "",
|
|
4840
|
+
children: [
|
|
4841
|
+
{
|
|
4842
|
+
name: "style",
|
|
4843
|
+
type: "element",
|
|
4844
|
+
children: [
|
|
4845
|
+
{
|
|
4846
|
+
type: "text",
|
|
4847
|
+
value: ""
|
|
4848
|
+
}
|
|
4849
|
+
]
|
|
4850
|
+
},
|
|
4851
|
+
{
|
|
4852
|
+
name: "rect",
|
|
4853
|
+
type: "element",
|
|
4854
|
+
attributes: {
|
|
4855
|
+
class: "boundary",
|
|
4856
|
+
x: "0",
|
|
4857
|
+
y: "0",
|
|
4858
|
+
fill: "#000",
|
|
4859
|
+
width: svgWidth.toString(),
|
|
4860
|
+
height: svgHeight.toString()
|
|
4861
|
+
}
|
|
4862
|
+
},
|
|
4863
|
+
createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY),
|
|
4864
|
+
...svgObjects
|
|
4865
|
+
].filter((child) => child !== null)
|
|
4866
|
+
};
|
|
4867
|
+
try {
|
|
4868
|
+
return stringify4(svgObject);
|
|
4869
|
+
} catch (error) {
|
|
4870
|
+
console.error("Error stringifying SVG object:", error);
|
|
4871
|
+
throw error;
|
|
4872
|
+
}
|
|
4873
|
+
function updateBounds(center, width, height) {
|
|
4874
|
+
const halfWidth = width / 2;
|
|
4875
|
+
const halfHeight = height / 2;
|
|
4876
|
+
minX = Math.min(minX, center.x - halfWidth);
|
|
4877
|
+
minY = Math.min(minY, center.y - halfHeight);
|
|
4878
|
+
maxX = Math.max(maxX, center.x + halfWidth);
|
|
4879
|
+
maxY = Math.max(maxY, center.y + halfHeight);
|
|
4880
|
+
}
|
|
4881
|
+
function updateBoundsToIncludeOutline(outline) {
|
|
4882
|
+
for (const point of outline) {
|
|
4883
|
+
minX = Math.min(minX, point.x);
|
|
4884
|
+
minY = Math.min(minY, point.y);
|
|
4885
|
+
maxX = Math.max(maxX, point.x);
|
|
4886
|
+
maxY = Math.max(maxY, point.y);
|
|
4887
|
+
}
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4890
|
+
function createSvgObjects3(elm, transform) {
|
|
4891
|
+
switch (elm.type) {
|
|
4892
|
+
case "pcb_board":
|
|
4893
|
+
return createSvgObjectsFromPcbBoard(elm, transform);
|
|
4894
|
+
case "pcb_solder_paste":
|
|
4895
|
+
return createSvgObjectsFromSolderPaste(elm, transform);
|
|
4896
|
+
default:
|
|
4897
|
+
return [];
|
|
4898
|
+
}
|
|
4899
|
+
}
|
|
4900
|
+
function createSvgObjectFromPcbBoundary2(transform, minX, minY, maxX, maxY) {
|
|
4901
|
+
const [x1, y1] = applyToPoint38(transform, [minX, minY]);
|
|
4902
|
+
const [x2, y2] = applyToPoint38(transform, [maxX, maxY]);
|
|
4903
|
+
const width = Math.abs(x2 - x1);
|
|
4904
|
+
const height = Math.abs(y2 - y1);
|
|
4905
|
+
const x = Math.min(x1, x2);
|
|
4906
|
+
const y = Math.min(y1, y2);
|
|
4907
|
+
return {
|
|
4908
|
+
name: "rect",
|
|
4909
|
+
type: "element",
|
|
4910
|
+
value: "",
|
|
4911
|
+
children: [],
|
|
4912
|
+
attributes: {
|
|
4913
|
+
class: "pcb-boundary",
|
|
4914
|
+
fill: "none",
|
|
4915
|
+
stroke: "#fff",
|
|
4916
|
+
"stroke-width": "0.3",
|
|
4917
|
+
x: x.toString(),
|
|
4918
|
+
y: y.toString(),
|
|
4919
|
+
width: width.toString(),
|
|
4920
|
+
height: height.toString()
|
|
4921
|
+
}
|
|
4922
|
+
};
|
|
4923
|
+
}
|
|
4662
4924
|
export {
|
|
4663
4925
|
circuitJsonToPcbSvg,
|
|
4664
4926
|
circuitJsonToSchematicSvg,
|
|
4665
4927
|
convertCircuitJsonToAssemblySvg,
|
|
4666
4928
|
convertCircuitJsonToPcbSvg,
|
|
4667
|
-
convertCircuitJsonToSchematicSvg
|
|
4929
|
+
convertCircuitJsonToSchematicSvg,
|
|
4930
|
+
convertCircuitJsonToSolderPasteMask
|
|
4668
4931
|
};
|
|
4669
4932
|
//# sourceMappingURL=index.js.map
|