circuit-to-canvas 0.0.43 → 0.0.44
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 +27 -9
- package/lib/drawer/elements/pcb-hole.ts +21 -1
- package/package.json +1 -1
- package/tests/elements/__snapshots__/rotated-oval-hole.snap.png +0 -0
- package/tests/elements/__snapshots__/rotated-pill-hole.snap.png +0 -0
- package/tests/elements/__snapshots__/rotated-rect-hole.snap.png +0 -0
- package/tests/elements/__snapshots__/rotated-square-hole.snap.png +0 -0
- package/tests/elements/pcb-hole.test.ts +107 -0
package/dist/index.js
CHANGED
|
@@ -816,6 +816,12 @@ function drawPcbVia(params) {
|
|
|
816
816
|
}
|
|
817
817
|
|
|
818
818
|
// lib/drawer/elements/pcb-hole.ts
|
|
819
|
+
function getRotation(hole) {
|
|
820
|
+
if ("ccw_rotation" in hole && typeof hole.ccw_rotation === "number") {
|
|
821
|
+
return hole.ccw_rotation;
|
|
822
|
+
}
|
|
823
|
+
return 0;
|
|
824
|
+
}
|
|
819
825
|
function drawPcbHole(params) {
|
|
820
826
|
const { ctx, hole, realToCanvasMat, colorMap } = params;
|
|
821
827
|
const hasSoldermask = hole.is_covered_with_solder_mask === true && hole.soldermask_margin !== void 0 && hole.soldermask_margin > 0;
|
|
@@ -841,6 +847,7 @@ function drawPcbHole(params) {
|
|
|
841
847
|
return;
|
|
842
848
|
}
|
|
843
849
|
if (hole.hole_shape === "square") {
|
|
850
|
+
const rotation = getRotation(hole);
|
|
844
851
|
if (hasSoldermask && margin > 0) {
|
|
845
852
|
drawRect({
|
|
846
853
|
ctx,
|
|
@@ -848,7 +855,8 @@ function drawPcbHole(params) {
|
|
|
848
855
|
width: hole.hole_diameter + margin * 2,
|
|
849
856
|
height: hole.hole_diameter + margin * 2,
|
|
850
857
|
fill: positiveMarginColor,
|
|
851
|
-
realToCanvasMat
|
|
858
|
+
realToCanvasMat,
|
|
859
|
+
rotation
|
|
852
860
|
});
|
|
853
861
|
}
|
|
854
862
|
drawRect({
|
|
@@ -857,11 +865,13 @@ function drawPcbHole(params) {
|
|
|
857
865
|
width: hole.hole_diameter,
|
|
858
866
|
height: hole.hole_diameter,
|
|
859
867
|
fill: colorMap.drill,
|
|
860
|
-
realToCanvasMat
|
|
868
|
+
realToCanvasMat,
|
|
869
|
+
rotation
|
|
861
870
|
});
|
|
862
871
|
return;
|
|
863
872
|
}
|
|
864
873
|
if (hole.hole_shape === "oval") {
|
|
874
|
+
const rotation = getRotation(hole);
|
|
865
875
|
if (hasSoldermask && margin > 0) {
|
|
866
876
|
drawOval({
|
|
867
877
|
ctx,
|
|
@@ -869,7 +879,8 @@ function drawPcbHole(params) {
|
|
|
869
879
|
radius_x: hole.hole_width / 2 + margin,
|
|
870
880
|
radius_y: hole.hole_height / 2 + margin,
|
|
871
881
|
fill: positiveMarginColor,
|
|
872
|
-
realToCanvasMat
|
|
882
|
+
realToCanvasMat,
|
|
883
|
+
rotation
|
|
873
884
|
});
|
|
874
885
|
}
|
|
875
886
|
drawOval({
|
|
@@ -878,11 +889,13 @@ function drawPcbHole(params) {
|
|
|
878
889
|
radius_x: hole.hole_width / 2,
|
|
879
890
|
radius_y: hole.hole_height / 2,
|
|
880
891
|
fill: colorMap.drill,
|
|
881
|
-
realToCanvasMat
|
|
892
|
+
realToCanvasMat,
|
|
893
|
+
rotation
|
|
882
894
|
});
|
|
883
895
|
return;
|
|
884
896
|
}
|
|
885
897
|
if (hole.hole_shape === "rect") {
|
|
898
|
+
const rotation = getRotation(hole);
|
|
886
899
|
if (hasSoldermask && margin > 0) {
|
|
887
900
|
drawRect({
|
|
888
901
|
ctx,
|
|
@@ -890,7 +903,8 @@ function drawPcbHole(params) {
|
|
|
890
903
|
width: hole.hole_width + margin * 2,
|
|
891
904
|
height: hole.hole_height + margin * 2,
|
|
892
905
|
fill: positiveMarginColor,
|
|
893
|
-
realToCanvasMat
|
|
906
|
+
realToCanvasMat,
|
|
907
|
+
rotation
|
|
894
908
|
});
|
|
895
909
|
}
|
|
896
910
|
drawRect({
|
|
@@ -899,11 +913,13 @@ function drawPcbHole(params) {
|
|
|
899
913
|
width: hole.hole_width,
|
|
900
914
|
height: hole.hole_height,
|
|
901
915
|
fill: colorMap.drill,
|
|
902
|
-
realToCanvasMat
|
|
916
|
+
realToCanvasMat,
|
|
917
|
+
rotation
|
|
903
918
|
});
|
|
904
919
|
return;
|
|
905
920
|
}
|
|
906
921
|
if (hole.hole_shape === "pill") {
|
|
922
|
+
const rotation = getRotation(hole);
|
|
907
923
|
if (hasSoldermask && margin > 0) {
|
|
908
924
|
drawPill({
|
|
909
925
|
ctx,
|
|
@@ -911,7 +927,8 @@ function drawPcbHole(params) {
|
|
|
911
927
|
width: hole.hole_width + margin * 2,
|
|
912
928
|
height: hole.hole_height + margin * 2,
|
|
913
929
|
fill: positiveMarginColor,
|
|
914
|
-
realToCanvasMat
|
|
930
|
+
realToCanvasMat,
|
|
931
|
+
rotation
|
|
915
932
|
});
|
|
916
933
|
}
|
|
917
934
|
drawPill({
|
|
@@ -920,12 +937,13 @@ function drawPcbHole(params) {
|
|
|
920
937
|
width: hole.hole_width,
|
|
921
938
|
height: hole.hole_height,
|
|
922
939
|
fill: colorMap.drill,
|
|
923
|
-
realToCanvasMat
|
|
940
|
+
realToCanvasMat,
|
|
941
|
+
rotation
|
|
924
942
|
});
|
|
925
943
|
return;
|
|
926
944
|
}
|
|
927
945
|
if (hole.hole_shape === "rotated_pill") {
|
|
928
|
-
const rotation = hole
|
|
946
|
+
const rotation = getRotation(hole);
|
|
929
947
|
if (hasSoldermask && margin > 0) {
|
|
930
948
|
drawPill({
|
|
931
949
|
ctx,
|
|
@@ -13,6 +13,14 @@ export interface DrawPcbHoleParams {
|
|
|
13
13
|
colorMap: PcbColorMap
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
// Helper function to safely access ccw_rotation property
|
|
17
|
+
function getRotation(hole: PCBHole): number {
|
|
18
|
+
if ("ccw_rotation" in hole && typeof hole.ccw_rotation === "number") {
|
|
19
|
+
return hole.ccw_rotation
|
|
20
|
+
}
|
|
21
|
+
return 0
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
17
25
|
const { ctx, hole, realToCanvasMat, colorMap } = params
|
|
18
26
|
|
|
@@ -47,6 +55,7 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
if (hole.hole_shape === "square") {
|
|
58
|
+
const rotation = getRotation(hole)
|
|
50
59
|
// For positive margins, draw extended mask area first
|
|
51
60
|
if (hasSoldermask && margin > 0) {
|
|
52
61
|
drawRect({
|
|
@@ -56,6 +65,7 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
56
65
|
height: hole.hole_diameter + margin * 2,
|
|
57
66
|
fill: positiveMarginColor,
|
|
58
67
|
realToCanvasMat,
|
|
68
|
+
rotation,
|
|
59
69
|
})
|
|
60
70
|
}
|
|
61
71
|
|
|
@@ -67,11 +77,13 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
67
77
|
height: hole.hole_diameter,
|
|
68
78
|
fill: colorMap.drill,
|
|
69
79
|
realToCanvasMat,
|
|
80
|
+
rotation,
|
|
70
81
|
})
|
|
71
82
|
return
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
if (hole.hole_shape === "oval") {
|
|
86
|
+
const rotation = getRotation(hole)
|
|
75
87
|
// For positive margins, draw extended mask area first
|
|
76
88
|
if (hasSoldermask && margin > 0) {
|
|
77
89
|
drawOval({
|
|
@@ -81,6 +93,7 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
81
93
|
radius_y: hole.hole_height / 2 + margin,
|
|
82
94
|
fill: positiveMarginColor,
|
|
83
95
|
realToCanvasMat,
|
|
96
|
+
rotation,
|
|
84
97
|
})
|
|
85
98
|
}
|
|
86
99
|
|
|
@@ -92,11 +105,13 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
92
105
|
radius_y: hole.hole_height / 2,
|
|
93
106
|
fill: colorMap.drill,
|
|
94
107
|
realToCanvasMat,
|
|
108
|
+
rotation,
|
|
95
109
|
})
|
|
96
110
|
return
|
|
97
111
|
}
|
|
98
112
|
|
|
99
113
|
if (hole.hole_shape === "rect") {
|
|
114
|
+
const rotation = getRotation(hole)
|
|
100
115
|
// For positive margins, draw extended mask area first
|
|
101
116
|
if (hasSoldermask && margin > 0) {
|
|
102
117
|
drawRect({
|
|
@@ -106,6 +121,7 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
106
121
|
height: hole.hole_height + margin * 2,
|
|
107
122
|
fill: positiveMarginColor,
|
|
108
123
|
realToCanvasMat,
|
|
124
|
+
rotation,
|
|
109
125
|
})
|
|
110
126
|
}
|
|
111
127
|
|
|
@@ -117,11 +133,13 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
117
133
|
height: hole.hole_height,
|
|
118
134
|
fill: colorMap.drill,
|
|
119
135
|
realToCanvasMat,
|
|
136
|
+
rotation,
|
|
120
137
|
})
|
|
121
138
|
return
|
|
122
139
|
}
|
|
123
140
|
|
|
124
141
|
if (hole.hole_shape === "pill") {
|
|
142
|
+
const rotation = getRotation(hole)
|
|
125
143
|
// For positive margins, draw extended mask area first
|
|
126
144
|
if (hasSoldermask && margin > 0) {
|
|
127
145
|
drawPill({
|
|
@@ -131,6 +149,7 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
131
149
|
height: hole.hole_height + margin * 2,
|
|
132
150
|
fill: positiveMarginColor,
|
|
133
151
|
realToCanvasMat,
|
|
152
|
+
rotation,
|
|
134
153
|
})
|
|
135
154
|
}
|
|
136
155
|
|
|
@@ -142,12 +161,13 @@ export function drawPcbHole(params: DrawPcbHoleParams): void {
|
|
|
142
161
|
height: hole.hole_height,
|
|
143
162
|
fill: colorMap.drill,
|
|
144
163
|
realToCanvasMat,
|
|
164
|
+
rotation,
|
|
145
165
|
})
|
|
146
166
|
return
|
|
147
167
|
}
|
|
148
168
|
|
|
149
169
|
if (hole.hole_shape === "rotated_pill") {
|
|
150
|
-
const rotation = (hole
|
|
170
|
+
const rotation = getRotation(hole)
|
|
151
171
|
|
|
152
172
|
// For positive margins, draw extended mask area first
|
|
153
173
|
if (hasSoldermask && margin > 0) {
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -103,3 +103,110 @@ test("draw pill hole", async () => {
|
|
|
103
103
|
"pill-hole",
|
|
104
104
|
)
|
|
105
105
|
})
|
|
106
|
+
|
|
107
|
+
test("draw rotated oval hole", async () => {
|
|
108
|
+
const canvas = createCanvas(100, 100)
|
|
109
|
+
const ctx = canvas.getContext("2d")
|
|
110
|
+
const drawer = new CircuitToCanvasDrawer(ctx)
|
|
111
|
+
|
|
112
|
+
ctx.fillStyle = "#1a1a1a"
|
|
113
|
+
ctx.fillRect(0, 0, 100, 100)
|
|
114
|
+
|
|
115
|
+
const hole: PCBHole & { ccw_rotation?: number } = {
|
|
116
|
+
type: "pcb_hole",
|
|
117
|
+
pcb_hole_id: "hole1",
|
|
118
|
+
hole_shape: "oval",
|
|
119
|
+
hole_width: 50,
|
|
120
|
+
hole_height: 30,
|
|
121
|
+
x: 50,
|
|
122
|
+
y: 50,
|
|
123
|
+
ccw_rotation: 45,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
drawer.drawElements([hole])
|
|
127
|
+
|
|
128
|
+
await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
|
|
129
|
+
import.meta.path,
|
|
130
|
+
"rotated-oval-hole",
|
|
131
|
+
)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test("draw rotated rect hole", async () => {
|
|
135
|
+
const canvas = createCanvas(100, 100)
|
|
136
|
+
const ctx = canvas.getContext("2d")
|
|
137
|
+
const drawer = new CircuitToCanvasDrawer(ctx)
|
|
138
|
+
|
|
139
|
+
ctx.fillStyle = "#1a1a1a"
|
|
140
|
+
ctx.fillRect(0, 0, 100, 100)
|
|
141
|
+
|
|
142
|
+
const hole: PCBHole & { ccw_rotation?: number } = {
|
|
143
|
+
type: "pcb_hole",
|
|
144
|
+
pcb_hole_id: "hole1",
|
|
145
|
+
hole_shape: "rect",
|
|
146
|
+
hole_width: 50,
|
|
147
|
+
hole_height: 30,
|
|
148
|
+
x: 50,
|
|
149
|
+
y: 50,
|
|
150
|
+
ccw_rotation: 45,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
drawer.drawElements([hole])
|
|
154
|
+
|
|
155
|
+
await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
|
|
156
|
+
import.meta.path,
|
|
157
|
+
"rotated-rect-hole",
|
|
158
|
+
)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
test("draw rotated square hole", async () => {
|
|
162
|
+
const canvas = createCanvas(100, 100)
|
|
163
|
+
const ctx = canvas.getContext("2d")
|
|
164
|
+
const drawer = new CircuitToCanvasDrawer(ctx)
|
|
165
|
+
|
|
166
|
+
ctx.fillStyle = "#1a1a1a"
|
|
167
|
+
ctx.fillRect(0, 0, 100, 100)
|
|
168
|
+
|
|
169
|
+
const hole: PCBHole & { ccw_rotation?: number } = {
|
|
170
|
+
type: "pcb_hole",
|
|
171
|
+
pcb_hole_id: "hole1",
|
|
172
|
+
hole_shape: "square",
|
|
173
|
+
hole_diameter: 30,
|
|
174
|
+
x: 50,
|
|
175
|
+
y: 50,
|
|
176
|
+
ccw_rotation: 45,
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
drawer.drawElements([hole])
|
|
180
|
+
|
|
181
|
+
await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
|
|
182
|
+
import.meta.path,
|
|
183
|
+
"rotated-square-hole",
|
|
184
|
+
)
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
test("draw rotated pill hole", async () => {
|
|
188
|
+
const canvas = createCanvas(100, 100)
|
|
189
|
+
const ctx = canvas.getContext("2d")
|
|
190
|
+
const drawer = new CircuitToCanvasDrawer(ctx)
|
|
191
|
+
|
|
192
|
+
ctx.fillStyle = "#1a1a1a"
|
|
193
|
+
ctx.fillRect(0, 0, 100, 100)
|
|
194
|
+
|
|
195
|
+
const hole: PCBHole & { ccw_rotation?: number } = {
|
|
196
|
+
type: "pcb_hole",
|
|
197
|
+
pcb_hole_id: "hole1",
|
|
198
|
+
hole_shape: "pill",
|
|
199
|
+
hole_width: 60,
|
|
200
|
+
hole_height: 30,
|
|
201
|
+
x: 50,
|
|
202
|
+
y: 50,
|
|
203
|
+
ccw_rotation: 45,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
drawer.drawElements([hole])
|
|
207
|
+
|
|
208
|
+
await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
|
|
209
|
+
import.meta.path,
|
|
210
|
+
"rotated-pill-hole",
|
|
211
|
+
)
|
|
212
|
+
})
|