circuit-to-canvas 0.0.55 → 0.0.56

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 CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyCircuitElement, PcbRenderLayer, NinePointAnchor, PcbPlatedHole, PCBVia, PcbHole, PcbSmtPad, PCBTrace, PcbBoard, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbSilkscreenPill, PcbSilkscreenOval, PcbCutout, PCBKeepout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText, PcbNoteDimension, PcbFabricationNoteDimension } from 'circuit-json';
1
+ import { AnyCircuitElement, PcbRenderLayer, NinePointAnchor, PcbPlatedHole, PCBVia, PcbHole, PcbSmtPad, PCBTrace, PcbBoard, PcbPanel, PcbSilkscreenText, PcbSilkscreenRect, PcbSilkscreenCircle, PcbSilkscreenLine, PcbSilkscreenPath, PcbSilkscreenPill, PcbSilkscreenOval, PcbCutout, PCBKeepout, PcbCopperPour, PcbCopperText, PcbFabricationNoteText, PcbFabricationNoteRect, PcbNoteRect, PcbFabricationNotePath, PcbNotePath, PcbNoteText, PcbNoteDimension, PcbFabricationNoteDimension } from 'circuit-json';
2
2
  import { Matrix } from 'transformation-matrix';
3
3
 
4
4
  /**
@@ -384,6 +384,15 @@ interface DrawPcbBoardParams {
384
384
  }
385
385
  declare function drawPcbBoard(params: DrawPcbBoardParams): void;
386
386
 
387
+ interface DrawPcbPanelParams {
388
+ ctx: CanvasContext;
389
+ panel: PcbPanel;
390
+ realToCanvasMat: Matrix;
391
+ colorMap: PcbColorMap;
392
+ drawBoardMaterial: boolean;
393
+ }
394
+ declare function drawPcbPanelElement(params: DrawPcbPanelParams): void;
395
+
387
396
  interface DrawPcbSilkscreenTextParams {
388
397
  ctx: CanvasContext;
389
398
  text: PcbSilkscreenText;
@@ -536,4 +545,4 @@ interface DrawPcbFabricationNoteDimensionParams {
536
545
  }
537
546
  declare function drawPcbFabricationNoteDimension(params: DrawPcbFabricationNoteDimensionParams): void;
538
547
 
539
- export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawArrowParams, type DrawCircleParams, type DrawContext, type DrawDimensionLineParams, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNoteDimensionParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbKeepoutParams, type DrawPcbNoteDimensionParams, type DrawPcbNotePathParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenOvalParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenPillParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawArrow, drawCircle, drawDimensionLine, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNoteDimension, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbKeepout, drawPcbNoteDimension, drawPcbNotePath, drawPcbNoteRect, drawPcbNoteText, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenOval, drawPcbSilkscreenPath, drawPcbSilkscreenPill, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawSoldermaskRingForCircle, drawSoldermaskRingForOval, drawSoldermaskRingForPill, drawSoldermaskRingForRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
548
+ export { type AlphabetLayout, type AnchorAlignment, type CameraBounds, type CanvasContext, CircuitToCanvasDrawer, type CopperColorMap, type CopperLayerName, DEFAULT_PCB_COLOR_MAP, type DrawArrowParams, type DrawCircleParams, type DrawContext, type DrawDimensionLineParams, type DrawElementsOptions, type DrawLineParams, type DrawOvalParams, type DrawPathParams, type DrawPcbBoardParams, type DrawPcbCopperPourParams, type DrawPcbCopperTextParams, type DrawPcbCutoutParams, type DrawPcbFabricationNoteDimensionParams, type DrawPcbFabricationNotePathParams, type DrawPcbFabricationNoteRectParams, type DrawPcbFabricationNoteTextParams, type DrawPcbHoleParams, type DrawPcbKeepoutParams, type DrawPcbNoteDimensionParams, type DrawPcbNotePathParams, type DrawPcbNoteRectParams, type DrawPcbNoteTextParams, type DrawPcbPanelParams, type DrawPcbPlatedHoleParams, type DrawPcbSilkscreenCircleParams, type DrawPcbSilkscreenLineParams, type DrawPcbSilkscreenOvalParams, type DrawPcbSilkscreenPathParams, type DrawPcbSilkscreenPillParams, type DrawPcbSilkscreenRectParams, type DrawPcbSilkscreenTextParams, type DrawPcbSmtPadParams, type DrawPcbTraceParams, type DrawPcbViaParams, type DrawPillParams, type DrawPolygonParams, type DrawRectParams, type DrawTextParams, type DrawerConfig, type PcbColorMap, drawArrow, drawCircle, drawDimensionLine, drawLine, drawOval, drawPath, drawPcbBoard, drawPcbCopperPour, drawPcbCopperText, drawPcbCutout, drawPcbFabricationNoteDimension, drawPcbFabricationNotePath, drawPcbFabricationNoteRect, drawPcbFabricationNoteText, drawPcbHole, drawPcbKeepout, drawPcbNoteDimension, drawPcbNotePath, drawPcbNoteRect, drawPcbNoteText, drawPcbPanelElement, drawPcbPlatedHole, drawPcbSilkscreenCircle, drawPcbSilkscreenLine, drawPcbSilkscreenOval, drawPcbSilkscreenPath, drawPcbSilkscreenPill, drawPcbSilkscreenRect, drawPcbSilkscreenText, drawPcbSmtPad, drawPcbTrace, drawPcbVia, drawPill, drawPolygon, drawRect, drawSoldermaskRingForCircle, drawSoldermaskRingForOval, drawSoldermaskRingForPill, drawSoldermaskRingForRect, drawText, getAlphabetLayout, getTextStartPosition, strokeAlphabetText };
package/dist/index.js CHANGED
@@ -1351,6 +1351,40 @@ function drawPcbNoteText(params) {
1351
1351
  });
1352
1352
  }
1353
1353
 
1354
+ // lib/drawer/elements/pcb-panel.ts
1355
+ function drawPcbPanelElement(params) {
1356
+ const { ctx, panel, realToCanvasMat, colorMap, drawBoardMaterial } = params;
1357
+ const { width, height, center } = panel;
1358
+ if (width !== void 0 && height !== void 0 && center) {
1359
+ if (drawBoardMaterial) {
1360
+ drawRect({
1361
+ ctx,
1362
+ center,
1363
+ width,
1364
+ height,
1365
+ fill: colorMap.substrate,
1366
+ realToCanvasMat
1367
+ });
1368
+ }
1369
+ const halfWidth = width / 2;
1370
+ const halfHeight = height / 2;
1371
+ const corners = [
1372
+ { x: center.x - halfWidth, y: center.y - halfHeight },
1373
+ { x: center.x + halfWidth, y: center.y - halfHeight },
1374
+ { x: center.x + halfWidth, y: center.y + halfHeight },
1375
+ { x: center.x - halfWidth, y: center.y + halfHeight }
1376
+ ];
1377
+ drawPath({
1378
+ ctx,
1379
+ points: corners,
1380
+ stroke: colorMap.boardOutline,
1381
+ strokeWidth: 0.5,
1382
+ realToCanvasMat,
1383
+ closePath: true
1384
+ });
1385
+ }
1386
+ }
1387
+
1354
1388
  // lib/drawer/elements/soldermask-margin.ts
1355
1389
  import { applyToPoint as applyToPoint14 } from "transformation-matrix";
1356
1390
  function drawSoldermaskRingForRect(ctx, center, width, height, margin, borderRadius, rotation, realToCanvasMat, soldermaskColor, padColor, asymmetricMargins) {
@@ -3204,6 +3238,16 @@ var CircuitToCanvasDrawer = class {
3204
3238
  }
3205
3239
  drawElements(elements, options = {}) {
3206
3240
  const board = elements.find((el) => el.type === "pcb_board");
3241
+ const panel = elements.find((el) => el.type === "pcb_panel");
3242
+ if (panel) {
3243
+ drawPcbPanelElement({
3244
+ ctx: this.ctx,
3245
+ panel,
3246
+ realToCanvasMat: this.realToCanvasMat,
3247
+ colorMap: this.colorMap,
3248
+ drawBoardMaterial: options.drawBoardMaterial ?? false
3249
+ });
3250
+ }
3207
3251
  if (board) {
3208
3252
  drawPcbBoard({
3209
3253
  ctx: this.ctx,
@@ -3487,6 +3531,7 @@ export {
3487
3531
  drawPcbNotePath,
3488
3532
  drawPcbNoteRect,
3489
3533
  drawPcbNoteText,
3534
+ drawPcbPanelElement,
3490
3535
  drawPcbPlatedHole,
3491
3536
  drawPcbSilkscreenCircle,
3492
3537
  drawPcbSilkscreenLine,
@@ -15,6 +15,7 @@ import type {
15
15
  PcbNotePath,
16
16
  PcbNoteRect,
17
17
  PcbNoteText,
18
+ PcbPanel,
18
19
  PcbPlatedHole,
19
20
  PcbRenderLayer,
20
21
  PcbSilkscreenCircle,
@@ -51,6 +52,7 @@ import { drawPcbNoteLine } from "./elements/pcb-note-line"
51
52
  import { drawPcbNotePath } from "./elements/pcb-note-path"
52
53
  import { drawPcbNoteRect } from "./elements/pcb-note-rect"
53
54
  import { drawPcbNoteText } from "./elements/pcb-note-text"
55
+ import { drawPcbPanelElement } from "./elements/pcb-panel"
54
56
  import { drawPcbPlatedHole } from "./elements/pcb-plated-hole"
55
57
  import { drawPcbSilkscreenCircle } from "./elements/pcb-silkscreen-circle"
56
58
  import { drawPcbSilkscreenLine } from "./elements/pcb-silkscreen-line"
@@ -165,14 +167,18 @@ export class CircuitToCanvasDrawer {
165
167
  elements: AnyCircuitElement[],
166
168
  options: DrawElementsOptions = {},
167
169
  ): void {
168
- // Find the board element
170
+ // Find the board or panel element
169
171
  const board = elements.find((el) => el.type === "pcb_board") as
170
172
  | PcbBoard
171
173
  | undefined
174
+ const panel = elements.find((el) => el.type === "pcb_panel") as
175
+ | PcbPanel
176
+ | undefined
172
177
 
173
178
  // Drawing order:
174
- // 1. Board outline (just the outline stroke, no fill)
175
- // 2. Copper elements underneath soldermask (pads, copper text)
179
+ // 1. Panel outline (outer boundary)
180
+ // 2. Board outline (inner board)
181
+ // 3. Copper elements underneath soldermask (pads, copper text)
176
182
  // 3. Soldermask (covers everything except openings)
177
183
  // 4. Silkscreen (on soldermask, under top copper layers)
178
184
  // 5. Copper pour and traces (drawn on top of soldermask and silkscreen)
@@ -180,7 +186,18 @@ export class CircuitToCanvasDrawer {
180
186
  // 7. Holes and cutouts (punch through everything)
181
187
  // 8. Other annotations
182
188
 
183
- // Step 1: Draw board outline
189
+ // Step 1: Draw panel outline (outer boundary)
190
+ if (panel) {
191
+ drawPcbPanelElement({
192
+ ctx: this.ctx,
193
+ panel,
194
+ realToCanvasMat: this.realToCanvasMat,
195
+ colorMap: this.colorMap,
196
+ drawBoardMaterial: options.drawBoardMaterial ?? false,
197
+ })
198
+ }
199
+
200
+ // Step 2: Draw board outline (inner board, drawn after panel)
184
201
  if (board) {
185
202
  drawPcbBoard({
186
203
  ctx: this.ctx,
@@ -19,6 +19,8 @@ export { drawPcbTrace, type DrawPcbTraceParams } from "./pcb-trace"
19
19
 
20
20
  export { drawPcbBoard, type DrawPcbBoardParams } from "./pcb-board"
21
21
 
22
+ export { drawPcbPanelElement, type DrawPcbPanelParams } from "./pcb-panel"
23
+
22
24
  export {
23
25
  drawPcbSilkscreenText,
24
26
  type DrawPcbSilkscreenTextParams,
@@ -0,0 +1,52 @@
1
+ import type { PcbPanel } from "circuit-json"
2
+ import type { Matrix } from "transformation-matrix"
3
+ import { drawPath } from "../shapes/path"
4
+ import { drawRect } from "../shapes/rect"
5
+ import type { CanvasContext, PcbColorMap } from "../types"
6
+
7
+ export interface DrawPcbPanelParams {
8
+ ctx: CanvasContext
9
+ panel: PcbPanel
10
+ realToCanvasMat: Matrix
11
+ colorMap: PcbColorMap
12
+ drawBoardMaterial: boolean
13
+ }
14
+
15
+ export function drawPcbPanelElement(params: DrawPcbPanelParams): void {
16
+ const { ctx, panel, realToCanvasMat, colorMap, drawBoardMaterial } = params
17
+ const { width, height, center } = panel
18
+
19
+ // Draw a rectangle
20
+ if (width !== undefined && height !== undefined && center) {
21
+ // Draw substrate fill only if drawBoardMaterial is true
22
+ if (drawBoardMaterial) {
23
+ drawRect({
24
+ ctx,
25
+ center,
26
+ width,
27
+ height,
28
+ fill: colorMap.substrate,
29
+ realToCanvasMat,
30
+ })
31
+ }
32
+
33
+ // Always draw the outline stroke separately using path
34
+ const halfWidth = width / 2
35
+ const halfHeight = height / 2
36
+ const corners = [
37
+ { x: center.x - halfWidth, y: center.y - halfHeight },
38
+ { x: center.x + halfWidth, y: center.y - halfHeight },
39
+ { x: center.x + halfWidth, y: center.y + halfHeight },
40
+ { x: center.x - halfWidth, y: center.y + halfHeight },
41
+ ]
42
+
43
+ drawPath({
44
+ ctx,
45
+ points: corners,
46
+ stroke: colorMap.boardOutline,
47
+ strokeWidth: 0.5,
48
+ realToCanvasMat,
49
+ closePath: true,
50
+ })
51
+ }
52
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-to-canvas",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.55",
4
+ "version": "0.0.56",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "build": "tsup-node ./lib/index.ts --format esm --dts",
@@ -0,0 +1,115 @@
1
+ import { expect, test } from "bun:test"
2
+ import { createCanvas } from "@napi-rs/canvas"
3
+ import { getBoundsOfPcbElements } from "@tscircuit/circuit-json-util"
4
+ import type { AnyCircuitElement } from "circuit-json"
5
+ import { CircuitToCanvasDrawer } from "../../lib/drawer"
6
+
7
+ test("drawPcbPanel with board and components", async () => {
8
+ const elements: AnyCircuitElement[] = [
9
+ // PANEL - represents the manufacturing panel boundary
10
+ {
11
+ type: "pcb_panel" as const,
12
+ pcb_panel_id: "panel1",
13
+ center: { x: 100, y: 75 },
14
+ width: 180,
15
+ height: 120,
16
+ covered_with_solder_mask: false,
17
+ },
18
+ // BOARD - smaller PCB board inside the panel
19
+ {
20
+ type: "pcb_board" as const,
21
+ pcb_board_id: "board1",
22
+ center: { x: 75, y: 60 },
23
+ width: 80,
24
+ height: 60,
25
+ thickness: 1.6,
26
+ num_layers: 2,
27
+ material: "fr4" as const,
28
+ },
29
+ {
30
+ type: "pcb_smtpad" as const,
31
+ pcb_smtpad_id: "pad1",
32
+ shape: "rect" as const,
33
+ x: 50,
34
+ y: 45,
35
+ width: 12,
36
+ height: 6,
37
+ layer: "top" as const,
38
+ },
39
+ {
40
+ type: "pcb_smtpad" as const,
41
+ pcb_smtpad_id: "pad2",
42
+ shape: "rect" as const,
43
+ x: 100,
44
+ y: 45,
45
+ width: 12,
46
+ height: 6,
47
+ layer: "top" as const,
48
+ },
49
+ {
50
+ type: "pcb_trace" as const,
51
+ pcb_trace_id: "trace1",
52
+ route: [
53
+ {
54
+ route_type: "wire" as const,
55
+ x: 50,
56
+ y: 45,
57
+ width: 2,
58
+ layer: "top" as const,
59
+ },
60
+ {
61
+ route_type: "wire" as const,
62
+ x: 75,
63
+ y: 45,
64
+ width: 2,
65
+ layer: "top" as const,
66
+ },
67
+ {
68
+ route_type: "wire" as const,
69
+ x: 75,
70
+ y: 75,
71
+ width: 2,
72
+ layer: "top" as const,
73
+ },
74
+ {
75
+ route_type: "wire" as const,
76
+ x: 100,
77
+ y: 75,
78
+ width: 2,
79
+ layer: "top" as const,
80
+ },
81
+ ],
82
+ },
83
+ {
84
+ type: "pcb_via" as const,
85
+ pcb_via_id: "via1",
86
+ x: 75,
87
+ y: 60,
88
+ outer_diameter: 6,
89
+ hole_diameter: 3,
90
+ layers: ["top", "bottom"] as ("top" | "bottom")[],
91
+ },
92
+ ]
93
+
94
+ // Panel is larger than the board (180x120 vs board 80x60)
95
+ const canvas = createCanvas(800, 600)
96
+ const ctx = canvas.getContext("2d")
97
+ const drawer = new CircuitToCanvasDrawer(ctx)
98
+
99
+ ctx.fillStyle = "#000000"
100
+ ctx.fillRect(0, 0, 800, 600)
101
+
102
+ const bounds = getBoundsOfPcbElements(elements)
103
+ drawer.setCameraBounds({
104
+ minX: bounds.minX,
105
+ maxX: bounds.maxX,
106
+ minY: bounds.minY,
107
+ maxY: bounds.maxY,
108
+ })
109
+
110
+ drawer.drawElements(elements, { drawBoardMaterial: false })
111
+
112
+ await expect(canvas.toBuffer("image/png")).toMatchPngSnapshot(
113
+ import.meta.path,
114
+ )
115
+ })