@tscircuit/pcb-viewer 1.11.282 → 1.11.283
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 +177 -114
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10468,7 +10468,6 @@ var createBoxFromPoints = (points) => {
|
|
|
10468
10468
|
}
|
|
10469
10469
|
return { minX, maxX, minY, maxY };
|
|
10470
10470
|
};
|
|
10471
|
-
var getBoundsFromPoints = createBoxFromPoints;
|
|
10472
10471
|
var mergeBoundingBoxesInternal = (a, b) => ({
|
|
10473
10472
|
minX: Math.min(a.minX, b.minX),
|
|
10474
10473
|
maxX: Math.max(a.maxX, b.maxX),
|
|
@@ -10605,7 +10604,7 @@ function calculateDiagonalLabel(params) {
|
|
|
10605
10604
|
} = params;
|
|
10606
10605
|
const deltaX = dimensionEnd.x - dimensionStart.x;
|
|
10607
10606
|
const deltaY = dimensionEnd.y - dimensionStart.y;
|
|
10608
|
-
const
|
|
10607
|
+
const distance4 = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
10609
10608
|
const screenDeltaX = screenDimensionEnd.x - screenDimensionStart.x;
|
|
10610
10609
|
const screenDeltaY = screenDimensionEnd.y - screenDimensionStart.y;
|
|
10611
10610
|
const screenDistance = Math.sqrt(
|
|
@@ -10647,11 +10646,11 @@ function calculateDiagonalLabel(params) {
|
|
|
10647
10646
|
const x = midX + offsetX;
|
|
10648
10647
|
const y = midY + offsetY;
|
|
10649
10648
|
return {
|
|
10650
|
-
distance:
|
|
10649
|
+
distance: distance4,
|
|
10651
10650
|
screenDistance,
|
|
10652
10651
|
x,
|
|
10653
10652
|
y,
|
|
10654
|
-
show:
|
|
10653
|
+
show: distance4 > 0.01 && screenDistance > 30 && isDiagonal
|
|
10655
10654
|
};
|
|
10656
10655
|
}
|
|
10657
10656
|
|
|
@@ -10945,11 +10944,11 @@ var DimensionOverlay = ({
|
|
|
10945
10944
|
for (const snap of snappingPointsWithScreen) {
|
|
10946
10945
|
const dx = snap.screenPoint.x - screenPoint.x;
|
|
10947
10946
|
const dy = snap.screenPoint.y - screenPoint.y;
|
|
10948
|
-
const
|
|
10949
|
-
if (
|
|
10950
|
-
if (!bestMatch ||
|
|
10947
|
+
const distance4 = Math.hypot(dx, dy);
|
|
10948
|
+
if (distance4 > SNAP_THRESHOLD_PX) continue;
|
|
10949
|
+
if (!bestMatch || distance4 < bestMatch.distance) {
|
|
10951
10950
|
bestMatch = {
|
|
10952
|
-
distance:
|
|
10951
|
+
distance: distance4,
|
|
10953
10952
|
id: snap.id,
|
|
10954
10953
|
point: snap.point
|
|
10955
10954
|
};
|
|
@@ -11548,10 +11547,10 @@ var isInsideOfSmtpad = (elm, point, padding = 0) => {
|
|
|
11548
11547
|
};
|
|
11549
11548
|
var isInsideOfPlatedHole = (hole, point, padding = 0) => {
|
|
11550
11549
|
if (hole.shape === "circle") {
|
|
11551
|
-
const
|
|
11550
|
+
const distance4 = Math.sqrt(
|
|
11552
11551
|
(point.x - hole.x) ** 2 + (point.y - hole.y) ** 2
|
|
11553
11552
|
);
|
|
11554
|
-
return
|
|
11553
|
+
return distance4 <= hole.outer_diameter / 2 + padding;
|
|
11555
11554
|
} else if (hole.shape === "circular_hole_with_rect_pad") {
|
|
11556
11555
|
const dx = Math.abs(point.x - hole.x);
|
|
11557
11556
|
const dy = Math.abs(point.y - hole.y);
|
|
@@ -12379,7 +12378,7 @@ var ErrorOverlay = ({
|
|
|
12379
12378
|
|
|
12380
12379
|
// src/components/MouseElementTracker.tsx
|
|
12381
12380
|
import { pointToSegmentDistance } from "@tscircuit/math-utils";
|
|
12382
|
-
import { distance as
|
|
12381
|
+
import { distance as distance3 } from "circuit-json";
|
|
12383
12382
|
|
|
12384
12383
|
// src/lib/util/if-sets-match-exactly.ts
|
|
12385
12384
|
function ifSetsMatchExactly(set1, set2) {
|
|
@@ -12709,6 +12708,7 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12709
12708
|
const components = elements.filter(
|
|
12710
12709
|
(el) => isPcbComponent(el)
|
|
12711
12710
|
);
|
|
12711
|
+
const groups = elements.filter((el) => isPcbGroup(el));
|
|
12712
12712
|
const hoveredComponentIds = highlightedPrimitives.map((primitive) => {
|
|
12713
12713
|
if (isPcbComponent(primitive._parent_pcb_component)) {
|
|
12714
12714
|
return primitive._parent_pcb_component.pcb_component_id;
|
|
@@ -12718,20 +12718,36 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12718
12718
|
}
|
|
12719
12719
|
return null;
|
|
12720
12720
|
}).filter((id) => Boolean(id));
|
|
12721
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
12722
|
+
hoveredComponentIds.forEach((componentId) => {
|
|
12723
|
+
const component = components.find((c) => c.pcb_component_id === componentId);
|
|
12724
|
+
if (component?.pcb_group_id) {
|
|
12725
|
+
hoveredGroupIds.add(component.pcb_group_id);
|
|
12726
|
+
}
|
|
12727
|
+
});
|
|
12721
12728
|
const isShowingAnchorOffsets = useGlobalStore(
|
|
12722
12729
|
(state) => state.is_showing_group_anchor_offsets
|
|
12723
12730
|
);
|
|
12724
12731
|
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12725
12732
|
return null;
|
|
12726
12733
|
}
|
|
12727
|
-
const
|
|
12734
|
+
const componentTargets = components.map((component) => {
|
|
12728
12735
|
const boardId = component.positioned_relative_to_pcb_board_id;
|
|
12729
12736
|
if (!boardId) return null;
|
|
12730
12737
|
const board = boards.find((b) => b.pcb_board_id === boardId);
|
|
12731
|
-
return board ? { component, board } : null;
|
|
12738
|
+
return board ? { component, board, type: "component" } : null;
|
|
12732
12739
|
}).filter(
|
|
12733
12740
|
(target) => Boolean(target)
|
|
12734
12741
|
);
|
|
12742
|
+
const groupTargets = groups.map((group) => {
|
|
12743
|
+
const boardId = group.positioned_relative_to_pcb_board_id;
|
|
12744
|
+
if (!boardId || !group.center) return null;
|
|
12745
|
+
const board = boards.find((b) => b.pcb_board_id === boardId);
|
|
12746
|
+
return board ? { group, board, type: "group" } : null;
|
|
12747
|
+
}).filter(
|
|
12748
|
+
(target) => Boolean(target)
|
|
12749
|
+
);
|
|
12750
|
+
const targets = [...componentTargets, ...groupTargets];
|
|
12735
12751
|
if (targets.length === 0) return null;
|
|
12736
12752
|
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12737
12753
|
const labelStyle = {
|
|
@@ -12742,9 +12758,13 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12742
12758
|
fontFamily: "monospace",
|
|
12743
12759
|
fontWeight: "bold"
|
|
12744
12760
|
};
|
|
12745
|
-
const targetEntries = targets.filter(
|
|
12746
|
-
(
|
|
12747
|
-
|
|
12761
|
+
const targetEntries = targets.filter((target) => {
|
|
12762
|
+
if (target.type === "component") {
|
|
12763
|
+
return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
|
|
12764
|
+
} else {
|
|
12765
|
+
return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id);
|
|
12766
|
+
}
|
|
12767
|
+
});
|
|
12748
12768
|
if (targetEntries.length === 0) return null;
|
|
12749
12769
|
const boardAnchorScreens = /* @__PURE__ */ new Map();
|
|
12750
12770
|
return /* @__PURE__ */ jsx12(
|
|
@@ -12772,35 +12792,53 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12772
12792
|
width: containerWidth,
|
|
12773
12793
|
height: containerHeight,
|
|
12774
12794
|
children: [
|
|
12775
|
-
targetEntries.map((
|
|
12776
|
-
const anchorPosition = board.center;
|
|
12777
|
-
const
|
|
12778
|
-
|
|
12795
|
+
targetEntries.map((target) => {
|
|
12796
|
+
const anchorPosition = target.board.center;
|
|
12797
|
+
const anchorKey = target.board.pcb_board_id;
|
|
12798
|
+
let targetCenter;
|
|
12799
|
+
let targetId;
|
|
12800
|
+
let displayOffsetX;
|
|
12801
|
+
let displayOffsetY;
|
|
12802
|
+
if (target.type === "component") {
|
|
12803
|
+
targetCenter = target.component.center;
|
|
12804
|
+
targetId = target.component.pcb_component_id;
|
|
12805
|
+
displayOffsetX = target.component.display_offset_x;
|
|
12806
|
+
displayOffsetY = target.component.display_offset_y;
|
|
12807
|
+
} else {
|
|
12808
|
+
if (!target.group.center) return null;
|
|
12809
|
+
targetCenter = {
|
|
12810
|
+
x: target.group.center.x,
|
|
12811
|
+
y: target.group.center.y
|
|
12812
|
+
};
|
|
12813
|
+
targetId = target.group.pcb_group_id;
|
|
12814
|
+
displayOffsetX = target.group.display_offset_x;
|
|
12815
|
+
displayOffsetY = target.group.display_offset_y;
|
|
12816
|
+
}
|
|
12779
12817
|
if (!boardAnchorScreens.has(anchorKey)) {
|
|
12780
12818
|
const screenPoint = applyToPoint12(transform, anchorPosition);
|
|
12781
12819
|
boardAnchorScreens.set(anchorKey, screenPoint);
|
|
12782
12820
|
}
|
|
12783
12821
|
const anchorMarkerScreen = boardAnchorScreens.get(anchorKey);
|
|
12784
|
-
const
|
|
12785
|
-
const offsetX =
|
|
12786
|
-
const offsetY =
|
|
12787
|
-
const xLineLength = Math.abs(
|
|
12788
|
-
const yLineLength = Math.abs(
|
|
12789
|
-
const
|
|
12790
|
-
const
|
|
12791
|
-
const xLabelOffset =
|
|
12792
|
-
const yLabelOffset =
|
|
12822
|
+
const targetScreen = applyToPoint12(transform, targetCenter);
|
|
12823
|
+
const offsetX = targetCenter.x - anchorPosition.x;
|
|
12824
|
+
const offsetY = targetCenter.y - anchorPosition.y;
|
|
12825
|
+
const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
|
|
12826
|
+
const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
|
|
12827
|
+
const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
|
|
12828
|
+
const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
|
|
12829
|
+
const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
12830
|
+
const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
12793
12831
|
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12794
12832
|
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
12795
|
-
const xLabelText =
|
|
12796
|
-
const yLabelText =
|
|
12833
|
+
const xLabelText = displayOffsetX ?? `Board \u0394x: ${offsetX.toFixed(2)}mm`;
|
|
12834
|
+
const yLabelText = displayOffsetY ?? `Board \u0394y: ${offsetY.toFixed(2)}mm`;
|
|
12797
12835
|
return /* @__PURE__ */ jsxs9("g", { children: [
|
|
12798
12836
|
/* @__PURE__ */ jsx12(
|
|
12799
12837
|
"line",
|
|
12800
12838
|
{
|
|
12801
12839
|
x1: anchorMarkerScreen.x,
|
|
12802
12840
|
y1: anchorMarkerScreen.y,
|
|
12803
|
-
x2:
|
|
12841
|
+
x2: targetScreen.x,
|
|
12804
12842
|
y2: anchorMarkerScreen.y,
|
|
12805
12843
|
stroke: COLORS.OFFSET_LINE,
|
|
12806
12844
|
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
@@ -12810,10 +12848,10 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12810
12848
|
/* @__PURE__ */ jsx12(
|
|
12811
12849
|
"line",
|
|
12812
12850
|
{
|
|
12813
|
-
x1:
|
|
12851
|
+
x1: targetScreen.x,
|
|
12814
12852
|
y1: anchorMarkerScreen.y,
|
|
12815
|
-
x2:
|
|
12816
|
-
y2:
|
|
12853
|
+
x2: targetScreen.x,
|
|
12854
|
+
y2: targetScreen.y,
|
|
12817
12855
|
stroke: COLORS.OFFSET_LINE,
|
|
12818
12856
|
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
12819
12857
|
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
@@ -12822,8 +12860,8 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12822
12860
|
/* @__PURE__ */ jsx12(
|
|
12823
12861
|
"circle",
|
|
12824
12862
|
{
|
|
12825
|
-
cx:
|
|
12826
|
-
cy:
|
|
12863
|
+
cx: targetScreen.x,
|
|
12864
|
+
cy: targetScreen.y,
|
|
12827
12865
|
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
12828
12866
|
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
12829
12867
|
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
@@ -12833,9 +12871,9 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12833
12871
|
shouldShowXLabel && /* @__PURE__ */ jsx12(
|
|
12834
12872
|
"foreignObject",
|
|
12835
12873
|
{
|
|
12836
|
-
x: Math.min(anchorMarkerScreen.x,
|
|
12874
|
+
x: Math.min(anchorMarkerScreen.x, targetScreen.x),
|
|
12837
12875
|
y: anchorMarkerScreen.y + xLabelOffset,
|
|
12838
|
-
width: Math.abs(
|
|
12876
|
+
width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
|
|
12839
12877
|
height: 20,
|
|
12840
12878
|
style: { overflow: "visible" },
|
|
12841
12879
|
children: /* @__PURE__ */ jsx12("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
@@ -12844,10 +12882,10 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12844
12882
|
shouldShowYLabel && /* @__PURE__ */ jsx12(
|
|
12845
12883
|
"foreignObject",
|
|
12846
12884
|
{
|
|
12847
|
-
x:
|
|
12848
|
-
y: Math.min(anchorMarkerScreen.y,
|
|
12885
|
+
x: targetScreen.x + yLabelOffset,
|
|
12886
|
+
y: Math.min(anchorMarkerScreen.y, targetScreen.y),
|
|
12849
12887
|
width: 20,
|
|
12850
|
-
height: Math.abs(
|
|
12888
|
+
height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
|
|
12851
12889
|
style: { overflow: "visible" },
|
|
12852
12890
|
children: /* @__PURE__ */ jsx12(
|
|
12853
12891
|
"div",
|
|
@@ -12863,7 +12901,7 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12863
12901
|
)
|
|
12864
12902
|
}
|
|
12865
12903
|
)
|
|
12866
|
-
] }, `${board.pcb_board_id}-${
|
|
12904
|
+
] }, `${target.board.pcb_board_id}-${targetId}-${target.type}`);
|
|
12867
12905
|
}),
|
|
12868
12906
|
Array.from(boardAnchorScreens.entries()).map(
|
|
12869
12907
|
([boardId, anchorScreen]) => /* @__PURE__ */ jsxs9("g", { children: [
|
|
@@ -12900,26 +12938,6 @@ var BoardAnchorOffsetOverlay = ({
|
|
|
12900
12938
|
|
|
12901
12939
|
// src/components/AnchorOffsetOverlay/Group/index.tsx
|
|
12902
12940
|
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
12903
|
-
|
|
12904
|
-
// src/components/AnchorOffsetOverlay/Group/calculateGroupBoundingBox.ts
|
|
12905
|
-
import { distance as distance3 } from "circuit-json";
|
|
12906
|
-
var calculateGroupBoundingBox = (groupComponents) => {
|
|
12907
|
-
const points = [];
|
|
12908
|
-
for (const comp of groupComponents) {
|
|
12909
|
-
if (!comp.center) {
|
|
12910
|
-
continue;
|
|
12911
|
-
}
|
|
12912
|
-
const width = typeof comp.width === "number" ? comp.width : distance3.parse(comp.width);
|
|
12913
|
-
const height = typeof comp.height === "number" ? comp.height : distance3.parse(comp.height);
|
|
12914
|
-
const halfWidth = width / 2;
|
|
12915
|
-
const halfHeight = height / 2;
|
|
12916
|
-
points.push({ x: comp.center.x - halfWidth, y: comp.center.y - halfHeight });
|
|
12917
|
-
points.push({ x: comp.center.x + halfWidth, y: comp.center.y + halfHeight });
|
|
12918
|
-
}
|
|
12919
|
-
return getBoundsFromPoints(points);
|
|
12920
|
-
};
|
|
12921
|
-
|
|
12922
|
-
// src/components/AnchorOffsetOverlay/Group/index.tsx
|
|
12923
12941
|
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
12924
12942
|
var GroupAnchorOffsetOverlay = ({
|
|
12925
12943
|
elements,
|
|
@@ -12941,29 +12959,53 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12941
12959
|
}
|
|
12942
12960
|
return null;
|
|
12943
12961
|
}).filter((id) => Boolean(id));
|
|
12962
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
12963
|
+
hoveredComponentIds.forEach((componentId) => {
|
|
12964
|
+
const component = components.find((c) => c.pcb_component_id === componentId);
|
|
12965
|
+
if (component?.pcb_group_id) {
|
|
12966
|
+
hoveredGroupIds.add(component.pcb_group_id);
|
|
12967
|
+
}
|
|
12968
|
+
if (component?.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12969
|
+
hoveredGroupIds.add(component.positioned_relative_to_pcb_group_id);
|
|
12970
|
+
}
|
|
12971
|
+
});
|
|
12944
12972
|
const isShowingAnchorOffsets = useGlobalStore(
|
|
12945
12973
|
(s) => s.is_showing_group_anchor_offsets
|
|
12946
12974
|
);
|
|
12947
12975
|
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12948
12976
|
return null;
|
|
12949
12977
|
}
|
|
12950
|
-
const
|
|
12978
|
+
const componentTargets = components.map((component) => {
|
|
12951
12979
|
if (component.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12952
12980
|
const parentGroup = groups.find(
|
|
12953
12981
|
(group) => group.pcb_group_id === component.positioned_relative_to_pcb_group_id
|
|
12954
12982
|
);
|
|
12955
|
-
return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
|
|
12983
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
|
|
12956
12984
|
}
|
|
12957
12985
|
if (component.pcb_group_id) {
|
|
12958
12986
|
const parentGroup = groups.find(
|
|
12959
12987
|
(group) => group.pcb_group_id === component.pcb_group_id
|
|
12960
12988
|
);
|
|
12961
|
-
return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
|
|
12989
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
|
|
12962
12990
|
}
|
|
12963
12991
|
return null;
|
|
12964
12992
|
}).filter(
|
|
12965
12993
|
(target) => Boolean(target)
|
|
12966
12994
|
);
|
|
12995
|
+
const groupTargets = groups.map((group) => {
|
|
12996
|
+
if (group.position_mode === "relative_to_group_anchor" && group.positioned_relative_to_pcb_group_id) {
|
|
12997
|
+
const parentGroup = groups.find(
|
|
12998
|
+
(g) => g.pcb_group_id === group.positioned_relative_to_pcb_group_id
|
|
12999
|
+
);
|
|
13000
|
+
if (parentGroup && parentGroup.anchor_position && group.center) {
|
|
13001
|
+
return { group, parentGroup, type: "group" };
|
|
13002
|
+
}
|
|
13003
|
+
}
|
|
13004
|
+
return null;
|
|
13005
|
+
}).filter(
|
|
13006
|
+
(target) => Boolean(target)
|
|
13007
|
+
);
|
|
13008
|
+
const targets = [...componentTargets, ...groupTargets];
|
|
12967
13009
|
if (targets.length === 0) return null;
|
|
12968
13010
|
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12969
13011
|
const labelStyle = {
|
|
@@ -12974,15 +13016,22 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12974
13016
|
fontFamily: "monospace",
|
|
12975
13017
|
fontWeight: "bold"
|
|
12976
13018
|
};
|
|
12977
|
-
const targetEntries = targets.filter(
|
|
12978
|
-
(
|
|
12979
|
-
|
|
13019
|
+
const targetEntries = targets.filter((target) => {
|
|
13020
|
+
if (target.type === "component") {
|
|
13021
|
+
return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
|
|
13022
|
+
} else {
|
|
13023
|
+
return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id) || hoveredGroupIds.has(target.parentGroup.pcb_group_id);
|
|
13024
|
+
}
|
|
13025
|
+
});
|
|
12980
13026
|
if (targetEntries.length === 0) return null;
|
|
12981
13027
|
const groupAnchorScreens = /* @__PURE__ */ new Map();
|
|
12982
|
-
targetEntries.forEach((
|
|
12983
|
-
if (!parentGroup.anchor_position) return;
|
|
12984
|
-
const anchorScreen = applyToPoint13(
|
|
12985
|
-
|
|
13028
|
+
targetEntries.forEach((target) => {
|
|
13029
|
+
if (!target.parentGroup.anchor_position) return;
|
|
13030
|
+
const anchorScreen = applyToPoint13(
|
|
13031
|
+
transform,
|
|
13032
|
+
target.parentGroup.anchor_position
|
|
13033
|
+
);
|
|
13034
|
+
groupAnchorScreens.set(target.parentGroup.pcb_group_id, anchorScreen);
|
|
12986
13035
|
});
|
|
12987
13036
|
return /* @__PURE__ */ jsx13(
|
|
12988
13037
|
"div",
|
|
@@ -13009,34 +13058,48 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13009
13058
|
width: containerWidth,
|
|
13010
13059
|
height: containerHeight,
|
|
13011
13060
|
children: [
|
|
13012
|
-
targetEntries.map((
|
|
13013
|
-
const anchor = parentGroup.anchor_position;
|
|
13014
|
-
|
|
13015
|
-
if (!anchor || !center) return null;
|
|
13061
|
+
targetEntries.map((target) => {
|
|
13062
|
+
const anchor = target.parentGroup.anchor_position;
|
|
13063
|
+
if (!anchor) return null;
|
|
13016
13064
|
const anchorMarkerPosition = { x: anchor.x, y: anchor.y };
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13065
|
+
let targetCenter = null;
|
|
13066
|
+
let targetId;
|
|
13067
|
+
let displayOffsetX;
|
|
13068
|
+
let displayOffsetY;
|
|
13069
|
+
if (target.type === "component") {
|
|
13070
|
+
const center = target.component.center;
|
|
13071
|
+
if (!center) return null;
|
|
13072
|
+
targetCenter = { x: center.x, y: center.y };
|
|
13073
|
+
targetId = target.component.pcb_component_id;
|
|
13074
|
+
displayOffsetX = target.component.display_offset_x;
|
|
13075
|
+
displayOffsetY = target.component.display_offset_y;
|
|
13076
|
+
} else {
|
|
13077
|
+
if (!target.group.center) return null;
|
|
13078
|
+
targetCenter = {
|
|
13079
|
+
x: target.group.center.x,
|
|
13080
|
+
y: target.group.center.y
|
|
13081
|
+
};
|
|
13082
|
+
targetId = target.group.pcb_group_id;
|
|
13083
|
+
displayOffsetX = target.group.display_offset_x;
|
|
13084
|
+
displayOffsetY = target.group.display_offset_y;
|
|
13085
|
+
}
|
|
13023
13086
|
const offsetX = targetCenter.x - anchorMarkerPosition.x;
|
|
13024
13087
|
const offsetY = targetCenter.y - anchorMarkerPosition.y;
|
|
13025
13088
|
const anchorMarkerScreen = applyToPoint13(
|
|
13026
13089
|
transform,
|
|
13027
13090
|
anchorMarkerPosition
|
|
13028
13091
|
);
|
|
13029
|
-
const
|
|
13030
|
-
const xLineLength = Math.abs(
|
|
13031
|
-
const yLineLength = Math.abs(
|
|
13032
|
-
const
|
|
13033
|
-
const
|
|
13034
|
-
const xLabelOffset =
|
|
13035
|
-
const yLabelOffset =
|
|
13092
|
+
const targetScreen = applyToPoint13(transform, targetCenter);
|
|
13093
|
+
const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
|
|
13094
|
+
const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
|
|
13095
|
+
const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
|
|
13096
|
+
const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
|
|
13097
|
+
const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
13098
|
+
const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
13036
13099
|
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13037
13100
|
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13038
|
-
const xLabelText =
|
|
13039
|
-
const yLabelText =
|
|
13101
|
+
const xLabelText = displayOffsetX ?? `\u0394x: ${offsetX.toFixed(2)}mm`;
|
|
13102
|
+
const yLabelText = displayOffsetY ?? `\u0394y: ${offsetY.toFixed(2)}mm`;
|
|
13040
13103
|
return /* @__PURE__ */ jsxs10(
|
|
13041
13104
|
"g",
|
|
13042
13105
|
{
|
|
@@ -13046,7 +13109,7 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13046
13109
|
{
|
|
13047
13110
|
x1: anchorMarkerScreen.x,
|
|
13048
13111
|
y1: anchorMarkerScreen.y,
|
|
13049
|
-
x2:
|
|
13112
|
+
x2: targetScreen.x,
|
|
13050
13113
|
y2: anchorMarkerScreen.y,
|
|
13051
13114
|
stroke: COLORS.OFFSET_LINE,
|
|
13052
13115
|
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
@@ -13056,10 +13119,10 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13056
13119
|
/* @__PURE__ */ jsx13(
|
|
13057
13120
|
"line",
|
|
13058
13121
|
{
|
|
13059
|
-
x1:
|
|
13122
|
+
x1: targetScreen.x,
|
|
13060
13123
|
y1: anchorMarkerScreen.y,
|
|
13061
|
-
x2:
|
|
13062
|
-
y2:
|
|
13124
|
+
x2: targetScreen.x,
|
|
13125
|
+
y2: targetScreen.y,
|
|
13063
13126
|
stroke: COLORS.OFFSET_LINE,
|
|
13064
13127
|
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
13065
13128
|
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
@@ -13068,8 +13131,8 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13068
13131
|
/* @__PURE__ */ jsx13(
|
|
13069
13132
|
"circle",
|
|
13070
13133
|
{
|
|
13071
|
-
cx:
|
|
13072
|
-
cy:
|
|
13134
|
+
cx: targetScreen.x,
|
|
13135
|
+
cy: targetScreen.y,
|
|
13073
13136
|
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
13074
13137
|
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
13075
13138
|
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
@@ -13079,9 +13142,9 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13079
13142
|
shouldShowXLabel && /* @__PURE__ */ jsx13(
|
|
13080
13143
|
"foreignObject",
|
|
13081
13144
|
{
|
|
13082
|
-
x: Math.min(anchorMarkerScreen.x,
|
|
13145
|
+
x: Math.min(anchorMarkerScreen.x, targetScreen.x),
|
|
13083
13146
|
y: anchorMarkerScreen.y + xLabelOffset,
|
|
13084
|
-
width: Math.abs(
|
|
13147
|
+
width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
|
|
13085
13148
|
height: 20,
|
|
13086
13149
|
style: { overflow: "visible" },
|
|
13087
13150
|
children: /* @__PURE__ */ jsx13("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
@@ -13090,10 +13153,10 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13090
13153
|
shouldShowYLabel && /* @__PURE__ */ jsx13(
|
|
13091
13154
|
"foreignObject",
|
|
13092
13155
|
{
|
|
13093
|
-
x:
|
|
13094
|
-
y: Math.min(anchorMarkerScreen.y,
|
|
13156
|
+
x: targetScreen.x + yLabelOffset,
|
|
13157
|
+
y: Math.min(anchorMarkerScreen.y, targetScreen.y),
|
|
13095
13158
|
width: 20,
|
|
13096
|
-
height: Math.abs(
|
|
13159
|
+
height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
|
|
13097
13160
|
style: { overflow: "visible" },
|
|
13098
13161
|
children: /* @__PURE__ */ jsx13(
|
|
13099
13162
|
"div",
|
|
@@ -13111,7 +13174,7 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13111
13174
|
)
|
|
13112
13175
|
]
|
|
13113
13176
|
},
|
|
13114
|
-
`${parentGroup.pcb_group_id}-${
|
|
13177
|
+
`${target.parentGroup.pcb_group_id}-${targetId}-${target.type}`
|
|
13115
13178
|
);
|
|
13116
13179
|
}),
|
|
13117
13180
|
Array.from(groupAnchorScreens.entries()).map(
|
|
@@ -13190,22 +13253,22 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
13190
13253
|
for (const primitive of primitives) {
|
|
13191
13254
|
if (!primitive._element) continue;
|
|
13192
13255
|
if ("x1" in primitive && primitive._element?.type === "pcb_trace") {
|
|
13193
|
-
const
|
|
13256
|
+
const distance4 = pointToSegmentDistance(
|
|
13194
13257
|
{ x: rwPoint.x, y: rwPoint.y },
|
|
13195
13258
|
{ x: primitive.x1, y: primitive.y1 },
|
|
13196
13259
|
{ x: primitive.x2, y: primitive.y2 }
|
|
13197
13260
|
);
|
|
13198
13261
|
const lineWidth = primitive.width || 0.5;
|
|
13199
13262
|
const detectionThreshold = Math.max(lineWidth * 25, 2) / transform.a;
|
|
13200
|
-
if (
|
|
13263
|
+
if (distance4 < detectionThreshold) {
|
|
13201
13264
|
newMousedPrimitives.push(primitive);
|
|
13202
13265
|
}
|
|
13203
13266
|
continue;
|
|
13204
13267
|
}
|
|
13205
13268
|
if (primitive.pcb_drawing_type === "polygon") {
|
|
13206
13269
|
const points = primitive.points.map((point) => ({
|
|
13207
|
-
x:
|
|
13208
|
-
y:
|
|
13270
|
+
x: distance3.parse(point.x),
|
|
13271
|
+
y: distance3.parse(point.y)
|
|
13209
13272
|
}));
|
|
13210
13273
|
const boundingBox = getPolygonBoundingBox(points);
|
|
13211
13274
|
if (!boundingBox) continue;
|
|
@@ -13219,8 +13282,8 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
13219
13282
|
}
|
|
13220
13283
|
if (primitive.pcb_drawing_type === "polygon_with_arcs") {
|
|
13221
13284
|
const points = primitive.brep_shape.outer_ring.vertices.map((v) => ({
|
|
13222
|
-
x:
|
|
13223
|
-
y:
|
|
13285
|
+
x: distance3.parse(v.x),
|
|
13286
|
+
y: distance3.parse(v.y)
|
|
13224
13287
|
}));
|
|
13225
13288
|
const boundingBox = getPolygonBoundingBox(points);
|
|
13226
13289
|
if (!boundingBox) continue;
|
|
@@ -13668,11 +13731,11 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13668
13731
|
connectedIds.forEach((id) => {
|
|
13669
13732
|
const pos = getElementPosition(id);
|
|
13670
13733
|
if (pos) {
|
|
13671
|
-
const
|
|
13734
|
+
const distance4 = Math.sqrt(
|
|
13672
13735
|
(sourcePoint.x - pos.x) ** 2 + (sourcePoint.y - pos.y) ** 2
|
|
13673
13736
|
);
|
|
13674
|
-
if (
|
|
13675
|
-
minDistance =
|
|
13737
|
+
if (distance4 < minDistance && distance4 > 0) {
|
|
13738
|
+
minDistance = distance4;
|
|
13676
13739
|
nearestPoint = pos;
|
|
13677
13740
|
}
|
|
13678
13741
|
}
|
|
@@ -13752,7 +13815,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
13752
13815
|
// package.json
|
|
13753
13816
|
var package_default = {
|
|
13754
13817
|
name: "@tscircuit/pcb-viewer",
|
|
13755
|
-
version: "1.11.
|
|
13818
|
+
version: "1.11.282",
|
|
13756
13819
|
main: "dist/index.js",
|
|
13757
13820
|
type: "module",
|
|
13758
13821
|
repository: "tscircuit/pcb-viewer",
|