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 +72 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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:
|
|
3821
|
-
y1:
|
|
3822
|
-
x2:
|
|
3823
|
-
y2:
|
|
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:
|
|
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
|
-
|
|
3865
|
+
let horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
|
|
3856
3866
|
const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
|
|
3857
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
5624
|
+
version: "0.0.296",
|
|
5569
5625
|
description: "Convert Circuit JSON to SVG",
|
|
5570
5626
|
main: "dist/index.js",
|
|
5571
5627
|
files: [
|