circuit-to-svg 0.0.296 → 0.0.297

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
@@ -3777,13 +3777,17 @@ import { applyToPoint as applyToPoint23 } from "transformation-matrix";
3777
3777
 
3778
3778
  // lib/utils/create-pcb-component-anchor-offset-indicators.ts
3779
3779
  import { applyToPoint as applyToPoint22 } from "transformation-matrix";
3780
- var OFFSET_THRESHOLD_MM = 0.01;
3780
+ var OFFSET_THRESHOLD_MM = 0.05;
3781
3781
  var TICK_SIZE_PX = 4;
3782
3782
  var LABEL_GAP_PX = 8;
3783
3783
  var LABEL_FONT_SIZE_PX = 11;
3784
3784
  var STROKE_WIDTH_PX = 1;
3785
3785
  var ANCHOR_MARKER_SIZE_PX = 5;
3786
3786
  var ANCHOR_MARKER_STROKE_WIDTH_PX = 1.5;
3787
+ var COMPONENT_ANCHOR_MARKER_RADIUS_PX = 2;
3788
+ var CONNECTOR_GROUP_GAP_PX = ANCHOR_MARKER_SIZE_PX + 2;
3789
+ var CONNECTOR_COMPONENT_GAP_PX = COMPONENT_ANCHOR_MARKER_RADIUS_PX + 2;
3790
+ var DIMENSION_ANCHOR_CLEARANCE_PX = ANCHOR_MARKER_SIZE_PX + TICK_SIZE_PX + 6;
3787
3791
  var COMPONENT_GAP_PX = 15;
3788
3792
  var COMPONENT_SIDE_GAP_PX = 10;
3789
3793
  var DISTANCE_MULTIPLIER = 0.2;
@@ -3813,14 +3817,20 @@ function createAnchorOffsetIndicators(params) {
3813
3817
  const screenComponentWidth = componentWidth * scale10;
3814
3818
  const screenComponentHeight = componentHeight * scale10;
3815
3819
  objects.push(createAnchorMarker(screenGroupAnchorX, screenGroupAnchorY));
3820
+ const trimmedConnector = getTrimmedConnectorLine(
3821
+ screenGroupAnchorX,
3822
+ screenGroupAnchorY,
3823
+ screenComponentX,
3824
+ screenComponentY
3825
+ );
3816
3826
  objects.push({
3817
3827
  name: "line",
3818
3828
  type: "element",
3819
3829
  attributes: {
3820
- x1: screenGroupAnchorX.toString(),
3821
- y1: screenGroupAnchorY.toString(),
3822
- x2: screenComponentX.toString(),
3823
- y2: screenComponentY.toString(),
3830
+ x1: trimmedConnector.x1.toString(),
3831
+ y1: trimmedConnector.y1.toString(),
3832
+ x2: trimmedConnector.x2.toString(),
3833
+ y2: trimmedConnector.y2.toString(),
3824
3834
  stroke: "#ffffff",
3825
3835
  "stroke-width": "0.5",
3826
3836
  "stroke-dasharray": "3,3",
@@ -3836,7 +3846,7 @@ function createAnchorOffsetIndicators(params) {
3836
3846
  attributes: {
3837
3847
  cx: screenComponentX.toString(),
3838
3848
  cy: screenComponentY.toString(),
3839
- r: "2",
3849
+ r: COMPONENT_ANCHOR_MARKER_RADIUS_PX.toString(),
3840
3850
  fill: "#ffffff",
3841
3851
  opacity: "0.7",
3842
3852
  class: "anchor-offset-component-marker"
@@ -3852,9 +3862,23 @@ function createAnchorOffsetIndicators(params) {
3852
3862
  componentHeightOffset,
3853
3863
  Math.min(MAX_OFFSET_PX, totalDistance * DISTANCE_MULTIPLIER)
3854
3864
  );
3855
- const horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
3865
+ let horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
3856
3866
  const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
3857
- const verticalLineX = offsetX > 0 ? screenComponentX + componentWidthOffset : screenComponentX - componentWidthOffset;
3867
+ let verticalLineX = offsetX > 0 ? screenComponentX + componentWidthOffset : screenComponentX - componentWidthOffset;
3868
+ if (isTooCloseToAnchor(horizontalLineY, screenGroupAnchorY) || isTooCloseToAnchor(horizontalLineY, screenComponentY)) {
3869
+ const minY = Math.min(screenGroupAnchorY, screenComponentY);
3870
+ const maxY = Math.max(screenGroupAnchorY, screenComponentY);
3871
+ const candidateAbove = minY - DIMENSION_ANCHOR_CLEARANCE_PX;
3872
+ const candidateBelow = maxY + DIMENSION_ANCHOR_CLEARANCE_PX;
3873
+ horizontalLineY = Math.abs(horizontalLineY - candidateAbove) < Math.abs(horizontalLineY - candidateBelow) ? candidateAbove : candidateBelow;
3874
+ }
3875
+ if (isTooCloseToAnchor(verticalLineX, screenGroupAnchorX) || isTooCloseToAnchor(verticalLineX, screenComponentX)) {
3876
+ const minX = Math.min(screenGroupAnchorX, screenComponentX);
3877
+ const maxX = Math.max(screenGroupAnchorX, screenComponentX);
3878
+ const candidateLeft = minX - DIMENSION_ANCHOR_CLEARANCE_PX;
3879
+ const candidateRight = maxX + DIMENSION_ANCHOR_CLEARANCE_PX;
3880
+ verticalLineX = Math.abs(verticalLineX - candidateLeft) < Math.abs(verticalLineX - candidateRight) ? candidateLeft : candidateRight;
3881
+ }
3858
3882
  if (Math.abs(offsetX) > OFFSET_THRESHOLD_MM) {
3859
3883
  objects.push(
3860
3884
  ...createHorizontalDimension({
@@ -3881,6 +3905,24 @@ function createAnchorOffsetIndicators(params) {
3881
3905
  }
3882
3906
  return objects;
3883
3907
  }
3908
+ function getTrimmedConnectorLine(x1, y1, x2, y2) {
3909
+ const dx = x2 - x1;
3910
+ const dy = y2 - y1;
3911
+ const distance4 = Math.hypot(dx, dy);
3912
+ const totalTrim = CONNECTOR_GROUP_GAP_PX + CONNECTOR_COMPONENT_GAP_PX;
3913
+ if (!(distance4 > totalTrim)) return { x1, y1, x2, y2 };
3914
+ const ux = dx / distance4;
3915
+ const uy = dy / distance4;
3916
+ return {
3917
+ x1: x1 + ux * CONNECTOR_GROUP_GAP_PX,
3918
+ y1: y1 + uy * CONNECTOR_GROUP_GAP_PX,
3919
+ x2: x2 - ux * CONNECTOR_COMPONENT_GAP_PX,
3920
+ y2: y2 - uy * CONNECTOR_COMPONENT_GAP_PX
3921
+ };
3922
+ }
3923
+ function isTooCloseToAnchor(value, anchorValue) {
3924
+ return Math.abs(value - anchorValue) < DIMENSION_ANCHOR_CLEARANCE_PX;
3925
+ }
3884
3926
  function createAnchorMarker(x, y) {
3885
3927
  return {
3886
3928
  name: "g",
@@ -4085,8 +4127,7 @@ function createVerticalDimension({
4085
4127
  return objects;
4086
4128
  }
4087
4129
  function formatOffsetLabel(axis, offsetMm, displayOffset) {
4088
- const baseValue = displayOffset ?? offsetMm.toFixed(2);
4089
- const valueStr = typeof baseValue === "number" ? baseValue.toString() : baseValue;
4130
+ const valueStr = typeof displayOffset === "string" ? displayOffset : offsetMm.toFixed(2);
4090
4131
  const hasUnit = typeof valueStr === "string" && valueStr.trim().endsWith("mm");
4091
4132
  const unitSuffix = hasUnit ? "" : "mm";
4092
4133
  return `${axis}: ${valueStr}${unitSuffix}`;
@@ -5371,6 +5412,17 @@ function createMajorGridPatternChildren(cellSize, majorCellSize, lineColor, majo
5371
5412
 
5372
5413
  // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
5373
5414
  import { applyToPoint as applyToPoint31 } from "transformation-matrix";
5415
+
5416
+ // lib/utils/get-point-from-elm.ts
5417
+ function getPointFromElm(elm) {
5418
+ const candidate = elm?.anchor_position ?? elm?.center;
5419
+ if (candidate && typeof candidate.x === "number" && typeof candidate.y === "number") {
5420
+ return { x: candidate.x, y: candidate.y };
5421
+ }
5422
+ return void 0;
5423
+ }
5424
+
5425
+ // lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
5374
5426
  function createSvgObjectsFromPcbComponent(component, ctx) {
5375
5427
  const { transform, circuitJson } = ctx;
5376
5428
  const { center, width, height, rotation = 0 } = component;
@@ -5432,13 +5484,15 @@ function getAnchorPosition(component, circuitJson) {
5432
5484
  const pcbGroup = circuitJson.find(
5433
5485
  (elm) => elm.type === "pcb_group" && elm.pcb_group_id === component.positioned_relative_to_pcb_group_id
5434
5486
  );
5435
- if (pcbGroup?.center) return pcbGroup.center;
5487
+ const point = getPointFromElm(pcbGroup);
5488
+ if (point) return point;
5436
5489
  }
5437
5490
  if (component.positioned_relative_to_pcb_board_id) {
5438
5491
  const pcbBoard = circuitJson.find(
5439
5492
  (elm) => elm.type === "pcb_board" && elm.pcb_board_id === component.positioned_relative_to_pcb_board_id
5440
5493
  );
5441
- if (pcbBoard?.center) return pcbBoard.center;
5494
+ const point = getPointFromElm(pcbBoard);
5495
+ if (point) return point;
5442
5496
  }
5443
5497
  return void 0;
5444
5498
  }
@@ -5457,7 +5511,7 @@ function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
5457
5511
  svgObjects.push(
5458
5512
  ...createAnchorOffsetIndicators({
5459
5513
  groupAnchorPosition: anchorPosition,
5460
- componentPosition: pcbGroup.center,
5514
+ componentPosition: pcbGroup.anchor_position ?? pcbGroup.center,
5461
5515
  transform,
5462
5516
  componentWidth: pcbGroup.width,
5463
5517
  componentHeight: pcbGroup.height,
@@ -5542,13 +5596,15 @@ function getAnchorPosition2(group, circuitJson) {
5542
5596
  const pcbGroup = circuitJson.find(
5543
5597
  (elm) => elm.type === "pcb_group" && elm.pcb_group_id === group.positioned_relative_to_pcb_group_id
5544
5598
  );
5545
- if (pcbGroup?.center) return pcbGroup.center;
5599
+ const point = getPointFromElm(pcbGroup);
5600
+ if (point) return point;
5546
5601
  }
5547
5602
  if (group.positioned_relative_to_pcb_board_id) {
5548
5603
  const pcbBoard = circuitJson.find(
5549
5604
  (elm) => elm.type === "pcb_board" && elm.pcb_board_id === group.positioned_relative_to_pcb_board_id
5550
5605
  );
5551
- if (pcbBoard?.center) return pcbBoard.center;
5606
+ const point = getPointFromElm(pcbBoard);
5607
+ if (point) return point;
5552
5608
  }
5553
5609
  return void 0;
5554
5610
  }
@@ -5565,7 +5621,7 @@ function getSoftwareUsedString(circuitJson) {
5565
5621
  var package_default = {
5566
5622
  name: "circuit-to-svg",
5567
5623
  type: "module",
5568
- version: "0.0.295",
5624
+ version: "0.0.296",
5569
5625
  description: "Convert Circuit JSON to SVG",
5570
5626
  main: "dist/index.js",
5571
5627
  files: [