circuit-to-svg 0.0.110 → 0.0.112

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 CHANGED
@@ -3,7 +3,7 @@ import { stringify } from "svgson";
3
3
  import {
4
4
  applyToPoint as applyToPoint16,
5
5
  compose as compose3,
6
- scale,
6
+ scale as scale2,
7
7
  translate as translate3
8
8
  } from "transformation-matrix";
9
9
 
@@ -288,11 +288,63 @@ function createSvgObjectsFromPcbPlatedHole(hole, transform) {
288
288
  }
289
289
  ];
290
290
  }
291
+ if (hole.shape === "circular_hole_with_rect_pad") {
292
+ const scaledHoleDiameter = hole.hole_diameter * Math.abs(transform.a);
293
+ const scaledRectPadWidth = hole.rect_pad_width * Math.abs(transform.a);
294
+ const scaledRectPadHeight = hole.rect_pad_height * Math.abs(transform.a);
295
+ const holeRadius = scaledHoleDiameter / 2;
296
+ return [
297
+ {
298
+ name: "g",
299
+ type: "element",
300
+ children: [
301
+ // Rectangular pad (outer shape)
302
+ {
303
+ name: "rect",
304
+ type: "element",
305
+ attributes: {
306
+ class: "pcb-hole-outer-pad",
307
+ fill: "rgb(200, 52, 52)",
308
+ x: (x - scaledRectPadWidth / 2).toString(),
309
+ y: (y - scaledRectPadHeight / 2).toString(),
310
+ width: scaledRectPadWidth.toString(),
311
+ height: scaledRectPadHeight.toString()
312
+ },
313
+ value: "",
314
+ children: []
315
+ },
316
+ // Circular hole inside the rectangle
317
+ {
318
+ name: "circle",
319
+ type: "element",
320
+ attributes: {
321
+ class: "pcb-hole-inner",
322
+ fill: "rgb(255, 38, 226)",
323
+ cx: x.toString(),
324
+ cy: y.toString(),
325
+ r: holeRadius.toString()
326
+ },
327
+ value: "",
328
+ children: []
329
+ }
330
+ ],
331
+ value: "",
332
+ attributes: {}
333
+ }
334
+ ];
335
+ }
291
336
  return [];
292
337
  }
293
338
 
294
339
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts
295
340
  import { applyToPoint as applyToPoint5 } from "transformation-matrix";
341
+
342
+ // lib/pcb/colors.ts
343
+ var HOLE_COLOR = "#FF26E2";
344
+ var SILKSCREEN_TOP_COLOR = "#f2eda1";
345
+ var SILKSCREEN_BOTTOM_COLOR = "#5da9e9";
346
+
347
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-silkscreen-path.ts
296
348
  function createSvgObjectsFromPcbSilkscreenPath(silkscreenPath, transform) {
297
349
  if (!silkscreenPath.route || !Array.isArray(silkscreenPath.route)) return [];
298
350
  let path = silkscreenPath.route.map((point, index) => {
@@ -304,15 +356,17 @@ function createSvgObjectsFromPcbSilkscreenPath(silkscreenPath, transform) {
304
356
  if (firstPoint && lastPoint && firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) {
305
357
  path += " Z";
306
358
  }
359
+ const layer = silkscreenPath.layer || "top";
360
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
307
361
  return [
308
362
  {
309
363
  name: "path",
310
364
  type: "element",
311
365
  attributes: {
312
- class: `pcb-silkscreen pcb-silkscreen-${silkscreenPath.layer}`,
366
+ class: `pcb-silkscreen pcb-silkscreen-${layer}`,
313
367
  d: path,
314
368
  fill: "none",
315
- stroke: "#f2eda1",
369
+ stroke: color,
316
370
  "stroke-width": (silkscreenPath.stroke_width * Math.abs(transform.a)).toString(),
317
371
  "data-pcb-component-id": silkscreenPath.pcb_component_id,
318
372
  "data-pcb-silkscreen-path-id": silkscreenPath.pcb_silkscreen_path_id
@@ -329,6 +383,7 @@ import {
329
383
  compose as compose2,
330
384
  rotate as rotate2,
331
385
  translate as translate2,
386
+ scale,
332
387
  toString as matrixToString2
333
388
  } from "transformation-matrix";
334
389
  function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
@@ -352,15 +407,17 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
352
407
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
353
408
  const textTransform = compose2(
354
409
  translate2(transformedX, transformedY),
355
- rotate2(ccw_rotation * Math.PI / 180)
410
+ rotate2(ccw_rotation * Math.PI / 180),
411
+ ...layer === "bottom" ? [scale(-1, 1)] : []
356
412
  );
413
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
357
414
  const svgObject = {
358
415
  name: "text",
359
416
  type: "element",
360
417
  attributes: {
361
418
  x: "0",
362
419
  y: "0",
363
- fill: "#f2eda1",
420
+ fill: color,
364
421
  "font-family": "Arial, sans-serif",
365
422
  "font-size": transformedFontSize.toString(),
366
423
  "text-anchor": "middle",
@@ -368,7 +425,7 @@ function createSvgObjectsFromPcbSilkscreenText(pcbSilkscreenText, transform) {
368
425
  transform: matrixToString2(textTransform),
369
426
  class: `pcb-silkscreen-text pcb-silkscreen-${layer}`,
370
427
  "data-pcb-silkscreen-text-id": pcbSilkscreenText.pcb_component_id,
371
- stroke: "#f2eda1",
428
+ stroke: color,
372
429
  "stroke-width": transformedStrokeWidth.toString()
373
430
  },
374
431
  children: [
@@ -409,6 +466,7 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, transform) {
409
466
  const transformedWidth = width * Math.abs(transform.a);
410
467
  const transformedHeight = height * Math.abs(transform.d);
411
468
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
469
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
412
470
  const svgObject = {
413
471
  name: "rect",
414
472
  type: "element",
@@ -419,7 +477,7 @@ function createSvgObjectsFromPcbSilkscreenRect(pcbSilkscreenRect, transform) {
419
477
  height: transformedHeight.toString(),
420
478
  class: `pcb-silkscreen-rect pcb-silkscreen-${layer}`,
421
479
  fill: "none",
422
- stroke: "#f2eda1",
480
+ stroke: color,
423
481
  "stroke-width": transformedStrokeWidth.toString(),
424
482
  "data-pcb-silkscreen-rect-id": pcb_silkscreen_rect_id
425
483
  },
@@ -451,6 +509,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, transform)
451
509
  ]);
452
510
  const transformedRadius = radius * Math.abs(transform.a);
453
511
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
512
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
454
513
  const svgObject = {
455
514
  name: "circle",
456
515
  type: "element",
@@ -459,7 +518,7 @@ function createSvgObjectsFromPcbSilkscreenCircle(pcbSilkscreenCircle, transform)
459
518
  cy: transformedY.toString(),
460
519
  r: transformedRadius.toString(),
461
520
  class: `pcb-silkscreen-circle pcb-silkscreen-${layer}`,
462
- stroke: "#f2eda1",
521
+ stroke: color,
463
522
  "stroke-width": transformedStrokeWidth.toString(),
464
523
  "data-pcb-silkscreen-circle-id": pcb_silkscreen_circle_id
465
524
  },
@@ -490,6 +549,7 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, transform) {
490
549
  const [transformedX1, transformedY1] = applyToPoint9(transform, [x1, y1]);
491
550
  const [transformedX2, transformedY2] = applyToPoint9(transform, [x2, y2]);
492
551
  const transformedStrokeWidth = stroke_width * Math.abs(transform.a);
552
+ const color = layer === "bottom" ? SILKSCREEN_BOTTOM_COLOR : SILKSCREEN_TOP_COLOR;
493
553
  return [
494
554
  {
495
555
  name: "line",
@@ -499,7 +559,7 @@ function createSvgObjectsFromPcbSilkscreenLine(pcbSilkscreenLine, transform) {
499
559
  y1: transformedY1.toString(),
500
560
  x2: transformedX2.toString(),
501
561
  y2: transformedY2.toString(),
502
- stroke: "#f2eda1",
562
+ stroke: color,
503
563
  "stroke-width": transformedStrokeWidth.toString(),
504
564
  class: `pcb-silkscreen-line pcb-silkscreen-${layer}`,
505
565
  "data-pcb-silkscreen-line-id": pcb_silkscreen_line_id
@@ -731,11 +791,6 @@ function createSvgObjectsFromPcbVia(hole, transform) {
731
791
 
732
792
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
733
793
  import { applyToPoint as applyToPoint14 } from "transformation-matrix";
734
-
735
- // lib/pcb/colors.ts
736
- var HOLE_COLOR = "#FF26E2";
737
-
738
- // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-hole.ts
739
794
  function createSvgObjectsFromPcbHole(hole, transform) {
740
795
  const [x, y] = applyToPoint14(transform, [hole.x, hole.y]);
741
796
  if (hole.hole_shape === "circle" || hole.hole_shape === "square") {
@@ -966,7 +1021,7 @@ function convertCircuitJsonToPcbSvg(soup, options) {
966
1021
  offsetX - minX * scaleFactor + padding * scaleFactor,
967
1022
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
968
1023
  ),
969
- scale(scaleFactor, -scaleFactor)
1024
+ scale2(scaleFactor, -scaleFactor)
970
1025
  // Flip in y-direction
971
1026
  );
972
1027
  let svgObjects = soup.sort(
@@ -1175,7 +1230,7 @@ import { su as su3 } from "@tscircuit/soup-util";
1175
1230
  import {
1176
1231
  applyToPoint as applyToPoint20,
1177
1232
  compose as compose4,
1178
- scale as scale2,
1233
+ scale as scale3,
1179
1234
  translate as translate4
1180
1235
  } from "transformation-matrix";
1181
1236
 
@@ -1294,9 +1349,9 @@ function createComponentPath(scaledWidth, scaledHeight, centerX, centerY, pinX,
1294
1349
  };
1295
1350
  }
1296
1351
  function createComponentLabel(scaledWidth, scaledHeight, name, transform) {
1297
- const scale7 = Math.min(scaledWidth, scaledHeight) * 0.4;
1298
- const fontSize = getSchScreenFontSize(transform, "net_label") * (scale7 / 2.5);
1299
- const scaledFontSize = scale7 < 25 ? fontSize : fontSize * 0.6;
1352
+ const scale8 = Math.min(scaledWidth, scaledHeight) * 0.4;
1353
+ const fontSize = getSchScreenFontSize(transform, "net_label") * (scale8 / 2.5);
1354
+ const scaledFontSize = scale8 < 25 ? fontSize : fontSize * 0.6;
1300
1355
  return {
1301
1356
  name: "text",
1302
1357
  type: "element",
@@ -1400,7 +1455,7 @@ function convertCircuitJsonToAssemblySvg(soup, options) {
1400
1455
  offsetX - minX * scaleFactor + padding * scaleFactor,
1401
1456
  svgHeight - offsetY + minY * scaleFactor - padding * scaleFactor
1402
1457
  ),
1403
- scale2(scaleFactor, -scaleFactor)
1458
+ scale3(scaleFactor, -scaleFactor)
1404
1459
  // Flip in y-direction
1405
1460
  );
1406
1461
  const svgObjects = soup.sort(
@@ -2034,7 +2089,7 @@ var matchSchPortsToSymbolPorts = ({
2034
2089
  };
2035
2090
 
2036
2091
  // lib/utils/point-pairs-to-matrix.ts
2037
- import { compose as compose5, scale as scale3, translate as translate5 } from "transformation-matrix";
2092
+ import { compose as compose5, scale as scale4, translate as translate5 } from "transformation-matrix";
2038
2093
  function pointPairsToMatrix(a1, a2, b1, b2) {
2039
2094
  const tx = a2.x - a1.x;
2040
2095
  const ty = a2.y - a1.y;
@@ -2042,7 +2097,7 @@ function pointPairsToMatrix(a1, a2, b1, b2) {
2042
2097
  const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
2043
2098
  const a = transformedDistance / originalDistance;
2044
2099
  const translateMatrix = translate5(tx, ty);
2045
- const scaleMatrix = scale3(a, a);
2100
+ const scaleMatrix = scale4(a, a);
2046
2101
  return compose5(translateMatrix, scaleMatrix);
2047
2102
  }
2048
2103
 
@@ -2944,7 +2999,7 @@ import {
2944
2999
  applyToPoint as applyToPoint35,
2945
3000
  compose as compose8,
2946
3001
  rotate as rotate4,
2947
- scale as scale5,
3002
+ scale as scale6,
2948
3003
  translate as translate8
2949
3004
  } from "transformation-matrix";
2950
3005
 
@@ -3732,7 +3787,7 @@ import {
3732
3787
  applyToPoint as applyToPoint34,
3733
3788
  compose as compose7,
3734
3789
  rotate as rotate3,
3735
- scale as scale4,
3790
+ scale as scale5,
3736
3791
  translate as translate7
3737
3792
  } from "transformation-matrix";
3738
3793
  import { symbols as symbols3 } from "schematic-symbols";
@@ -3766,8 +3821,8 @@ var ninePointAnchorToDominantBaseline = {
3766
3821
  middle_bottom: "hanging"
3767
3822
  };
3768
3823
  function getTextOffsets(pathRotation, transform) {
3769
- const scale7 = Math.abs(transform.a);
3770
- const baseOffset = scale7 * 0.1;
3824
+ const scale8 = Math.abs(transform.a);
3825
+ const baseOffset = scale8 * 0.1;
3771
3826
  const rotationOffsetMap = {
3772
3827
  "0": { x: baseOffset * 0.8, y: -baseOffset },
3773
3828
  // Left
@@ -3856,7 +3911,7 @@ var createSvgObjectsForSchNetLabelWithSymbol = (schNetLabel, realToScreenTransfo
3856
3911
  realAnchorPosition.y - rotatedSymbolEnd.y
3857
3912
  ),
3858
3913
  rotationMatrix,
3859
- scale4(1)
3914
+ scale5(1)
3860
3915
  // Use full symbol size
3861
3916
  );
3862
3917
  const [screenMinX, screenMinY] = applyToPoint34(
@@ -3917,8 +3972,8 @@ var createSvgObjectsForSchNetLabelWithSymbol = (schNetLabel, realToScreenTransfo
3917
3972
  } else if (textValue === "{VAL}") {
3918
3973
  textValue = "";
3919
3974
  }
3920
- const scale7 = Math.abs(realToScreenTransform.a);
3921
- const baseOffset = scale7 * 0.1;
3975
+ const scale8 = Math.abs(realToScreenTransform.a);
3976
+ const baseOffset = scale8 * 0.1;
3922
3977
  const rotationOffset = getTextOffsets(pathRotation, realToScreenTransform);
3923
3978
  const offsetScreenPos = {
3924
3979
  x: screenTextPos.x + rotationOffset.x,
@@ -4063,7 +4118,7 @@ var createSvgObjectsForSchNetLabel = (schNetLabel, realToScreenTransform) => {
4063
4118
  compose8(
4064
4119
  realToScreenTransform,
4065
4120
  translate8(realAnchorPosition.x, realAnchorPosition.y),
4066
- scale5(fontSizeMm),
4121
+ scale6(fontSizeMm),
4067
4122
  rotate4(pathRotation / 180 * Math.PI)
4068
4123
  ),
4069
4124
  fontRelativePoint