📍 Coordenadas relativas al viewport
Las bboxes son relativas al viewport. En el video, se convierten en coordenadas del canvas al sumar el offset de la ventana.
La captura se ejecuta en un viewport fijo (p. ej., 1280×800). Todas las bbox vienen de ese espacio. En el canvas 1920×1080, la captura de pantalla se dibuja dentro de la ventana y cada punto se mapea.
📐 Capturar la bbox de cada objetivo
Para cada paso con target, capture.mjs lee el rect y redondea a {x,y,w,h}.
Si el selector no coincide, capture graba target: null e imprime ! alvo não encontrado no passo X. Es la señal clara de que el selector es incorrecto — corrígelo antes de renderizar.
🧷 Selectores robustos
data-testid, role y el texto visible sobreviven al cambio de estado. Los refs @eN no.
- ✓
[data-testid="gerar"] - ✓
role+ nombre accesible - ✓ Texto visible:
{tag:"button",text:"Gerar"} - ✓ Atributos:
input[name=height]
- ✗ Refs
@eNen pantallas que cambian - ✗ Clases generadas (CSS-in-JS) que cambian en el build
- ✗ nth-child posicional en un layout dinámico
- ✗ El texto con acentos y espacios no coincide exactamente
En el POC, cuando apareció el enlace "descargar PNG", todas las refs se desplazaron. Por eso, en un estado mutable, usa CSS selectors o {tag,text} — y vuelve a tomar una captura cuando el DOM cambie mucho.
🎯 El cursor apunta al centro del cuadro
El cursor es un SVG global con el hotspot en la punta. El tween compensa el offset para que la punta caiga en el centro.
Un único #cursor animado en la timeline principal — se desliza continuamente mientras cambian las capturas de pantalla.
La punta queda en ~(6,3) dentro del SVG de 42px. El tween usa x = alvoX - 6, y = alvoY - 3.
scale:.82 yoyo + um #ripple ámbar que se expande sobre el objetivo en el instante del clic.
El movimiento usa duration:.7, ease:"power3.inOut", comenzando ~0,35s después de que aparece la escena. El cursor llega al target antes de la explicación principal.
🔍 Región de zoom / resaltado
La misma bbox posiciona el anillo de resaltado y el acercamiento del zoom. Una coordenada correcta sirve para los tres efectos.
transformOrigin en el centro del objetivo.O .hlbox es solo box-shadow (anillo + glow): aparece con back.out y pulsa, dirigiendo la mirada al control activo sin tapar nada.
📜 Gestionar un objetivo fuera de la pantalla
Si el objetivo está debajo del pliegue, desplázate hasta él antes de capturar y medir; haz ambas cosas después del mismo desplazamiento.
capture.mjs actualmente no desplaza la página. En pantallas largas, controla agent-browser manualmente (scrollIntoView) antes de la captura de pantalla. Agregar scroll/scrollTo es el elemento nº 1 del backlog.
Como la bbox se mide en el viewport actual, coincide con el screenshot de ese scroll, siempre que la captura y la medición se hagan después de lo mismo scrollIntoView.
✅ Comprobar que se capturó el elemento correcto
Compara la bbox con el screenshot antes de renderizar. capture imprime cada bbox en el log para una verificación rápida.
- ✓ El bbox cae sobre el control visible en el shot
- ✓ Ningún aviso de "objetivo no encontrado"
- ✓ w/h plausibles (ni 0×0 ni toda la pantalla)
- ✗ target=— donde debería haber un bbox
- ✗ El bbox queda sobre el elemento equivocado
- ✗ Coordenadas fuera de los límites de la captura
🎯 Resumen del módulo
- ✓ bbox relativo al viewport → canvasX = WIN_L + sx, canvasY = SHOT_T + sy
- ✓ capture lee getBoundingClientRect; objetivo sin match = bbox null + aviso
- ✓ prefiere data-testid / role / texto visible a refs @eN
- ✓ cursor global con hotspot en la punta; clic = pulse + ripple
- ✓ el mismo bbox sirve para el cursor, el resaltado y el zoom; revísalo en el registro antes de renderizar