@tscircuit/pcb-viewer 1.11.238 → 1.11.239
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 +351 -38
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6412,7 +6412,7 @@ var ToastContainer = () => {
|
|
|
6412
6412
|
};
|
|
6413
6413
|
|
|
6414
6414
|
// src/PCBViewer.tsx
|
|
6415
|
-
import { useEffect as useEffect16, useMemo as
|
|
6415
|
+
import { useEffect as useEffect16, useMemo as useMemo7, useRef as useRef11, useState as useState11 } from "react";
|
|
6416
6416
|
|
|
6417
6417
|
// node_modules/react-use/esm/misc/util.js
|
|
6418
6418
|
var noop = function() {
|
|
@@ -6963,7 +6963,7 @@ function addInteractionMetadataToPrimitives({
|
|
|
6963
6963
|
}
|
|
6964
6964
|
|
|
6965
6965
|
// src/components/CanvasElementsRenderer.tsx
|
|
6966
|
-
import { useCallback as
|
|
6966
|
+
import { useCallback as useCallback5, useMemo as useMemo6, useState as useState10 } from "react";
|
|
6967
6967
|
|
|
6968
6968
|
// src/lib/util/expand-stroke.ts
|
|
6969
6969
|
function getExpandedStroke(strokeInput, defaultWidth) {
|
|
@@ -9702,43 +9702,306 @@ var WarningGraphicsOverlay = ({
|
|
|
9702
9702
|
};
|
|
9703
9703
|
|
|
9704
9704
|
// src/components/DimensionOverlay.tsx
|
|
9705
|
-
import { useEffect as useEffect7, useRef as useRef5, useState as useState3 } from "react";
|
|
9705
|
+
import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo3, useRef as useRef5, useState as useState3 } from "react";
|
|
9706
9706
|
import { applyToPoint as applyToPoint8, identity as identity4, inverse as inverse2 } from "transformation-matrix";
|
|
9707
|
+
|
|
9708
|
+
// src/lib/util/get-primitive-bounding-box.ts
|
|
9709
|
+
var mergeNumber = (a, b, fn) => fn(a, b);
|
|
9710
|
+
var rotatePoint = (x, y, centerX, centerY, rotationDeg) => {
|
|
9711
|
+
const radians = rotationDeg * Math.PI / 180;
|
|
9712
|
+
const cos = Math.cos(radians);
|
|
9713
|
+
const sin = Math.sin(radians);
|
|
9714
|
+
const translatedX = x - centerX;
|
|
9715
|
+
const translatedY = y - centerY;
|
|
9716
|
+
const rotatedX = translatedX * cos - translatedY * sin;
|
|
9717
|
+
const rotatedY = translatedX * sin + translatedY * cos;
|
|
9718
|
+
return {
|
|
9719
|
+
x: rotatedX + centerX,
|
|
9720
|
+
y: rotatedY + centerY
|
|
9721
|
+
};
|
|
9722
|
+
};
|
|
9723
|
+
var createBoxFromPoints = (points) => {
|
|
9724
|
+
if (points.length === 0) return null;
|
|
9725
|
+
let minX = points[0].x;
|
|
9726
|
+
let maxX = points[0].x;
|
|
9727
|
+
let minY = points[0].y;
|
|
9728
|
+
let maxY = points[0].y;
|
|
9729
|
+
for (const point of points) {
|
|
9730
|
+
minX = mergeNumber(minX, point.x, Math.min);
|
|
9731
|
+
maxX = mergeNumber(maxX, point.x, Math.max);
|
|
9732
|
+
minY = mergeNumber(minY, point.y, Math.min);
|
|
9733
|
+
maxY = mergeNumber(maxY, point.y, Math.max);
|
|
9734
|
+
}
|
|
9735
|
+
return { minX, maxX, minY, maxY };
|
|
9736
|
+
};
|
|
9737
|
+
var mergeBoundingBoxesInternal = (a, b) => ({
|
|
9738
|
+
minX: Math.min(a.minX, b.minX),
|
|
9739
|
+
maxX: Math.max(a.maxX, b.maxX),
|
|
9740
|
+
minY: Math.min(a.minY, b.minY),
|
|
9741
|
+
maxY: Math.max(a.maxY, b.maxY)
|
|
9742
|
+
});
|
|
9743
|
+
var mergeBoundingBoxes = (existing, next) => {
|
|
9744
|
+
if (!existing) return next;
|
|
9745
|
+
return mergeBoundingBoxesInternal(existing, next);
|
|
9746
|
+
};
|
|
9747
|
+
var getPrimitiveBoundingBox = (primitive) => {
|
|
9748
|
+
switch (primitive.pcb_drawing_type) {
|
|
9749
|
+
case "line": {
|
|
9750
|
+
const halfWidth = (primitive.width ?? 0) / 2;
|
|
9751
|
+
const points = [
|
|
9752
|
+
{ x: primitive.x1, y: primitive.y1 },
|
|
9753
|
+
{ x: primitive.x2, y: primitive.y2 }
|
|
9754
|
+
];
|
|
9755
|
+
const baseBox = createBoxFromPoints(points);
|
|
9756
|
+
if (!baseBox) return null;
|
|
9757
|
+
return {
|
|
9758
|
+
minX: baseBox.minX - halfWidth,
|
|
9759
|
+
maxX: baseBox.maxX + halfWidth,
|
|
9760
|
+
minY: baseBox.minY - halfWidth,
|
|
9761
|
+
maxY: baseBox.maxY + halfWidth
|
|
9762
|
+
};
|
|
9763
|
+
}
|
|
9764
|
+
case "rect": {
|
|
9765
|
+
const halfW = primitive.w / 2;
|
|
9766
|
+
const halfH = primitive.h / 2;
|
|
9767
|
+
const corners = [
|
|
9768
|
+
{ x: primitive.x - halfW, y: primitive.y - halfH },
|
|
9769
|
+
{ x: primitive.x + halfW, y: primitive.y - halfH },
|
|
9770
|
+
{ x: primitive.x + halfW, y: primitive.y + halfH },
|
|
9771
|
+
{ x: primitive.x - halfW, y: primitive.y + halfH }
|
|
9772
|
+
];
|
|
9773
|
+
const rotation = primitive.ccw_rotation ?? 0;
|
|
9774
|
+
const rotatedCorners = rotation === 0 ? corners : corners.map(
|
|
9775
|
+
(corner) => rotatePoint(
|
|
9776
|
+
corner.x,
|
|
9777
|
+
corner.y,
|
|
9778
|
+
primitive.x,
|
|
9779
|
+
primitive.y,
|
|
9780
|
+
rotation
|
|
9781
|
+
)
|
|
9782
|
+
);
|
|
9783
|
+
return createBoxFromPoints(rotatedCorners);
|
|
9784
|
+
}
|
|
9785
|
+
case "circle": {
|
|
9786
|
+
return {
|
|
9787
|
+
minX: primitive.x - primitive.r,
|
|
9788
|
+
maxX: primitive.x + primitive.r,
|
|
9789
|
+
minY: primitive.y - primitive.r,
|
|
9790
|
+
maxY: primitive.y + primitive.r
|
|
9791
|
+
};
|
|
9792
|
+
}
|
|
9793
|
+
case "oval": {
|
|
9794
|
+
return {
|
|
9795
|
+
minX: primitive.x - primitive.rX,
|
|
9796
|
+
maxX: primitive.x + primitive.rX,
|
|
9797
|
+
minY: primitive.y - primitive.rY,
|
|
9798
|
+
maxY: primitive.y + primitive.rY
|
|
9799
|
+
};
|
|
9800
|
+
}
|
|
9801
|
+
case "pill": {
|
|
9802
|
+
const halfW = primitive.w / 2;
|
|
9803
|
+
const halfH = primitive.h / 2;
|
|
9804
|
+
const corners = [
|
|
9805
|
+
{ x: primitive.x - halfW, y: primitive.y - halfH },
|
|
9806
|
+
{ x: primitive.x + halfW, y: primitive.y - halfH },
|
|
9807
|
+
{ x: primitive.x + halfW, y: primitive.y + halfH },
|
|
9808
|
+
{ x: primitive.x - halfW, y: primitive.y + halfH }
|
|
9809
|
+
];
|
|
9810
|
+
const rotation = primitive.ccw_rotation ?? 0;
|
|
9811
|
+
const rotatedCorners = rotation === 0 ? corners : corners.map(
|
|
9812
|
+
(corner) => rotatePoint(
|
|
9813
|
+
corner.x,
|
|
9814
|
+
corner.y,
|
|
9815
|
+
primitive.x,
|
|
9816
|
+
primitive.y,
|
|
9817
|
+
rotation
|
|
9818
|
+
)
|
|
9819
|
+
);
|
|
9820
|
+
return createBoxFromPoints(rotatedCorners);
|
|
9821
|
+
}
|
|
9822
|
+
case "polygon": {
|
|
9823
|
+
return createBoxFromPoints(primitive.points);
|
|
9824
|
+
}
|
|
9825
|
+
case "polygon_with_arcs": {
|
|
9826
|
+
const points = primitive.brep_shape.outer_ring.vertices.map((vertex) => ({
|
|
9827
|
+
x: vertex.x,
|
|
9828
|
+
y: vertex.y
|
|
9829
|
+
}));
|
|
9830
|
+
return createBoxFromPoints(points);
|
|
9831
|
+
}
|
|
9832
|
+
case "text": {
|
|
9833
|
+
const size = primitive.size ?? 0;
|
|
9834
|
+
const width = primitive.text ? primitive.text.length * size * 0.6 : 0;
|
|
9835
|
+
const height = size;
|
|
9836
|
+
if (width === 0 && height === 0) {
|
|
9837
|
+
return {
|
|
9838
|
+
minX: primitive.x,
|
|
9839
|
+
maxX: primitive.x,
|
|
9840
|
+
minY: primitive.y,
|
|
9841
|
+
maxY: primitive.y
|
|
9842
|
+
};
|
|
9843
|
+
}
|
|
9844
|
+
const halfW = width / 2;
|
|
9845
|
+
const halfH = height / 2;
|
|
9846
|
+
return {
|
|
9847
|
+
minX: primitive.x - halfW,
|
|
9848
|
+
maxX: primitive.x + halfW,
|
|
9849
|
+
minY: primitive.y - halfH,
|
|
9850
|
+
maxY: primitive.y + halfH
|
|
9851
|
+
};
|
|
9852
|
+
}
|
|
9853
|
+
default:
|
|
9854
|
+
return null;
|
|
9855
|
+
}
|
|
9856
|
+
};
|
|
9857
|
+
|
|
9858
|
+
// src/components/DimensionOverlay.tsx
|
|
9707
9859
|
import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
9860
|
+
var SNAP_THRESHOLD_PX = 16;
|
|
9861
|
+
var SNAP_MARKER_SIZE = 5;
|
|
9862
|
+
var shouldExcludePrimitiveFromSnapping = (primitive) => {
|
|
9863
|
+
if (primitive.pcb_drawing_type === "text") return true;
|
|
9864
|
+
const element = primitive._element;
|
|
9865
|
+
if (!element || typeof element !== "object") {
|
|
9866
|
+
return false;
|
|
9867
|
+
}
|
|
9868
|
+
const elementType = typeof element.type === "string" ? element.type : void 0;
|
|
9869
|
+
if (!elementType) return false;
|
|
9870
|
+
if (elementType.startsWith("pcb_silkscreen_")) return true;
|
|
9871
|
+
if (elementType.startsWith("pcb_note_")) return true;
|
|
9872
|
+
if (elementType === "pcb_text") return true;
|
|
9873
|
+
if (elementType.startsWith("pcb_fabrication_note_") && elementType !== "pcb_fabrication_note_rect") {
|
|
9874
|
+
return true;
|
|
9875
|
+
}
|
|
9876
|
+
return false;
|
|
9877
|
+
};
|
|
9708
9878
|
var DimensionOverlay = ({
|
|
9709
9879
|
children,
|
|
9710
9880
|
transform,
|
|
9711
|
-
focusOnHover = false
|
|
9881
|
+
focusOnHover = false,
|
|
9882
|
+
primitives = []
|
|
9712
9883
|
}) => {
|
|
9713
9884
|
if (!transform) transform = identity4();
|
|
9714
9885
|
const [dimensionToolVisible, setDimensionToolVisible] = useState3(false);
|
|
9715
9886
|
const [dimensionToolStretching, setDimensionToolStretching] = useState3(false);
|
|
9716
9887
|
const [measureToolArmed, setMeasureToolArmed] = useState3(false);
|
|
9717
|
-
const
|
|
9888
|
+
const [activeSnapIds, setActiveSnapIds] = useState3({
|
|
9889
|
+
start: null,
|
|
9890
|
+
end: null
|
|
9891
|
+
});
|
|
9892
|
+
const disarmMeasure = useCallback3(() => {
|
|
9718
9893
|
if (measureToolArmed) {
|
|
9719
9894
|
setMeasureToolArmed(false);
|
|
9720
9895
|
window.dispatchEvent(new Event("disarm-dimension-tool"));
|
|
9721
9896
|
}
|
|
9722
|
-
};
|
|
9897
|
+
}, [measureToolArmed]);
|
|
9723
9898
|
const [dStart, setDStart] = useState3({ x: 0, y: 0 });
|
|
9724
9899
|
const [dEnd, setDEnd] = useState3({ x: 0, y: 0 });
|
|
9725
9900
|
const mousePosRef = useRef5({ x: 0, y: 0 });
|
|
9726
9901
|
const containerRef = useRef5(null);
|
|
9727
9902
|
const container = containerRef.current;
|
|
9728
9903
|
const containerBounds = container?.getBoundingClientRect();
|
|
9904
|
+
const elementBoundingBoxes = useMemo3(() => {
|
|
9905
|
+
const boundingBoxes = /* @__PURE__ */ new Map();
|
|
9906
|
+
for (const primitive of primitives) {
|
|
9907
|
+
if (!primitive._element) continue;
|
|
9908
|
+
if (shouldExcludePrimitiveFromSnapping(primitive)) continue;
|
|
9909
|
+
const bbox = getPrimitiveBoundingBox(primitive);
|
|
9910
|
+
if (!bbox) continue;
|
|
9911
|
+
const existing = boundingBoxes.get(primitive._element);
|
|
9912
|
+
boundingBoxes.set(
|
|
9913
|
+
primitive._element,
|
|
9914
|
+
mergeBoundingBoxes(existing ?? void 0, bbox)
|
|
9915
|
+
);
|
|
9916
|
+
}
|
|
9917
|
+
return boundingBoxes;
|
|
9918
|
+
}, [primitives]);
|
|
9919
|
+
const snappingPoints = useMemo3(() => {
|
|
9920
|
+
const points = [];
|
|
9921
|
+
elementBoundingBoxes.forEach((bounds, element) => {
|
|
9922
|
+
if (!bounds) return;
|
|
9923
|
+
const centerX = (bounds.minX + bounds.maxX) / 2;
|
|
9924
|
+
const centerY = (bounds.minY + bounds.maxY) / 2;
|
|
9925
|
+
const anchorPoints = {
|
|
9926
|
+
top_left: { x: bounds.minX, y: bounds.minY },
|
|
9927
|
+
top_center: { x: centerX, y: bounds.minY },
|
|
9928
|
+
top_right: { x: bounds.maxX, y: bounds.minY },
|
|
9929
|
+
center_left: { x: bounds.minX, y: centerY },
|
|
9930
|
+
center: { x: centerX, y: centerY },
|
|
9931
|
+
center_right: { x: bounds.maxX, y: centerY },
|
|
9932
|
+
bottom_left: { x: bounds.minX, y: bounds.maxY },
|
|
9933
|
+
bottom_center: { x: centerX, y: bounds.maxY },
|
|
9934
|
+
bottom_right: { x: bounds.maxX, y: bounds.maxY }
|
|
9935
|
+
};
|
|
9936
|
+
for (const [anchor, point] of Object.entries(anchorPoints)) {
|
|
9937
|
+
points.push({
|
|
9938
|
+
anchor,
|
|
9939
|
+
point,
|
|
9940
|
+
element
|
|
9941
|
+
});
|
|
9942
|
+
}
|
|
9943
|
+
});
|
|
9944
|
+
return points;
|
|
9945
|
+
}, [elementBoundingBoxes]);
|
|
9946
|
+
const snappingPointsWithScreen = useMemo3(() => {
|
|
9947
|
+
return snappingPoints.map((snap, index) => ({
|
|
9948
|
+
...snap,
|
|
9949
|
+
id: `${index}-${snap.anchor}`,
|
|
9950
|
+
screenPoint: applyToPoint8(transform, snap.point)
|
|
9951
|
+
}));
|
|
9952
|
+
}, [snappingPoints, transform]);
|
|
9953
|
+
const findSnap = useCallback3(
|
|
9954
|
+
(rwPoint) => {
|
|
9955
|
+
if (snappingPointsWithScreen.length === 0) {
|
|
9956
|
+
return { point: rwPoint, id: null };
|
|
9957
|
+
}
|
|
9958
|
+
const screenPoint = applyToPoint8(transform, rwPoint);
|
|
9959
|
+
let bestMatch = null;
|
|
9960
|
+
for (const snap of snappingPointsWithScreen) {
|
|
9961
|
+
const dx = snap.screenPoint.x - screenPoint.x;
|
|
9962
|
+
const dy = snap.screenPoint.y - screenPoint.y;
|
|
9963
|
+
const distance5 = Math.hypot(dx, dy);
|
|
9964
|
+
if (distance5 > SNAP_THRESHOLD_PX) continue;
|
|
9965
|
+
if (!bestMatch || distance5 < bestMatch.distance) {
|
|
9966
|
+
bestMatch = {
|
|
9967
|
+
distance: distance5,
|
|
9968
|
+
id: snap.id,
|
|
9969
|
+
point: snap.point
|
|
9970
|
+
};
|
|
9971
|
+
}
|
|
9972
|
+
}
|
|
9973
|
+
if (!bestMatch) {
|
|
9974
|
+
return { point: rwPoint, id: null };
|
|
9975
|
+
}
|
|
9976
|
+
return { point: bestMatch.point, id: bestMatch.id };
|
|
9977
|
+
},
|
|
9978
|
+
[snappingPointsWithScreen, transform]
|
|
9979
|
+
);
|
|
9729
9980
|
useEffect7(() => {
|
|
9730
9981
|
const container2 = containerRef.current;
|
|
9731
9982
|
const down = (e) => {
|
|
9732
9983
|
if (e.key === "d") {
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9984
|
+
const snap = findSnap({
|
|
9985
|
+
x: mousePosRef.current.x,
|
|
9986
|
+
y: mousePosRef.current.y
|
|
9987
|
+
});
|
|
9988
|
+
setDStart({ x: snap.point.x, y: snap.point.y });
|
|
9989
|
+
setDEnd({ x: snap.point.x, y: snap.point.y });
|
|
9990
|
+
setActiveSnapIds({ start: snap.id, end: snap.id });
|
|
9991
|
+
if (dimensionToolVisible) {
|
|
9992
|
+
setDimensionToolVisible(false);
|
|
9993
|
+
setDimensionToolStretching(false);
|
|
9994
|
+
setActiveSnapIds({ start: null, end: null });
|
|
9995
|
+
} else {
|
|
9996
|
+
setDimensionToolVisible(true);
|
|
9997
|
+
setDimensionToolStretching(true);
|
|
9998
|
+
}
|
|
9737
9999
|
disarmMeasure();
|
|
9738
10000
|
}
|
|
9739
10001
|
if (e.key === "Escape") {
|
|
9740
10002
|
setDimensionToolVisible(false);
|
|
9741
10003
|
setDimensionToolStretching(false);
|
|
10004
|
+
setActiveSnapIds({ start: null, end: null });
|
|
9742
10005
|
disarmMeasure();
|
|
9743
10006
|
}
|
|
9744
10007
|
};
|
|
@@ -9772,7 +10035,7 @@ var DimensionOverlay = ({
|
|
|
9772
10035
|
container2.removeEventListener("mouseleave", removeKeyListener);
|
|
9773
10036
|
}
|
|
9774
10037
|
};
|
|
9775
|
-
}, [containerRef]);
|
|
10038
|
+
}, [containerRef, dimensionToolVisible, disarmMeasure, findSnap]);
|
|
9776
10039
|
const screenDStart = applyToPoint8(transform, dStart);
|
|
9777
10040
|
const screenDEnd = applyToPoint8(transform, dEnd);
|
|
9778
10041
|
const arrowScreenBounds = {
|
|
@@ -9811,7 +10074,9 @@ var DimensionOverlay = ({
|
|
|
9811
10074
|
mousePosRef.current.x = rwPoint.x;
|
|
9812
10075
|
mousePosRef.current.y = rwPoint.y;
|
|
9813
10076
|
if (dimensionToolStretching) {
|
|
9814
|
-
|
|
10077
|
+
const snap = findSnap(rwPoint);
|
|
10078
|
+
setDEnd({ x: snap.point.x, y: snap.point.y });
|
|
10079
|
+
setActiveSnapIds((prev) => ({ ...prev, end: snap.id }));
|
|
9815
10080
|
}
|
|
9816
10081
|
},
|
|
9817
10082
|
onMouseDown: (e) => {
|
|
@@ -9820,15 +10085,19 @@ var DimensionOverlay = ({
|
|
|
9820
10085
|
const y = e.clientY - rect.top;
|
|
9821
10086
|
const rwPoint = applyToPoint8(inverse2(transform), { x, y });
|
|
9822
10087
|
if (measureToolArmed && !dimensionToolVisible) {
|
|
9823
|
-
|
|
9824
|
-
|
|
10088
|
+
const snap = findSnap(rwPoint);
|
|
10089
|
+
setDStart({ x: snap.point.x, y: snap.point.y });
|
|
10090
|
+
setDEnd({ x: snap.point.x, y: snap.point.y });
|
|
10091
|
+
setActiveSnapIds({ start: snap.id, end: snap.id });
|
|
9825
10092
|
setDimensionToolVisible(true);
|
|
9826
10093
|
setDimensionToolStretching(true);
|
|
9827
10094
|
disarmMeasure();
|
|
9828
10095
|
} else if (dimensionToolStretching) {
|
|
9829
10096
|
setDimensionToolStretching(false);
|
|
10097
|
+
setActiveSnapIds((prev) => ({ ...prev, end: null }));
|
|
9830
10098
|
} else if (dimensionToolVisible) {
|
|
9831
10099
|
setDimensionToolVisible(false);
|
|
10100
|
+
setActiveSnapIds({ start: null, end: null });
|
|
9832
10101
|
}
|
|
9833
10102
|
},
|
|
9834
10103
|
children: [
|
|
@@ -9952,6 +10221,49 @@ var DimensionOverlay = ({
|
|
|
9952
10221
|
]
|
|
9953
10222
|
}
|
|
9954
10223
|
),
|
|
10224
|
+
dimensionToolStretching && snappingPointsWithScreen.map((snap) => {
|
|
10225
|
+
const isActive = snap.id === activeSnapIds.start || snap.id === activeSnapIds.end;
|
|
10226
|
+
const half = SNAP_MARKER_SIZE / 2;
|
|
10227
|
+
return /* @__PURE__ */ jsxs4(
|
|
10228
|
+
"svg",
|
|
10229
|
+
{
|
|
10230
|
+
width: SNAP_MARKER_SIZE,
|
|
10231
|
+
height: SNAP_MARKER_SIZE,
|
|
10232
|
+
style: {
|
|
10233
|
+
position: "absolute",
|
|
10234
|
+
left: snap.screenPoint.x - half,
|
|
10235
|
+
top: snap.screenPoint.y - half,
|
|
10236
|
+
pointerEvents: "none",
|
|
10237
|
+
zIndex: zIndexMap.dimensionOverlay
|
|
10238
|
+
},
|
|
10239
|
+
children: [
|
|
10240
|
+
/* @__PURE__ */ jsx6(
|
|
10241
|
+
"line",
|
|
10242
|
+
{
|
|
10243
|
+
x1: 0,
|
|
10244
|
+
y1: 0,
|
|
10245
|
+
x2: SNAP_MARKER_SIZE,
|
|
10246
|
+
y2: SNAP_MARKER_SIZE,
|
|
10247
|
+
stroke: isActive ? "#66ccff" : "white",
|
|
10248
|
+
strokeWidth: 1
|
|
10249
|
+
}
|
|
10250
|
+
),
|
|
10251
|
+
/* @__PURE__ */ jsx6(
|
|
10252
|
+
"line",
|
|
10253
|
+
{
|
|
10254
|
+
x1: SNAP_MARKER_SIZE,
|
|
10255
|
+
y1: 0,
|
|
10256
|
+
x2: 0,
|
|
10257
|
+
y2: SNAP_MARKER_SIZE,
|
|
10258
|
+
stroke: isActive ? "#66ccff" : "white",
|
|
10259
|
+
strokeWidth: 1
|
|
10260
|
+
}
|
|
10261
|
+
)
|
|
10262
|
+
]
|
|
10263
|
+
},
|
|
10264
|
+
snap.id
|
|
10265
|
+
);
|
|
10266
|
+
}),
|
|
9955
10267
|
/* @__PURE__ */ jsxs4(
|
|
9956
10268
|
"div",
|
|
9957
10269
|
{
|
|
@@ -11055,7 +11367,7 @@ var ErrorOverlay = ({
|
|
|
11055
11367
|
};
|
|
11056
11368
|
|
|
11057
11369
|
// src/components/MouseElementTracker.tsx
|
|
11058
|
-
import { useState as useState7, useMemo as
|
|
11370
|
+
import { useState as useState7, useMemo as useMemo4 } from "react";
|
|
11059
11371
|
import { applyToPoint as applyToPoint12, inverse as inverse5 } from "transformation-matrix";
|
|
11060
11372
|
|
|
11061
11373
|
// src/components/ElementOverlayBox.tsx
|
|
@@ -11472,7 +11784,7 @@ var MouseElementTracker = ({
|
|
|
11472
11784
|
}) => {
|
|
11473
11785
|
const [mousedPrimitives, setMousedPrimitives] = useState7([]);
|
|
11474
11786
|
const [mousePos, setMousePos] = useState7({ x: 0, y: 0 });
|
|
11475
|
-
const highlightedPrimitives =
|
|
11787
|
+
const highlightedPrimitives = useMemo4(() => {
|
|
11476
11788
|
const highlightedPrimitives2 = [];
|
|
11477
11789
|
for (const primitive of mousedPrimitives) {
|
|
11478
11790
|
if (primitive._element?.type === "pcb_via") continue;
|
|
@@ -11836,15 +12148,15 @@ var PcbGroupOverlay = ({
|
|
|
11836
12148
|
|
|
11837
12149
|
// src/components/RatsNestOverlay.tsx
|
|
11838
12150
|
import { applyToPoint as applyToPoint14, identity as identity9 } from "transformation-matrix";
|
|
11839
|
-
import { useMemo as
|
|
12151
|
+
import { useMemo as useMemo5 } from "react";
|
|
11840
12152
|
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
11841
12153
|
var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
11842
12154
|
const isShowingRatsNest = useGlobalStore((s) => s.is_showing_rats_nest);
|
|
11843
|
-
const { netMap, idToNetMap } =
|
|
12155
|
+
const { netMap, idToNetMap } = useMemo5(
|
|
11844
12156
|
() => getFullConnectivityMapFromCircuitJson(soup || []),
|
|
11845
12157
|
[soup]
|
|
11846
12158
|
);
|
|
11847
|
-
const ratsNestLines =
|
|
12159
|
+
const ratsNestLines = useMemo5(() => {
|
|
11848
12160
|
if (!soup || !isShowingRatsNest) return [];
|
|
11849
12161
|
const getElementPosition = (id) => {
|
|
11850
12162
|
const element = su(soup)[id.replace(/_\d+$/, "")].get(id);
|
|
@@ -11941,7 +12253,7 @@ var RatsNestOverlay = ({ transform, soup, children }) => {
|
|
|
11941
12253
|
import {
|
|
11942
12254
|
useEffect as useEffect15,
|
|
11943
12255
|
useState as useState9,
|
|
11944
|
-
useCallback as
|
|
12256
|
+
useCallback as useCallback4,
|
|
11945
12257
|
useRef as useRef10
|
|
11946
12258
|
} from "react";
|
|
11947
12259
|
import { css as css3 } from "@emotion/css";
|
|
@@ -11949,7 +12261,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
11949
12261
|
// package.json
|
|
11950
12262
|
var package_default = {
|
|
11951
12263
|
name: "@tscircuit/pcb-viewer",
|
|
11952
|
-
version: "1.11.
|
|
12264
|
+
version: "1.11.238",
|
|
11953
12265
|
main: "dist/index.js",
|
|
11954
12266
|
type: "module",
|
|
11955
12267
|
repository: "tscircuit/pcb-viewer",
|
|
@@ -12294,20 +12606,20 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
12294
12606
|
useHotKey("6", hotKeyCallbacks["6"]);
|
|
12295
12607
|
useHotKey("7", hotKeyCallbacks["7"]);
|
|
12296
12608
|
useHotKey("8", hotKeyCallbacks["8"]);
|
|
12297
|
-
const handleMouseEnter =
|
|
12609
|
+
const handleMouseEnter = useCallback4(() => {
|
|
12298
12610
|
setIsMouseOverContainer(true);
|
|
12299
12611
|
}, [setIsMouseOverContainer]);
|
|
12300
|
-
const handleMouseLeave =
|
|
12612
|
+
const handleMouseLeave = useCallback4(() => {
|
|
12301
12613
|
setIsMouseOverContainer(false);
|
|
12302
12614
|
setLayerMenuOpen(false);
|
|
12303
12615
|
setViewMenuOpen(false);
|
|
12304
12616
|
setErrorsOpen(false);
|
|
12305
12617
|
setHoveredErrorId(null);
|
|
12306
12618
|
}, [setIsMouseOverContainer, setHoveredErrorId]);
|
|
12307
|
-
const handleLayerMenuToggle =
|
|
12619
|
+
const handleLayerMenuToggle = useCallback4(() => {
|
|
12308
12620
|
setLayerMenuOpen(!isLayerMenuOpen);
|
|
12309
12621
|
}, [isLayerMenuOpen]);
|
|
12310
|
-
const handleErrorsToggle =
|
|
12622
|
+
const handleErrorsToggle = useCallback4(() => {
|
|
12311
12623
|
const newErrorsOpen = !isErrorsOpen;
|
|
12312
12624
|
setErrorsOpen(newErrorsOpen);
|
|
12313
12625
|
if (newErrorsOpen) {
|
|
@@ -12317,20 +12629,20 @@ var ToolbarOverlay = ({ children, elements }) => {
|
|
|
12317
12629
|
setHoveredErrorId(null);
|
|
12318
12630
|
}
|
|
12319
12631
|
}, [isErrorsOpen, setHoveredErrorId]);
|
|
12320
|
-
const handleEditTraceToggle =
|
|
12632
|
+
const handleEditTraceToggle = useCallback4(() => {
|
|
12321
12633
|
setEditMode(editModes.in_draw_trace_mode ? "off" : "draw_trace");
|
|
12322
12634
|
}, [editModes.in_draw_trace_mode, setEditMode]);
|
|
12323
|
-
const handleMoveComponentToggle =
|
|
12635
|
+
const handleMoveComponentToggle = useCallback4(() => {
|
|
12324
12636
|
setEditMode(editModes.in_move_footprint_mode ? "off" : "move_footprint");
|
|
12325
12637
|
}, [editModes.in_move_footprint_mode, setEditMode]);
|
|
12326
|
-
const handleRatsNestToggle =
|
|
12638
|
+
const handleRatsNestToggle = useCallback4(() => {
|
|
12327
12639
|
setIsShowingRatsNest(!viewSettings.is_showing_rats_nest);
|
|
12328
12640
|
}, [viewSettings.is_showing_rats_nest, setIsShowingRatsNest]);
|
|
12329
|
-
const handleMeasureToolClick =
|
|
12641
|
+
const handleMeasureToolClick = useCallback4(() => {
|
|
12330
12642
|
setMeasureToolArmed(true);
|
|
12331
12643
|
window.dispatchEvent(new Event("arm-dimension-tool"));
|
|
12332
12644
|
}, []);
|
|
12333
|
-
const handleViewMenuToggle =
|
|
12645
|
+
const handleViewMenuToggle = useCallback4(() => {
|
|
12334
12646
|
const newViewMenuOpen = !isViewMenuOpen;
|
|
12335
12647
|
setViewMenuOpen(newViewMenuOpen);
|
|
12336
12648
|
if (newViewMenuOpen) {
|
|
@@ -12765,7 +13077,7 @@ import { jsx as jsx16 } from "react/jsx-runtime";
|
|
|
12765
13077
|
var CanvasElementsRenderer = (props) => {
|
|
12766
13078
|
const { transform, elements } = props;
|
|
12767
13079
|
const hoveredErrorId = useGlobalStore((state) => state.hovered_error_id);
|
|
12768
|
-
const [primitivesWithoutInteractionMetadata, connectivityMap] =
|
|
13080
|
+
const [primitivesWithoutInteractionMetadata, connectivityMap] = useMemo6(() => {
|
|
12769
13081
|
const primitivesWithoutInteractionMetadata2 = props.elements.flatMap(
|
|
12770
13082
|
(elm) => convertElementToPrimitives(elm, props.elements)
|
|
12771
13083
|
);
|
|
@@ -12778,7 +13090,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12778
13090
|
drawingObjectIdsWithMouseOver: /* @__PURE__ */ new Set(),
|
|
12779
13091
|
primitiveIdsInMousedOverNet: []
|
|
12780
13092
|
});
|
|
12781
|
-
const errorRelatedIds =
|
|
13093
|
+
const errorRelatedIds = useMemo6(() => {
|
|
12782
13094
|
if (!hoveredErrorId) return [];
|
|
12783
13095
|
const errorElements = elements.filter(
|
|
12784
13096
|
(el) => el.type.includes("error")
|
|
@@ -12797,7 +13109,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12797
13109
|
}
|
|
12798
13110
|
return relatedIds;
|
|
12799
13111
|
}, [hoveredErrorId, elements]);
|
|
12800
|
-
const primitives =
|
|
13112
|
+
const primitives = useMemo6(() => {
|
|
12801
13113
|
const combinedPrimitiveIds = [
|
|
12802
13114
|
...hoverState.primitiveIdsInMousedOverNet,
|
|
12803
13115
|
...errorRelatedIds
|
|
@@ -12808,7 +13120,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12808
13120
|
primitiveIdsInMousedOverNet: combinedPrimitiveIds
|
|
12809
13121
|
});
|
|
12810
13122
|
}, [primitivesWithoutInteractionMetadata, hoverState, errorRelatedIds]);
|
|
12811
|
-
const onMouseOverPrimitives =
|
|
13123
|
+
const onMouseOverPrimitives = useCallback5(
|
|
12812
13124
|
(primitivesHoveredOver) => {
|
|
12813
13125
|
const primitiveIdsInMousedOverNet = [];
|
|
12814
13126
|
for (const primitive of primitivesHoveredOver) {
|
|
@@ -12861,6 +13173,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12861
13173
|
{
|
|
12862
13174
|
transform,
|
|
12863
13175
|
focusOnHover: props.focusOnHover,
|
|
13176
|
+
primitives: primitivesWithoutInteractionMetadata,
|
|
12864
13177
|
children: /* @__PURE__ */ jsx16(ToolbarOverlay, { elements, children: /* @__PURE__ */ jsx16(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx16(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx16(PcbGroupOverlay, { transform, elements, children: /* @__PURE__ */ jsx16(
|
|
12865
13178
|
DebugGraphicsOverlay,
|
|
12866
13179
|
{
|
|
@@ -12970,7 +13283,7 @@ var PCBViewer = ({
|
|
|
12970
13283
|
editEvents = editEventsProp ?? editEvents;
|
|
12971
13284
|
const initialRenderCompleted = useRef11(false);
|
|
12972
13285
|
const touchStartRef = useRef11(null);
|
|
12973
|
-
const circuitJsonKey =
|
|
13286
|
+
const circuitJsonKey = useMemo7(
|
|
12974
13287
|
() => calculateCircuitJsonKey(circuitJson),
|
|
12975
13288
|
[circuitJson]
|
|
12976
13289
|
);
|
|
@@ -13003,12 +13316,12 @@ var PCBViewer = ({
|
|
|
13003
13316
|
initialRenderCompleted.current = true;
|
|
13004
13317
|
}
|
|
13005
13318
|
}, [circuitJson, refDimensions]);
|
|
13006
|
-
const pcbElmsPreEdit =
|
|
13319
|
+
const pcbElmsPreEdit = useMemo7(() => {
|
|
13007
13320
|
return circuitJson?.filter(
|
|
13008
13321
|
(e) => e.type.startsWith("pcb_") || e.type.startsWith("source_")
|
|
13009
13322
|
) ?? [];
|
|
13010
13323
|
}, [circuitJsonKey]);
|
|
13011
|
-
const elements =
|
|
13324
|
+
const elements = useMemo7(() => {
|
|
13012
13325
|
return applyEditEvents({
|
|
13013
13326
|
circuitJson: pcbElmsPreEdit,
|
|
13014
13327
|
editEvents
|
|
@@ -13025,7 +13338,7 @@ var PCBViewer = ({
|
|
|
13025
13338
|
setEditEvents(newEditEvents);
|
|
13026
13339
|
onEditEventsChanged?.(newEditEvents);
|
|
13027
13340
|
};
|
|
13028
|
-
const mergedInitialState =
|
|
13341
|
+
const mergedInitialState = useMemo7(
|
|
13029
13342
|
() => ({
|
|
13030
13343
|
...initialState,
|
|
13031
13344
|
...disablePcbGroups && { is_showing_pcb_groups: false }
|