@tscircuit/pcb-viewer 1.11.282 → 1.11.284
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 +189 -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;
|
|
12739
|
+
}).filter(
|
|
12740
|
+
(target) => Boolean(target)
|
|
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;
|
|
12732
12747
|
}).filter(
|
|
12733
12748
|
(target) => Boolean(target)
|
|
12734
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,65 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12941
12959
|
}
|
|
12942
12960
|
return null;
|
|
12943
12961
|
}).filter((id) => Boolean(id));
|
|
12962
|
+
const collectParentGroups = (groupId, collected) => {
|
|
12963
|
+
if (collected.has(groupId)) return;
|
|
12964
|
+
collected.add(groupId);
|
|
12965
|
+
const group = groups.find((g) => g.pcb_group_id === groupId);
|
|
12966
|
+
if (group?.position_mode === "relative_to_group_anchor" && group.positioned_relative_to_pcb_group_id) {
|
|
12967
|
+
collectParentGroups(group.positioned_relative_to_pcb_group_id, collected);
|
|
12968
|
+
}
|
|
12969
|
+
};
|
|
12970
|
+
const hoveredGroupIds = /* @__PURE__ */ new Set();
|
|
12971
|
+
hoveredComponentIds.forEach((componentId) => {
|
|
12972
|
+
const component = components.find((c) => c.pcb_component_id === componentId);
|
|
12973
|
+
if (!component) return;
|
|
12974
|
+
if (component.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12975
|
+
collectParentGroups(
|
|
12976
|
+
component.positioned_relative_to_pcb_group_id,
|
|
12977
|
+
hoveredGroupIds
|
|
12978
|
+
);
|
|
12979
|
+
}
|
|
12980
|
+
if (component.pcb_group_id) {
|
|
12981
|
+
collectParentGroups(component.pcb_group_id, hoveredGroupIds);
|
|
12982
|
+
}
|
|
12983
|
+
});
|
|
12944
12984
|
const isShowingAnchorOffsets = useGlobalStore(
|
|
12945
12985
|
(s) => s.is_showing_group_anchor_offsets
|
|
12946
12986
|
);
|
|
12947
12987
|
if (!isShowingAnchorOffsets && hoveredComponentIds.length === 0) {
|
|
12948
12988
|
return null;
|
|
12949
12989
|
}
|
|
12950
|
-
const
|
|
12990
|
+
const componentTargets = components.map((component) => {
|
|
12951
12991
|
if (component.position_mode === "relative_to_group_anchor" && component.positioned_relative_to_pcb_group_id) {
|
|
12952
12992
|
const parentGroup = groups.find(
|
|
12953
12993
|
(group) => group.pcb_group_id === component.positioned_relative_to_pcb_group_id
|
|
12954
12994
|
);
|
|
12955
|
-
return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
|
|
12995
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
|
|
12956
12996
|
}
|
|
12957
12997
|
if (component.pcb_group_id) {
|
|
12958
12998
|
const parentGroup = groups.find(
|
|
12959
12999
|
(group) => group.pcb_group_id === component.pcb_group_id
|
|
12960
13000
|
);
|
|
12961
|
-
return parentGroup && parentGroup.anchor_position ? { component, parentGroup } : null;
|
|
13001
|
+
return parentGroup && parentGroup.anchor_position ? { component, parentGroup, type: "component" } : null;
|
|
13002
|
+
}
|
|
13003
|
+
return null;
|
|
13004
|
+
}).filter(
|
|
13005
|
+
(target) => Boolean(target)
|
|
13006
|
+
);
|
|
13007
|
+
const groupTargets = groups.map((group) => {
|
|
13008
|
+
if (group.position_mode === "relative_to_group_anchor" && group.positioned_relative_to_pcb_group_id) {
|
|
13009
|
+
const parentGroup = groups.find(
|
|
13010
|
+
(g) => g.pcb_group_id === group.positioned_relative_to_pcb_group_id
|
|
13011
|
+
);
|
|
13012
|
+
if (parentGroup && parentGroup.anchor_position && group.center) {
|
|
13013
|
+
return { group, parentGroup, type: "group" };
|
|
13014
|
+
}
|
|
12962
13015
|
}
|
|
12963
13016
|
return null;
|
|
12964
13017
|
}).filter(
|
|
12965
13018
|
(target) => Boolean(target)
|
|
12966
13019
|
);
|
|
13020
|
+
const targets = [...componentTargets, ...groupTargets];
|
|
12967
13021
|
if (targets.length === 0) return null;
|
|
12968
13022
|
const shouldShowAllTargets = hoveredComponentIds.length === 0;
|
|
12969
13023
|
const labelStyle = {
|
|
@@ -12974,15 +13028,22 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
12974
13028
|
fontFamily: "monospace",
|
|
12975
13029
|
fontWeight: "bold"
|
|
12976
13030
|
};
|
|
12977
|
-
const targetEntries = targets.filter(
|
|
12978
|
-
(
|
|
12979
|
-
|
|
13031
|
+
const targetEntries = targets.filter((target) => {
|
|
13032
|
+
if (target.type === "component") {
|
|
13033
|
+
return shouldShowAllTargets || hoveredComponentIds.includes(target.component.pcb_component_id);
|
|
13034
|
+
} else {
|
|
13035
|
+
return shouldShowAllTargets || hoveredGroupIds.has(target.group.pcb_group_id) || hoveredGroupIds.has(target.parentGroup.pcb_group_id);
|
|
13036
|
+
}
|
|
13037
|
+
});
|
|
12980
13038
|
if (targetEntries.length === 0) return null;
|
|
12981
13039
|
const groupAnchorScreens = /* @__PURE__ */ new Map();
|
|
12982
|
-
targetEntries.forEach((
|
|
12983
|
-
if (!parentGroup.anchor_position) return;
|
|
12984
|
-
const anchorScreen = applyToPoint13(
|
|
12985
|
-
|
|
13040
|
+
targetEntries.forEach((target) => {
|
|
13041
|
+
if (!target.parentGroup.anchor_position) return;
|
|
13042
|
+
const anchorScreen = applyToPoint13(
|
|
13043
|
+
transform,
|
|
13044
|
+
target.parentGroup.anchor_position
|
|
13045
|
+
);
|
|
13046
|
+
groupAnchorScreens.set(target.parentGroup.pcb_group_id, anchorScreen);
|
|
12986
13047
|
});
|
|
12987
13048
|
return /* @__PURE__ */ jsx13(
|
|
12988
13049
|
"div",
|
|
@@ -13009,34 +13070,48 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13009
13070
|
width: containerWidth,
|
|
13010
13071
|
height: containerHeight,
|
|
13011
13072
|
children: [
|
|
13012
|
-
targetEntries.map((
|
|
13013
|
-
const anchor = parentGroup.anchor_position;
|
|
13014
|
-
|
|
13015
|
-
if (!anchor || !center) return null;
|
|
13073
|
+
targetEntries.map((target) => {
|
|
13074
|
+
const anchor = target.parentGroup.anchor_position;
|
|
13075
|
+
if (!anchor) return null;
|
|
13016
13076
|
const anchorMarkerPosition = { x: anchor.x, y: anchor.y };
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13077
|
+
let targetCenter = null;
|
|
13078
|
+
let targetId;
|
|
13079
|
+
let displayOffsetX;
|
|
13080
|
+
let displayOffsetY;
|
|
13081
|
+
if (target.type === "component") {
|
|
13082
|
+
const center = target.component.center;
|
|
13083
|
+
if (!center) return null;
|
|
13084
|
+
targetCenter = { x: center.x, y: center.y };
|
|
13085
|
+
targetId = target.component.pcb_component_id;
|
|
13086
|
+
displayOffsetX = target.component.display_offset_x;
|
|
13087
|
+
displayOffsetY = target.component.display_offset_y;
|
|
13088
|
+
} else {
|
|
13089
|
+
if (!target.group.center) return null;
|
|
13090
|
+
targetCenter = {
|
|
13091
|
+
x: target.group.center.x,
|
|
13092
|
+
y: target.group.center.y
|
|
13093
|
+
};
|
|
13094
|
+
targetId = target.group.pcb_group_id;
|
|
13095
|
+
displayOffsetX = target.group.display_offset_x;
|
|
13096
|
+
displayOffsetY = target.group.display_offset_y;
|
|
13097
|
+
}
|
|
13023
13098
|
const offsetX = targetCenter.x - anchorMarkerPosition.x;
|
|
13024
13099
|
const offsetY = targetCenter.y - anchorMarkerPosition.y;
|
|
13025
13100
|
const anchorMarkerScreen = applyToPoint13(
|
|
13026
13101
|
transform,
|
|
13027
13102
|
anchorMarkerPosition
|
|
13028
13103
|
);
|
|
13029
|
-
const
|
|
13030
|
-
const xLineLength = Math.abs(
|
|
13031
|
-
const yLineLength = Math.abs(
|
|
13032
|
-
const
|
|
13033
|
-
const
|
|
13034
|
-
const xLabelOffset =
|
|
13035
|
-
const yLabelOffset =
|
|
13104
|
+
const targetScreen = applyToPoint13(transform, targetCenter);
|
|
13105
|
+
const xLineLength = Math.abs(targetScreen.x - anchorMarkerScreen.x);
|
|
13106
|
+
const yLineLength = Math.abs(targetScreen.y - anchorMarkerScreen.y);
|
|
13107
|
+
const isTargetAboveAnchor = targetScreen.y < anchorMarkerScreen.y;
|
|
13108
|
+
const isTargetRightOfAnchor = targetScreen.x > anchorMarkerScreen.x;
|
|
13109
|
+
const xLabelOffset = isTargetAboveAnchor ? VISUAL_CONFIG.LABEL_OFFSET_ABOVE : VISUAL_CONFIG.LABEL_OFFSET_BELOW;
|
|
13110
|
+
const yLabelOffset = isTargetRightOfAnchor ? VISUAL_CONFIG.LABEL_OFFSET_RIGHT : VISUAL_CONFIG.LABEL_OFFSET_LEFT;
|
|
13036
13111
|
const shouldShowXLabel = xLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13037
13112
|
const shouldShowYLabel = yLineLength > VISUAL_CONFIG.MIN_LINE_LENGTH_FOR_LABEL;
|
|
13038
|
-
const xLabelText =
|
|
13039
|
-
const yLabelText =
|
|
13113
|
+
const xLabelText = displayOffsetX ?? `\u0394x: ${offsetX.toFixed(2)}mm`;
|
|
13114
|
+
const yLabelText = displayOffsetY ?? `\u0394y: ${offsetY.toFixed(2)}mm`;
|
|
13040
13115
|
return /* @__PURE__ */ jsxs10(
|
|
13041
13116
|
"g",
|
|
13042
13117
|
{
|
|
@@ -13046,7 +13121,7 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13046
13121
|
{
|
|
13047
13122
|
x1: anchorMarkerScreen.x,
|
|
13048
13123
|
y1: anchorMarkerScreen.y,
|
|
13049
|
-
x2:
|
|
13124
|
+
x2: targetScreen.x,
|
|
13050
13125
|
y2: anchorMarkerScreen.y,
|
|
13051
13126
|
stroke: COLORS.OFFSET_LINE,
|
|
13052
13127
|
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
@@ -13056,10 +13131,10 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13056
13131
|
/* @__PURE__ */ jsx13(
|
|
13057
13132
|
"line",
|
|
13058
13133
|
{
|
|
13059
|
-
x1:
|
|
13134
|
+
x1: targetScreen.x,
|
|
13060
13135
|
y1: anchorMarkerScreen.y,
|
|
13061
|
-
x2:
|
|
13062
|
-
y2:
|
|
13136
|
+
x2: targetScreen.x,
|
|
13137
|
+
y2: targetScreen.y,
|
|
13063
13138
|
stroke: COLORS.OFFSET_LINE,
|
|
13064
13139
|
strokeWidth: VISUAL_CONFIG.LINE_STROKE_WIDTH,
|
|
13065
13140
|
strokeDasharray: VISUAL_CONFIG.LINE_DASH_PATTERN
|
|
@@ -13068,8 +13143,8 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13068
13143
|
/* @__PURE__ */ jsx13(
|
|
13069
13144
|
"circle",
|
|
13070
13145
|
{
|
|
13071
|
-
cx:
|
|
13072
|
-
cy:
|
|
13146
|
+
cx: targetScreen.x,
|
|
13147
|
+
cy: targetScreen.y,
|
|
13073
13148
|
r: VISUAL_CONFIG.COMPONENT_MARKER_RADIUS,
|
|
13074
13149
|
fill: COLORS.COMPONENT_MARKER_FILL,
|
|
13075
13150
|
stroke: COLORS.COMPONENT_MARKER_STROKE,
|
|
@@ -13079,9 +13154,9 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13079
13154
|
shouldShowXLabel && /* @__PURE__ */ jsx13(
|
|
13080
13155
|
"foreignObject",
|
|
13081
13156
|
{
|
|
13082
|
-
x: Math.min(anchorMarkerScreen.x,
|
|
13157
|
+
x: Math.min(anchorMarkerScreen.x, targetScreen.x),
|
|
13083
13158
|
y: anchorMarkerScreen.y + xLabelOffset,
|
|
13084
|
-
width: Math.abs(
|
|
13159
|
+
width: Math.abs(targetScreen.x - anchorMarkerScreen.x),
|
|
13085
13160
|
height: 20,
|
|
13086
13161
|
style: { overflow: "visible" },
|
|
13087
13162
|
children: /* @__PURE__ */ jsx13("div", { style: { ...labelStyle, textAlign: "center" }, children: xLabelText })
|
|
@@ -13090,10 +13165,10 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13090
13165
|
shouldShowYLabel && /* @__PURE__ */ jsx13(
|
|
13091
13166
|
"foreignObject",
|
|
13092
13167
|
{
|
|
13093
|
-
x:
|
|
13094
|
-
y: Math.min(anchorMarkerScreen.y,
|
|
13168
|
+
x: targetScreen.x + yLabelOffset,
|
|
13169
|
+
y: Math.min(anchorMarkerScreen.y, targetScreen.y),
|
|
13095
13170
|
width: 20,
|
|
13096
|
-
height: Math.abs(
|
|
13171
|
+
height: Math.abs(targetScreen.y - anchorMarkerScreen.y),
|
|
13097
13172
|
style: { overflow: "visible" },
|
|
13098
13173
|
children: /* @__PURE__ */ jsx13(
|
|
13099
13174
|
"div",
|
|
@@ -13111,7 +13186,7 @@ var GroupAnchorOffsetOverlay = ({
|
|
|
13111
13186
|
)
|
|
13112
13187
|
]
|
|
13113
13188
|
},
|
|
13114
|
-
`${parentGroup.pcb_group_id}-${
|
|
13189
|
+
`${target.parentGroup.pcb_group_id}-${targetId}-${target.type}`
|
|
13115
13190
|
);
|
|
13116
13191
|
}),
|
|
13117
13192
|
Array.from(groupAnchorScreens.entries()).map(
|
|
@@ -13190,22 +13265,22 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
13190
13265
|
for (const primitive of primitives) {
|
|
13191
13266
|
if (!primitive._element) continue;
|
|
13192
13267
|
if ("x1" in primitive && primitive._element?.type === "pcb_trace") {
|
|
13193
|
-
const
|
|
13268
|
+
const distance4 = pointToSegmentDistance(
|
|
13194
13269
|
{ x: rwPoint.x, y: rwPoint.y },
|
|
13195
13270
|
{ x: primitive.x1, y: primitive.y1 },
|
|
13196
13271
|
{ x: primitive.x2, y: primitive.y2 }
|
|
13197
13272
|
);
|
|
13198
13273
|
const lineWidth = primitive.width || 0.5;
|
|
13199
13274
|
const detectionThreshold = Math.max(lineWidth * 25, 2) / transform.a;
|
|
13200
|
-
if (
|
|
13275
|
+
if (distance4 < detectionThreshold) {
|
|
13201
13276
|
newMousedPrimitives.push(primitive);
|
|
13202
13277
|
}
|
|
13203
13278
|
continue;
|
|
13204
13279
|
}
|
|
13205
13280
|
if (primitive.pcb_drawing_type === "polygon") {
|
|
13206
13281
|
const points = primitive.points.map((point) => ({
|
|
13207
|
-
x:
|
|
13208
|
-
y:
|
|
13282
|
+
x: distance3.parse(point.x),
|
|
13283
|
+
y: distance3.parse(point.y)
|
|
13209
13284
|
}));
|
|
13210
13285
|
const boundingBox = getPolygonBoundingBox(points);
|
|
13211
13286
|
if (!boundingBox) continue;
|
|
@@ -13219,8 +13294,8 @@ var getPrimitivesUnderPoint = (primitives, rwPoint, transform) => {
|
|
|
13219
13294
|
}
|
|
13220
13295
|
if (primitive.pcb_drawing_type === "polygon_with_arcs") {
|
|
13221
13296
|
const points = primitive.brep_shape.outer_ring.vertices.map((v) => ({
|
|
13222
|
-
x:
|
|
13223
|
-
y:
|
|
13297
|
+
x: distance3.parse(v.x),
|
|
13298
|
+
y: distance3.parse(v.y)
|
|
13224
13299
|
}));
|
|
13225
13300
|
const boundingBox = getPolygonBoundingBox(points);
|
|
13226
13301
|
if (!boundingBox) continue;
|
|
@@ -13668,11 +13743,11 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
13668
13743
|
connectedIds.forEach((id) => {
|
|
13669
13744
|
const pos = getElementPosition(id);
|
|
13670
13745
|
if (pos) {
|
|
13671
|
-
const
|
|
13746
|
+
const distance4 = Math.sqrt(
|
|
13672
13747
|
(sourcePoint.x - pos.x) ** 2 + (sourcePoint.y - pos.y) ** 2
|
|
13673
13748
|
);
|
|
13674
|
-
if (
|
|
13675
|
-
minDistance =
|
|
13749
|
+
if (distance4 < minDistance && distance4 > 0) {
|
|
13750
|
+
minDistance = distance4;
|
|
13676
13751
|
nearestPoint = pos;
|
|
13677
13752
|
}
|
|
13678
13753
|
}
|
|
@@ -13752,7 +13827,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
13752
13827
|
// package.json
|
|
13753
13828
|
var package_default = {
|
|
13754
13829
|
name: "@tscircuit/pcb-viewer",
|
|
13755
|
-
version: "1.11.
|
|
13830
|
+
version: "1.11.283",
|
|
13756
13831
|
main: "dist/index.js",
|
|
13757
13832
|
type: "module",
|
|
13758
13833
|
repository: "tscircuit/pcb-viewer",
|