circuit-to-svg 0.0.295 → 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 +82 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2751,12 +2751,13 @@ var CHAR_WIDTH = 1;
|
|
|
2751
2751
|
var CHAR_SPACING = 0.2;
|
|
2752
2752
|
var LINE_HEIGHT = 1.4;
|
|
2753
2753
|
var FONT_SCALE = 0.53;
|
|
2754
|
-
|
|
2754
|
+
var BASELINE_Y = 0.241;
|
|
2755
|
+
function linesToPathData(lines, offsetX, offsetY, charScale, baselineAdjust = 0) {
|
|
2755
2756
|
return lines.map((line) => {
|
|
2756
2757
|
const x1 = offsetX + line.x1 * charScale;
|
|
2757
|
-
const y1 = offsetY + (1 - line.y1) * charScale;
|
|
2758
|
+
const y1 = offsetY + (1 - line.y1 + baselineAdjust) * charScale;
|
|
2758
2759
|
const x2 = offsetX + line.x2 * charScale;
|
|
2759
|
-
const y2 = offsetY + (1 - line.y2) * charScale;
|
|
2760
|
+
const y2 = offsetY + (1 - line.y2 + baselineAdjust) * charScale;
|
|
2760
2761
|
return `M${x1} ${y1}L${x2} ${y2}`;
|
|
2761
2762
|
}).join(" ");
|
|
2762
2763
|
}
|
|
@@ -2771,7 +2772,9 @@ function textToAlphabetPath(text, fontSize) {
|
|
|
2771
2772
|
}
|
|
2772
2773
|
const lines = lineAlphabet[char];
|
|
2773
2774
|
if (lines) {
|
|
2774
|
-
|
|
2775
|
+
const isLowercase = char >= "a" && char <= "z";
|
|
2776
|
+
const baselineAdjust = isLowercase ? BASELINE_Y : 0;
|
|
2777
|
+
paths.push(linesToPathData(lines, x, 0, fontSize, baselineAdjust));
|
|
2775
2778
|
}
|
|
2776
2779
|
x += charAdvance;
|
|
2777
2780
|
}
|
|
@@ -2804,7 +2807,9 @@ function textToCenteredAlphabetPaths(text, fontSize) {
|
|
|
2804
2807
|
}
|
|
2805
2808
|
const charLines = lineAlphabet[char];
|
|
2806
2809
|
if (charLines) {
|
|
2807
|
-
|
|
2810
|
+
const isLowercase = char >= "a" && char <= "z";
|
|
2811
|
+
const baselineAdjust = isLowercase ? BASELINE_Y : 0;
|
|
2812
|
+
paths.push(linesToPathData(charLines, x, y, fontSize, baselineAdjust));
|
|
2808
2813
|
}
|
|
2809
2814
|
x += charAdvance;
|
|
2810
2815
|
}
|
|
@@ -2875,7 +2880,6 @@ function createSvgObjectsFromPcbCopperText(pcbCopperText, ctx) {
|
|
|
2875
2880
|
id: maskId
|
|
2876
2881
|
},
|
|
2877
2882
|
children: [
|
|
2878
|
-
// White background - area that will show copper
|
|
2879
2883
|
{
|
|
2880
2884
|
name: "rect",
|
|
2881
2885
|
type: "element",
|
|
@@ -2889,7 +2893,6 @@ function createSvgObjectsFromPcbCopperText(pcbCopperText, ctx) {
|
|
|
2889
2893
|
},
|
|
2890
2894
|
children: []
|
|
2891
2895
|
},
|
|
2892
|
-
// Black text strokes - area that will be cut out
|
|
2893
2896
|
{
|
|
2894
2897
|
name: "path",
|
|
2895
2898
|
type: "element",
|
|
@@ -3774,13 +3777,17 @@ import { applyToPoint as applyToPoint23 } from "transformation-matrix";
|
|
|
3774
3777
|
|
|
3775
3778
|
// lib/utils/create-pcb-component-anchor-offset-indicators.ts
|
|
3776
3779
|
import { applyToPoint as applyToPoint22 } from "transformation-matrix";
|
|
3777
|
-
var OFFSET_THRESHOLD_MM = 0.
|
|
3780
|
+
var OFFSET_THRESHOLD_MM = 0.05;
|
|
3778
3781
|
var TICK_SIZE_PX = 4;
|
|
3779
3782
|
var LABEL_GAP_PX = 8;
|
|
3780
3783
|
var LABEL_FONT_SIZE_PX = 11;
|
|
3781
3784
|
var STROKE_WIDTH_PX = 1;
|
|
3782
3785
|
var ANCHOR_MARKER_SIZE_PX = 5;
|
|
3783
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;
|
|
3784
3791
|
var COMPONENT_GAP_PX = 15;
|
|
3785
3792
|
var COMPONENT_SIDE_GAP_PX = 10;
|
|
3786
3793
|
var DISTANCE_MULTIPLIER = 0.2;
|
|
@@ -3810,14 +3817,20 @@ function createAnchorOffsetIndicators(params) {
|
|
|
3810
3817
|
const screenComponentWidth = componentWidth * scale10;
|
|
3811
3818
|
const screenComponentHeight = componentHeight * scale10;
|
|
3812
3819
|
objects.push(createAnchorMarker(screenGroupAnchorX, screenGroupAnchorY));
|
|
3820
|
+
const trimmedConnector = getTrimmedConnectorLine(
|
|
3821
|
+
screenGroupAnchorX,
|
|
3822
|
+
screenGroupAnchorY,
|
|
3823
|
+
screenComponentX,
|
|
3824
|
+
screenComponentY
|
|
3825
|
+
);
|
|
3813
3826
|
objects.push({
|
|
3814
3827
|
name: "line",
|
|
3815
3828
|
type: "element",
|
|
3816
3829
|
attributes: {
|
|
3817
|
-
x1:
|
|
3818
|
-
y1:
|
|
3819
|
-
x2:
|
|
3820
|
-
y2:
|
|
3830
|
+
x1: trimmedConnector.x1.toString(),
|
|
3831
|
+
y1: trimmedConnector.y1.toString(),
|
|
3832
|
+
x2: trimmedConnector.x2.toString(),
|
|
3833
|
+
y2: trimmedConnector.y2.toString(),
|
|
3821
3834
|
stroke: "#ffffff",
|
|
3822
3835
|
"stroke-width": "0.5",
|
|
3823
3836
|
"stroke-dasharray": "3,3",
|
|
@@ -3833,7 +3846,7 @@ function createAnchorOffsetIndicators(params) {
|
|
|
3833
3846
|
attributes: {
|
|
3834
3847
|
cx: screenComponentX.toString(),
|
|
3835
3848
|
cy: screenComponentY.toString(),
|
|
3836
|
-
r:
|
|
3849
|
+
r: COMPONENT_ANCHOR_MARKER_RADIUS_PX.toString(),
|
|
3837
3850
|
fill: "#ffffff",
|
|
3838
3851
|
opacity: "0.7",
|
|
3839
3852
|
class: "anchor-offset-component-marker"
|
|
@@ -3849,9 +3862,23 @@ function createAnchorOffsetIndicators(params) {
|
|
|
3849
3862
|
componentHeightOffset,
|
|
3850
3863
|
Math.min(MAX_OFFSET_PX, totalDistance * DISTANCE_MULTIPLIER)
|
|
3851
3864
|
);
|
|
3852
|
-
|
|
3865
|
+
let horizontalLineY = offsetY > 0 ? screenComponentY - dynamicOffset : screenComponentY + dynamicOffset;
|
|
3853
3866
|
const componentWidthOffset = screenComponentWidth / 2 + COMPONENT_SIDE_GAP_PX;
|
|
3854
|
-
|
|
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
|
+
}
|
|
3855
3882
|
if (Math.abs(offsetX) > OFFSET_THRESHOLD_MM) {
|
|
3856
3883
|
objects.push(
|
|
3857
3884
|
...createHorizontalDimension({
|
|
@@ -3878,6 +3905,24 @@ function createAnchorOffsetIndicators(params) {
|
|
|
3878
3905
|
}
|
|
3879
3906
|
return objects;
|
|
3880
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
|
+
}
|
|
3881
3926
|
function createAnchorMarker(x, y) {
|
|
3882
3927
|
return {
|
|
3883
3928
|
name: "g",
|
|
@@ -4082,8 +4127,7 @@ function createVerticalDimension({
|
|
|
4082
4127
|
return objects;
|
|
4083
4128
|
}
|
|
4084
4129
|
function formatOffsetLabel(axis, offsetMm, displayOffset) {
|
|
4085
|
-
const
|
|
4086
|
-
const valueStr = typeof baseValue === "number" ? baseValue.toString() : baseValue;
|
|
4130
|
+
const valueStr = typeof displayOffset === "string" ? displayOffset : offsetMm.toFixed(2);
|
|
4087
4131
|
const hasUnit = typeof valueStr === "string" && valueStr.trim().endsWith("mm");
|
|
4088
4132
|
const unitSuffix = hasUnit ? "" : "mm";
|
|
4089
4133
|
return `${axis}: ${valueStr}${unitSuffix}`;
|
|
@@ -5368,6 +5412,17 @@ function createMajorGridPatternChildren(cellSize, majorCellSize, lineColor, majo
|
|
|
5368
5412
|
|
|
5369
5413
|
// lib/pcb/svg-object-fns/create-svg-objects-from-pcb-component.ts
|
|
5370
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
|
|
5371
5426
|
function createSvgObjectsFromPcbComponent(component, ctx) {
|
|
5372
5427
|
const { transform, circuitJson } = ctx;
|
|
5373
5428
|
const { center, width, height, rotation = 0 } = component;
|
|
@@ -5429,13 +5484,15 @@ function getAnchorPosition(component, circuitJson) {
|
|
|
5429
5484
|
const pcbGroup = circuitJson.find(
|
|
5430
5485
|
(elm) => elm.type === "pcb_group" && elm.pcb_group_id === component.positioned_relative_to_pcb_group_id
|
|
5431
5486
|
);
|
|
5432
|
-
|
|
5487
|
+
const point = getPointFromElm(pcbGroup);
|
|
5488
|
+
if (point) return point;
|
|
5433
5489
|
}
|
|
5434
5490
|
if (component.positioned_relative_to_pcb_board_id) {
|
|
5435
5491
|
const pcbBoard = circuitJson.find(
|
|
5436
5492
|
(elm) => elm.type === "pcb_board" && elm.pcb_board_id === component.positioned_relative_to_pcb_board_id
|
|
5437
5493
|
);
|
|
5438
|
-
|
|
5494
|
+
const point = getPointFromElm(pcbBoard);
|
|
5495
|
+
if (point) return point;
|
|
5439
5496
|
}
|
|
5440
5497
|
return void 0;
|
|
5441
5498
|
}
|
|
@@ -5454,7 +5511,7 @@ function createSvgObjectsFromPcbGroup(pcbGroup, ctx) {
|
|
|
5454
5511
|
svgObjects.push(
|
|
5455
5512
|
...createAnchorOffsetIndicators({
|
|
5456
5513
|
groupAnchorPosition: anchorPosition,
|
|
5457
|
-
componentPosition: pcbGroup.center,
|
|
5514
|
+
componentPosition: pcbGroup.anchor_position ?? pcbGroup.center,
|
|
5458
5515
|
transform,
|
|
5459
5516
|
componentWidth: pcbGroup.width,
|
|
5460
5517
|
componentHeight: pcbGroup.height,
|
|
@@ -5539,13 +5596,15 @@ function getAnchorPosition2(group, circuitJson) {
|
|
|
5539
5596
|
const pcbGroup = circuitJson.find(
|
|
5540
5597
|
(elm) => elm.type === "pcb_group" && elm.pcb_group_id === group.positioned_relative_to_pcb_group_id
|
|
5541
5598
|
);
|
|
5542
|
-
|
|
5599
|
+
const point = getPointFromElm(pcbGroup);
|
|
5600
|
+
if (point) return point;
|
|
5543
5601
|
}
|
|
5544
5602
|
if (group.positioned_relative_to_pcb_board_id) {
|
|
5545
5603
|
const pcbBoard = circuitJson.find(
|
|
5546
5604
|
(elm) => elm.type === "pcb_board" && elm.pcb_board_id === group.positioned_relative_to_pcb_board_id
|
|
5547
5605
|
);
|
|
5548
|
-
|
|
5606
|
+
const point = getPointFromElm(pcbBoard);
|
|
5607
|
+
if (point) return point;
|
|
5549
5608
|
}
|
|
5550
5609
|
return void 0;
|
|
5551
5610
|
}
|
|
@@ -5562,7 +5621,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
5562
5621
|
var package_default = {
|
|
5563
5622
|
name: "circuit-to-svg",
|
|
5564
5623
|
type: "module",
|
|
5565
|
-
version: "0.0.
|
|
5624
|
+
version: "0.0.296",
|
|
5566
5625
|
description: "Convert Circuit JSON to SVG",
|
|
5567
5626
|
main: "dist/index.js",
|
|
5568
5627
|
files: [
|