circuit-to-canvas 0.0.30 → 0.0.31
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 +27 -1
- package/dist/index.js +401 -24
- package/lib/drawer/CircuitToCanvasDrawer.ts +105 -2
- package/lib/drawer/elements/index.ts +5 -0
- package/lib/drawer/elements/pcb-smtpad.ts +174 -0
- package/lib/drawer/elements/soldermask-margin.ts +266 -0
- package/package.json +1 -1
- package/tests/elements/__snapshots__/pcb-smtpad-soldermask-margin.snap.png +0 -0
- package/tests/elements/pcb-smtpad-soldermask-margin.test.ts +163 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { createCanvas } from "@napi-rs/canvas"
|
|
3
|
+
import { CircuitToCanvasDrawer } from "../../lib/drawer"
|
|
4
|
+
|
|
5
|
+
test("draw smt pads with positive and negative soldermask margins", async () => {
|
|
6
|
+
const canvas = createCanvas(800, 600)
|
|
7
|
+
const ctx = canvas.getContext("2d")
|
|
8
|
+
const drawer = new CircuitToCanvasDrawer(ctx)
|
|
9
|
+
|
|
10
|
+
ctx.fillStyle = "#1a1a1a"
|
|
11
|
+
ctx.fillRect(0, 0, 800, 600)
|
|
12
|
+
|
|
13
|
+
const circuit: any = [
|
|
14
|
+
{
|
|
15
|
+
type: "pcb_board",
|
|
16
|
+
pcb_board_id: "board0",
|
|
17
|
+
center: { x: 0, y: 0 },
|
|
18
|
+
width: 14,
|
|
19
|
+
height: 10,
|
|
20
|
+
},
|
|
21
|
+
// Rectangle with positive margin (mask extends beyond pad)
|
|
22
|
+
{
|
|
23
|
+
type: "pcb_smtpad",
|
|
24
|
+
pcb_smtpad_id: "pad_rect_positive",
|
|
25
|
+
shape: "rect",
|
|
26
|
+
layer: "top",
|
|
27
|
+
x: -4,
|
|
28
|
+
y: 2,
|
|
29
|
+
width: 1.6,
|
|
30
|
+
height: 1.1,
|
|
31
|
+
is_covered_with_solder_mask: true,
|
|
32
|
+
soldermask_margin: 0.2,
|
|
33
|
+
},
|
|
34
|
+
// Rectangle with negative margin (spacing around copper, copper visible)
|
|
35
|
+
{
|
|
36
|
+
type: "pcb_smtpad",
|
|
37
|
+
pcb_smtpad_id: "pad_rect_negative",
|
|
38
|
+
shape: "rect",
|
|
39
|
+
layer: "top",
|
|
40
|
+
x: -4,
|
|
41
|
+
y: -2,
|
|
42
|
+
width: 1.6,
|
|
43
|
+
height: 1.1,
|
|
44
|
+
is_covered_with_solder_mask: true,
|
|
45
|
+
soldermask_margin: -0.15,
|
|
46
|
+
},
|
|
47
|
+
// Circle with positive margin
|
|
48
|
+
{
|
|
49
|
+
type: "pcb_smtpad",
|
|
50
|
+
pcb_smtpad_id: "pad_circle_positive",
|
|
51
|
+
shape: "circle",
|
|
52
|
+
layer: "top",
|
|
53
|
+
x: 0,
|
|
54
|
+
y: 2,
|
|
55
|
+
radius: 0.75,
|
|
56
|
+
is_covered_with_solder_mask: true,
|
|
57
|
+
soldermask_margin: 0.15,
|
|
58
|
+
},
|
|
59
|
+
// Circle with negative margin
|
|
60
|
+
{
|
|
61
|
+
type: "pcb_smtpad",
|
|
62
|
+
pcb_smtpad_id: "pad_circle_negative",
|
|
63
|
+
shape: "circle",
|
|
64
|
+
layer: "top",
|
|
65
|
+
x: 0,
|
|
66
|
+
y: -2,
|
|
67
|
+
radius: 0.75,
|
|
68
|
+
is_covered_with_solder_mask: true,
|
|
69
|
+
soldermask_margin: -0.2,
|
|
70
|
+
},
|
|
71
|
+
// Pill with positive margin
|
|
72
|
+
{
|
|
73
|
+
type: "pcb_smtpad",
|
|
74
|
+
pcb_smtpad_id: "pad_pill_positive",
|
|
75
|
+
shape: "pill",
|
|
76
|
+
layer: "top",
|
|
77
|
+
x: 4,
|
|
78
|
+
y: 2,
|
|
79
|
+
width: 2.4,
|
|
80
|
+
height: 1,
|
|
81
|
+
radius: 0.5,
|
|
82
|
+
is_covered_with_solder_mask: true,
|
|
83
|
+
soldermask_margin: 0.1,
|
|
84
|
+
},
|
|
85
|
+
// Pill with negative margin
|
|
86
|
+
{
|
|
87
|
+
type: "pcb_smtpad",
|
|
88
|
+
pcb_smtpad_id: "pad_pill_negative",
|
|
89
|
+
shape: "pill",
|
|
90
|
+
layer: "top",
|
|
91
|
+
x: 4,
|
|
92
|
+
y: -2,
|
|
93
|
+
width: 2.4,
|
|
94
|
+
height: 1,
|
|
95
|
+
radius: 0.5,
|
|
96
|
+
is_covered_with_solder_mask: true,
|
|
97
|
+
soldermask_margin: -0.12,
|
|
98
|
+
},
|
|
99
|
+
// Silkscreen labels for positive margin pads (top row)
|
|
100
|
+
{
|
|
101
|
+
type: "pcb_silkscreen_text",
|
|
102
|
+
pcb_silkscreen_text_id: "text_rect_pos",
|
|
103
|
+
layer: "top",
|
|
104
|
+
anchor_position: { x: -4, y: 3.2 },
|
|
105
|
+
anchor_alignment: "center",
|
|
106
|
+
text: "+0.2mm",
|
|
107
|
+
font_size: 0.4,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: "pcb_silkscreen_text",
|
|
111
|
+
pcb_silkscreen_text_id: "text_circle_pos",
|
|
112
|
+
layer: "top",
|
|
113
|
+
anchor_position: { x: 0, y: 3.2 },
|
|
114
|
+
anchor_alignment: "center",
|
|
115
|
+
text: "+0.15mm",
|
|
116
|
+
font_size: 0.4,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
type: "pcb_silkscreen_text",
|
|
120
|
+
pcb_silkscreen_text_id: "text_pill_pos",
|
|
121
|
+
layer: "top",
|
|
122
|
+
anchor_position: { x: 4, y: 3.2 },
|
|
123
|
+
anchor_alignment: "center",
|
|
124
|
+
text: "+0.1mm",
|
|
125
|
+
font_size: 0.4,
|
|
126
|
+
},
|
|
127
|
+
// Silkscreen labels for negative margin pads (bottom row)
|
|
128
|
+
{
|
|
129
|
+
type: "pcb_silkscreen_text",
|
|
130
|
+
pcb_silkscreen_text_id: "text_rect_neg",
|
|
131
|
+
layer: "top",
|
|
132
|
+
anchor_position: { x: -4, y: -3.2 },
|
|
133
|
+
anchor_alignment: "center",
|
|
134
|
+
text: "-0.15mm",
|
|
135
|
+
font_size: 0.4,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: "pcb_silkscreen_text",
|
|
139
|
+
pcb_silkscreen_text_id: "text_circle_neg",
|
|
140
|
+
layer: "top",
|
|
141
|
+
anchor_position: { x: 0, y: -3.2 },
|
|
142
|
+
anchor_alignment: "center",
|
|
143
|
+
text: "-0.2mm",
|
|
144
|
+
font_size: 0.4,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
type: "pcb_silkscreen_text",
|
|
148
|
+
pcb_silkscreen_text_id: "text_pill_neg",
|
|
149
|
+
layer: "top",
|
|
150
|
+
anchor_position: { x: 4, y: -3.2 },
|
|
151
|
+
anchor_alignment: "center",
|
|
152
|
+
text: "-0.12mm",
|
|
153
|
+
font_size: 0.4,
|
|
154
|
+
},
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
drawer.setCameraBounds({ minX: -7, maxX: 7, minY: -5, maxY: 5 })
|
|
158
|
+
drawer.drawElements(circuit)
|
|
159
|
+
|
|
160
|
+
await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
|
|
161
|
+
import.meta.path,
|
|
162
|
+
)
|
|
163
|
+
})
|