circuit-to-svg 0.0.254 → 0.0.256
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 +145 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -627,7 +627,9 @@ function createSvgObjectsFromPcbFabricationNoteDimension(dimension, ctx) {
|
|
|
627
627
|
arrow_size,
|
|
628
628
|
layer,
|
|
629
629
|
pcb_component_id,
|
|
630
|
-
pcb_fabrication_note_dimension_id
|
|
630
|
+
pcb_fabrication_note_dimension_id,
|
|
631
|
+
offset_distance,
|
|
632
|
+
offset_direction
|
|
631
633
|
} = dimension;
|
|
632
634
|
if (layerFilter && layer && layer !== layerFilter) return [];
|
|
633
635
|
if (!from || !to || typeof from !== "object" || typeof to !== "object") {
|
|
@@ -658,17 +660,30 @@ function createSvgObjectsFromPcbFabricationNoteDimension(dimension, ctx) {
|
|
|
658
660
|
return [];
|
|
659
661
|
}
|
|
660
662
|
const perpendicular = { x: -direction.y, y: direction.x };
|
|
663
|
+
const hasOffsetDirection = offset_direction && typeof offset_direction.x === "number" && typeof offset_direction.y === "number";
|
|
664
|
+
const normalizedOffsetDirection = hasOffsetDirection ? normalize({ x: offset_direction.x, y: offset_direction.y }) : { x: 0, y: 0 };
|
|
665
|
+
const offsetMagnitude = typeof offset_distance === "number" ? offset_distance : 0;
|
|
666
|
+
const offsetVector = {
|
|
667
|
+
x: normalizedOffsetDirection.x * offsetMagnitude,
|
|
668
|
+
y: normalizedOffsetDirection.y * offsetMagnitude
|
|
669
|
+
};
|
|
670
|
+
const applyOffset = (point) => ({
|
|
671
|
+
x: point.x + offsetVector.x,
|
|
672
|
+
y: point.y + offsetVector.y
|
|
673
|
+
});
|
|
674
|
+
const fromOffset = applyOffset(from);
|
|
675
|
+
const toOffset = applyOffset(to);
|
|
661
676
|
const arrowHalfWidth = arrowSize / 2;
|
|
662
677
|
const fromBase = {
|
|
663
|
-
x:
|
|
664
|
-
y:
|
|
678
|
+
x: fromOffset.x + direction.x * arrowSize,
|
|
679
|
+
y: fromOffset.y + direction.y * arrowSize
|
|
665
680
|
};
|
|
666
681
|
const toBase = {
|
|
667
|
-
x:
|
|
668
|
-
y:
|
|
682
|
+
x: toOffset.x - direction.x * arrowSize,
|
|
683
|
+
y: toOffset.y - direction.y * arrowSize
|
|
669
684
|
};
|
|
670
685
|
const fromTriangle = [
|
|
671
|
-
toScreen(
|
|
686
|
+
toScreen(fromOffset),
|
|
672
687
|
toScreen({
|
|
673
688
|
x: fromBase.x + perpendicular.x * arrowHalfWidth,
|
|
674
689
|
y: fromBase.y + perpendicular.y * arrowHalfWidth
|
|
@@ -679,7 +694,7 @@ function createSvgObjectsFromPcbFabricationNoteDimension(dimension, ctx) {
|
|
|
679
694
|
})
|
|
680
695
|
];
|
|
681
696
|
const toTriangle = [
|
|
682
|
-
toScreen(
|
|
697
|
+
toScreen(toOffset),
|
|
683
698
|
toScreen({
|
|
684
699
|
x: toBase.x + perpendicular.x * arrowHalfWidth,
|
|
685
700
|
y: toBase.y + perpendicular.y * arrowHalfWidth
|
|
@@ -696,9 +711,34 @@ function createSvgObjectsFromPcbFabricationNoteDimension(dimension, ctx) {
|
|
|
696
711
|
const [lineEndX, lineEndY] = applyToPoint6(transform, [toBase.x, toBase.y]);
|
|
697
712
|
const strokeWidth = arrowSize / 5 * Math.abs(transform.a);
|
|
698
713
|
const lineColor = color || "rgba(255,255,255,0.5)";
|
|
714
|
+
const extensionDirection = hasOffsetDirection && (Math.abs(normalizedOffsetDirection.x) > Number.EPSILON || Math.abs(normalizedOffsetDirection.y) > Number.EPSILON) ? normalizedOffsetDirection : perpendicular;
|
|
715
|
+
const extensionLength = offsetMagnitude + arrowSize;
|
|
716
|
+
const createExtensionLine = (anchor) => {
|
|
717
|
+
const endPoint = {
|
|
718
|
+
x: anchor.x + extensionDirection.x * extensionLength,
|
|
719
|
+
y: anchor.y + extensionDirection.y * extensionLength
|
|
720
|
+
};
|
|
721
|
+
const [startX, startY] = applyToPoint6(transform, [anchor.x, anchor.y]);
|
|
722
|
+
const [endX, endY] = applyToPoint6(transform, [endPoint.x, endPoint.y]);
|
|
723
|
+
return {
|
|
724
|
+
name: "path",
|
|
725
|
+
type: "element",
|
|
726
|
+
value: "",
|
|
727
|
+
attributes: {
|
|
728
|
+
d: `M ${startX} ${startY} L ${endX} ${endY}`,
|
|
729
|
+
stroke: lineColor,
|
|
730
|
+
fill: "none",
|
|
731
|
+
"stroke-width": strokeWidth.toString(),
|
|
732
|
+
"stroke-linecap": "round",
|
|
733
|
+
class: "pcb-fabrication-note-dimension-extension"
|
|
734
|
+
},
|
|
735
|
+
children: []
|
|
736
|
+
};
|
|
737
|
+
};
|
|
738
|
+
const extensionSegments = [createExtensionLine(from), createExtensionLine(to)];
|
|
699
739
|
const midPoint = {
|
|
700
|
-
x: (from.x + to.x) / 2,
|
|
701
|
-
y: (from.y + to.y) / 2
|
|
740
|
+
x: (from.x + to.x) / 2 + offsetVector.x,
|
|
741
|
+
y: (from.y + to.y) / 2 + offsetVector.y
|
|
702
742
|
};
|
|
703
743
|
const textOffset = arrowSize * 1.5;
|
|
704
744
|
const textPoint = {
|
|
@@ -706,8 +746,25 @@ function createSvgObjectsFromPcbFabricationNoteDimension(dimension, ctx) {
|
|
|
706
746
|
y: midPoint.y + perpendicular.y * textOffset
|
|
707
747
|
};
|
|
708
748
|
const [textX, textY] = applyToPoint6(transform, [textPoint.x, textPoint.y]);
|
|
749
|
+
const [screenFromX, screenFromY] = applyToPoint6(transform, [
|
|
750
|
+
fromOffset.x,
|
|
751
|
+
fromOffset.y
|
|
752
|
+
]);
|
|
753
|
+
const [screenToX, screenToY] = applyToPoint6(transform, [
|
|
754
|
+
toOffset.x,
|
|
755
|
+
toOffset.y
|
|
756
|
+
]);
|
|
757
|
+
const screenDirection = normalize({
|
|
758
|
+
x: screenToX - screenFromX,
|
|
759
|
+
y: screenToY - screenFromY
|
|
760
|
+
});
|
|
761
|
+
let textAngle = Math.atan2(screenDirection.y, screenDirection.x) * 180 / Math.PI;
|
|
762
|
+
if (textAngle > 90 || textAngle < -90) {
|
|
763
|
+
textAngle += 180;
|
|
764
|
+
}
|
|
709
765
|
const transformedFontSize = font_size * Math.abs(transform.a);
|
|
710
766
|
const children = [
|
|
767
|
+
...extensionSegments,
|
|
711
768
|
{
|
|
712
769
|
name: "path",
|
|
713
770
|
type: "element",
|
|
@@ -758,7 +815,8 @@ function createSvgObjectsFromPcbFabricationNoteDimension(dimension, ctx) {
|
|
|
758
815
|
"font-family": "Arial, sans-serif",
|
|
759
816
|
"text-anchor": "middle",
|
|
760
817
|
"dominant-baseline": "central",
|
|
761
|
-
class: "pcb-fabrication-note-dimension-text"
|
|
818
|
+
class: "pcb-fabrication-note-dimension-text",
|
|
819
|
+
transform: `rotate(${textAngle} ${textX} ${textY})`
|
|
762
820
|
},
|
|
763
821
|
children: [
|
|
764
822
|
{
|
|
@@ -1049,7 +1107,16 @@ function toPath2(points) {
|
|
|
1049
1107
|
}
|
|
1050
1108
|
function createSvgObjectsFromPcbNoteDimension(dimension, ctx) {
|
|
1051
1109
|
const { transform } = ctx;
|
|
1052
|
-
const {
|
|
1110
|
+
const {
|
|
1111
|
+
from,
|
|
1112
|
+
to,
|
|
1113
|
+
text,
|
|
1114
|
+
font_size = 1,
|
|
1115
|
+
color,
|
|
1116
|
+
arrow_size,
|
|
1117
|
+
offset_distance,
|
|
1118
|
+
offset_direction
|
|
1119
|
+
} = dimension;
|
|
1053
1120
|
if (!from || !to) {
|
|
1054
1121
|
console.error("Invalid pcb_note_dimension endpoints", { from, to });
|
|
1055
1122
|
return [];
|
|
@@ -1063,17 +1130,30 @@ function createSvgObjectsFromPcbNoteDimension(dimension, ctx) {
|
|
|
1063
1130
|
return [];
|
|
1064
1131
|
}
|
|
1065
1132
|
const perpendicular = { x: -direction.y, y: direction.x };
|
|
1133
|
+
const hasOffsetDirection = offset_direction && typeof offset_direction.x === "number" && typeof offset_direction.y === "number";
|
|
1134
|
+
const normalizedOffsetDirection = hasOffsetDirection ? normalize2({ x: offset_direction.x, y: offset_direction.y }) : { x: 0, y: 0 };
|
|
1135
|
+
const offsetMagnitude = typeof offset_distance === "number" ? offset_distance : 0;
|
|
1136
|
+
const offsetVector = {
|
|
1137
|
+
x: normalizedOffsetDirection.x * offsetMagnitude,
|
|
1138
|
+
y: normalizedOffsetDirection.y * offsetMagnitude
|
|
1139
|
+
};
|
|
1140
|
+
const applyOffset = (point) => ({
|
|
1141
|
+
x: point.x + offsetVector.x,
|
|
1142
|
+
y: point.y + offsetVector.y
|
|
1143
|
+
});
|
|
1144
|
+
const fromOffset = applyOffset(from);
|
|
1145
|
+
const toOffset = applyOffset(to);
|
|
1066
1146
|
const arrowHalfWidth = arrow_size / 2;
|
|
1067
1147
|
const fromBase = {
|
|
1068
|
-
x:
|
|
1069
|
-
y:
|
|
1148
|
+
x: fromOffset.x + direction.x * arrow_size,
|
|
1149
|
+
y: fromOffset.y + direction.y * arrow_size
|
|
1070
1150
|
};
|
|
1071
1151
|
const toBase = {
|
|
1072
|
-
x:
|
|
1073
|
-
y:
|
|
1152
|
+
x: toOffset.x - direction.x * arrow_size,
|
|
1153
|
+
y: toOffset.y - direction.y * arrow_size
|
|
1074
1154
|
};
|
|
1075
1155
|
const fromTriangle = [
|
|
1076
|
-
toScreen(
|
|
1156
|
+
toScreen(fromOffset),
|
|
1077
1157
|
toScreen({
|
|
1078
1158
|
x: fromBase.x + perpendicular.x * arrowHalfWidth,
|
|
1079
1159
|
y: fromBase.y + perpendicular.y * arrowHalfWidth
|
|
@@ -1084,7 +1164,7 @@ function createSvgObjectsFromPcbNoteDimension(dimension, ctx) {
|
|
|
1084
1164
|
})
|
|
1085
1165
|
];
|
|
1086
1166
|
const toTriangle = [
|
|
1087
|
-
toScreen(
|
|
1167
|
+
toScreen(toOffset),
|
|
1088
1168
|
toScreen({
|
|
1089
1169
|
x: toBase.x + perpendicular.x * arrowHalfWidth,
|
|
1090
1170
|
y: toBase.y + perpendicular.y * arrowHalfWidth
|
|
@@ -1101,9 +1181,34 @@ function createSvgObjectsFromPcbNoteDimension(dimension, ctx) {
|
|
|
1101
1181
|
const [lineEndX, lineEndY] = applyToPoint7(transform, [toBase.x, toBase.y]);
|
|
1102
1182
|
const strokeWidth = arrow_size / 5 * Math.abs(transform.a);
|
|
1103
1183
|
const lineColor = color || colorMap.board.user_2;
|
|
1184
|
+
const extensionDirection = hasOffsetDirection && (Math.abs(normalizedOffsetDirection.x) > Number.EPSILON || Math.abs(normalizedOffsetDirection.y) > Number.EPSILON) ? normalizedOffsetDirection : perpendicular;
|
|
1185
|
+
const extensionLength = offsetMagnitude + arrow_size;
|
|
1186
|
+
const createExtensionLine = (anchor) => {
|
|
1187
|
+
const endPoint = {
|
|
1188
|
+
x: anchor.x + extensionDirection.x * extensionLength,
|
|
1189
|
+
y: anchor.y + extensionDirection.y * extensionLength
|
|
1190
|
+
};
|
|
1191
|
+
const [startX, startY] = applyToPoint7(transform, [anchor.x, anchor.y]);
|
|
1192
|
+
const [endX, endY] = applyToPoint7(transform, [endPoint.x, endPoint.y]);
|
|
1193
|
+
return {
|
|
1194
|
+
name: "path",
|
|
1195
|
+
type: "element",
|
|
1196
|
+
value: "",
|
|
1197
|
+
attributes: {
|
|
1198
|
+
d: `M ${startX} ${startY} L ${endX} ${endY}`,
|
|
1199
|
+
stroke: lineColor,
|
|
1200
|
+
fill: "none",
|
|
1201
|
+
"stroke-width": strokeWidth.toString(),
|
|
1202
|
+
"stroke-linecap": "round",
|
|
1203
|
+
class: "pcb-note-dimension-extension"
|
|
1204
|
+
},
|
|
1205
|
+
children: []
|
|
1206
|
+
};
|
|
1207
|
+
};
|
|
1208
|
+
const extensionSegments = [createExtensionLine(from), createExtensionLine(to)];
|
|
1104
1209
|
const midPoint = {
|
|
1105
|
-
x: (from.x + to.x) / 2,
|
|
1106
|
-
y: (from.y + to.y) / 2
|
|
1210
|
+
x: (from.x + to.x) / 2 + offsetVector.x,
|
|
1211
|
+
y: (from.y + to.y) / 2 + offsetVector.y
|
|
1107
1212
|
};
|
|
1108
1213
|
const textOffset = arrow_size * 1.5;
|
|
1109
1214
|
const textPoint = {
|
|
@@ -1111,8 +1216,25 @@ function createSvgObjectsFromPcbNoteDimension(dimension, ctx) {
|
|
|
1111
1216
|
y: midPoint.y + perpendicular.y * textOffset
|
|
1112
1217
|
};
|
|
1113
1218
|
const [textX, textY] = applyToPoint7(transform, [textPoint.x, textPoint.y]);
|
|
1219
|
+
const [screenFromX, screenFromY] = applyToPoint7(transform, [
|
|
1220
|
+
fromOffset.x,
|
|
1221
|
+
fromOffset.y
|
|
1222
|
+
]);
|
|
1223
|
+
const [screenToX, screenToY] = applyToPoint7(transform, [
|
|
1224
|
+
toOffset.x,
|
|
1225
|
+
toOffset.y
|
|
1226
|
+
]);
|
|
1227
|
+
const screenDirection = normalize2({
|
|
1228
|
+
x: screenToX - screenFromX,
|
|
1229
|
+
y: screenToY - screenFromY
|
|
1230
|
+
});
|
|
1231
|
+
let textAngle = Math.atan2(screenDirection.y, screenDirection.x) * 180 / Math.PI;
|
|
1232
|
+
if (textAngle > 90 || textAngle < -90) {
|
|
1233
|
+
textAngle += 180;
|
|
1234
|
+
}
|
|
1114
1235
|
const transformedFontSize = font_size * Math.abs(transform.a);
|
|
1115
1236
|
const children = [
|
|
1237
|
+
...extensionSegments,
|
|
1116
1238
|
{
|
|
1117
1239
|
name: "path",
|
|
1118
1240
|
type: "element",
|
|
@@ -1163,7 +1285,8 @@ function createSvgObjectsFromPcbNoteDimension(dimension, ctx) {
|
|
|
1163
1285
|
"font-family": "Arial, sans-serif",
|
|
1164
1286
|
"text-anchor": "middle",
|
|
1165
1287
|
"dominant-baseline": "central",
|
|
1166
|
-
class: "pcb-note-dimension-text"
|
|
1288
|
+
class: "pcb-note-dimension-text",
|
|
1289
|
+
transform: `rotate(${textAngle} ${textX} ${textY})`
|
|
1167
1290
|
},
|
|
1168
1291
|
children: [
|
|
1169
1292
|
{
|
|
@@ -3348,7 +3471,7 @@ function getSoftwareUsedString(circuitJson) {
|
|
|
3348
3471
|
var package_default = {
|
|
3349
3472
|
name: "circuit-to-svg",
|
|
3350
3473
|
type: "module",
|
|
3351
|
-
version: "0.0.
|
|
3474
|
+
version: "0.0.255",
|
|
3352
3475
|
description: "Convert Circuit JSON to SVG",
|
|
3353
3476
|
main: "dist/index.js",
|
|
3354
3477
|
files: [
|
|
@@ -3372,7 +3495,7 @@ var package_default = {
|
|
|
3372
3495
|
"bun-match-svg": "^0.0.12",
|
|
3373
3496
|
esbuild: "^0.20.2",
|
|
3374
3497
|
"performance-now": "^2.1.0",
|
|
3375
|
-
"circuit-json": "^0.0.
|
|
3498
|
+
"circuit-json": "^0.0.292",
|
|
3376
3499
|
react: "19.1.0",
|
|
3377
3500
|
"react-cosmos": "7.0.0",
|
|
3378
3501
|
"react-cosmos-plugin-vite": "7.0.0",
|