diff --git a/src/PCBViewer.tsx b/src/PCBViewer.tsx
index 6ce85371..ef37ff24 100644
--- a/src/PCBViewer.tsx
+++ b/src/PCBViewer.tsx
@@ -12,7 +12,6 @@ import useMouseMatrixTransform from "use-mouse-matrix-transform"
import { CanvasElementsRenderer } from "./components/CanvasElementsRenderer"
import type { ManualEditEvent } from "@tscircuit/props"
import { zIndexMap } from "lib/util/z-index-map"
-import { calculateCircuitJsonKey } from "lib/calculate-circuit-json-key"
const defaultTransform = compose(translate(400, 300), scale(40, -40))
@@ -61,10 +60,32 @@ export const PCBViewer = ({
const initialRenderCompleted = useRef(false)
const touchStartRef = useRef<{ x: number; y: number } | null>(null)
- const circuitJsonKey = useMemo(
- () => calculateCircuitJsonKey(circuitJson),
- [circuitJson],
- )
+
+ const pcbElmsPreEdit = useMemo(() => {
+ return (
+ circuitJson?.filter(
+ (e: any) => e.type.startsWith("pcb_") || e.type.startsWith("source_"),
+ ) ?? []
+ )
+ }, [circuitJson])
+
+ const elements = useMemo(() => {
+ return applyEditEvents({
+ circuitJson: pcbElmsPreEdit as any,
+ editEvents,
+ })
+ }, [pcbElmsPreEdit, editEvents])
+
+ // Track the pcb_board element's explicit width/height
+ const boardDimensions = useMemo(() => {
+ const pcbBoard = elements.find((e) => e.type === "pcb_board") as any
+ if (!pcbBoard?.width || !pcbBoard?.height) return null
+ return { width: pcbBoard.width, height: pcbBoard.height }
+ }, [elements])
+
+ // Extract width/height as primitives to avoid object reference changes triggering useEffect
+ const boardWidth = boardDimensions?.width ?? null
+ const boardHeight = boardDimensions?.height ?? null
const resetTransform = () => {
const elmBounds =
@@ -93,31 +114,29 @@ export const PCBViewer = ({
return
}
+ useEffect(() => {
+ if (initialRenderCompleted.current === true) {
+ resetTransform()
+ }
+ }, [
+ boardWidth,
+ boardHeight,
+ elements
+ .filter((e) => e.type === "pcb_board")
+ .flatMap((e: any) => [e.center?.x ?? 0, e.center?.y ?? 0])
+ .join(","),
+ ])
+
useEffect(() => {
if (!refDimensions?.width) return
- if (!circuitJson) return
- if (circuitJson.length === 0) return
+ if (boardWidth === null || boardHeight === null) return
if (!initialRenderCompleted.current) {
resetTransform()
initialRenderCompleted.current = true
+ return
}
- }, [circuitJson, refDimensions])
-
- const pcbElmsPreEdit = useMemo(() => {
- return (
- circuitJson?.filter(
- (e: any) => e.type.startsWith("pcb_") || e.type.startsWith("source_"),
- ) ?? []
- )
- }, [circuitJsonKey])
-
- const elements = useMemo(() => {
- return applyEditEvents({
- circuitJson: pcbElmsPreEdit as any,
- editEvents,
- })
- }, [pcbElmsPreEdit, editEvents])
+ }, [boardWidth, boardHeight, refDimensions])
const onCreateEditEvent = (event: ManualEditEvent) => {
setEditEvents([...editEvents, event])
diff --git a/src/examples/board-resize-test.fixture.tsx b/src/examples/board-resize-test.fixture.tsx
new file mode 100644
index 00000000..0e099307
--- /dev/null
+++ b/src/examples/board-resize-test.fixture.tsx
@@ -0,0 +1,89 @@
+import { Circuit } from "@tscircuit/core"
+import { PCBViewer } from "../PCBViewer"
+import { useState, useMemo } from "react"
+
+export const BoardResizeTest = () => {
+ const [boardSize, setBoardSize] = useState<"small" | "medium" | "large">(
+ "small",
+ )
+ const [showComponent, setShowComponent] = useState(false)
+
+ // Generate circuit JSON for each board size - memoized to avoid recreation
+ const soup = useMemo(() => {
+ const circuit = new Circuit()
+
+ const sizes = {
+ small: { width: "10mm", height: "10mm" },
+ medium: { width: "30mm", height: "30mm" },
+ large: { width: "60mm", height: "60mm" },
+ }
+
+ circuit.add(
+