From 98df5134cb7c0ad9017a5243f6f52ebaefd26e5d Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Tue, 28 Jul 2026 15:22:56 +0200 Subject: [PATCH] fix(canvas): las placas solo pintan encima cuando estan POSADAS en un zocalo El bump global a zIndex 3 (efecto iman del Round Display) puso TODAS las placas por encima de TODOS los componentes: una resistencia al lado de un Arduino quedaba oculta tras la placa en cualquier ejemplo normal (se veian los cables, no el cuerpo). Ahora isBoardSeated (misma matematica del snap, umbral 0.5px) decide: posada -> z3 encima de su zocalo, como el XIAO fisico apilado en el shield; libre -> z0 debajo de los componentes, como siempre. El iman coloca la placa exactamente en el asiento, asi que al capturarla salta al frente y al arrancarla vuelve abajo. --- .../components/simulator/BoardOnCanvas.tsx | 25 ++++++++++++++----- frontend/src/utils/socketSnap.ts | 19 ++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/simulator/BoardOnCanvas.tsx b/frontend/src/components/simulator/BoardOnCanvas.tsx index 75841ec6..42954e97 100644 --- a/frontend/src/components/simulator/BoardOnCanvas.tsx +++ b/frontend/src/components/simulator/BoardOnCanvas.tsx @@ -1,4 +1,6 @@ import React from 'react'; +import { useSimulatorStore } from '../../store/useSimulatorStore'; +import { isBoardSeated } from '../../utils/socketSnap'; import { getProBoard } from '../../lib/proBoardRegistry'; import type { BoardInstance } from '../../types/board'; import { ArduinoUno } from '../velxio-components/ArduinoUno'; @@ -103,6 +105,14 @@ export const BoardOnCanvas = ({ }: BoardOnCanvasProps) => { const { id, boardKind, x, y } = board; const size = BOARD_SIZE[boardKind] ?? getProBoard(boardKind)?.size ?? { w: 300, h: 200 }; + // Seated on a socket component (Round Display back header)? Decides the + // stacking below. Recomputed on every position change; the check is a few + // pad lookups over the component list, cheap at render rate. + const components = useSimulatorStore((st) => st.components); + const seated = React.useMemo( + () => isBoardSeated(id, boardKind, x, y, components), + [id, boardKind, x, y, components], + ); // Status dot color: green=running, amber=compiled, gray=idle const statusColor = board.running ? '#22c55e' : board.compiledProgram ? '#f59e0b' : '#6b7280'; @@ -184,12 +194,15 @@ export const BoardOnCanvas = ({ // sibling of PinOverlay) made moving onto a pin fire mouseleave, which // cleared the hover and hid the pins before you could click one.
diff --git a/frontend/src/utils/socketSnap.ts b/frontend/src/utils/socketSnap.ts index fed4f47e..a2ae90f9 100644 --- a/frontend/src/utils/socketSnap.ts +++ b/frontend/src/utils/socketSnap.ts @@ -93,3 +93,22 @@ export function snapBoardToSocket( } return best ? { x: tentativeX + best.dx, y: tentativeY + best.dy } : null; } + +/** + * True when the board's CURRENT position IS a socket seat (within half a + * pixel). This is the z-order question, not the drag question: a seated + * board must paint above its socket component, an unseated one must stay + * below components like every other board — the blanket zIndex bump that + * preceded this check hid a resistor behind an Arduino in every ordinary + * example. + */ +export function isBoardSeated( + boardId: string, + boardKind: string, + x: number, + y: number, + components: ComponentLike[], +): boolean { + const seat = snapBoardToSocket(boardId, boardKind, x, y, components); + return !!seat && Math.hypot(seat.x - x, seat.y - y) < 0.5; +}