MÓDULO 1.2

🧠 Capturar antes, animar depois

O princípio que rege toda a skill. Como o render do HyperFrames é determinístico (sem rede), nunca se carrega o site ao vivo no vídeo: captura-se a tela real antes e anima-se por cima. O viewport fixo da captura vira o espaço de coordenadas do cursor.

6
Tópicos
~30
Minutos
Básico
Nível
Conceito
Tipo
CAPTURAR → MEDIR → ANIMAR ① CAPTURA screenshot real viewport 1280×800 ② BOUNDING BOX x,y,w,h getBounding... viewport-relative ③ CURSOR alvo mira a box · clica ⚙️ Render determinístico — sem rede no render o mesmo viewport e scroll garantem a consistência shot ↔ coordenada
1

⚙️ Render determinístico

O HyperFrames renderiza o HTML em frames de forma determinística: dado o mesmo HTML e a mesma timeline, o vídeo sai idêntico. Para isso, não há acesso à rede durante a renderização.

Conceito Principal

Determinístico significa: o render não depende de nada que possa variar — não faz fetch, não carrega imagens remotas, não consulta APIs no meio do caminho. Cada frame é função pura do HTML + tempo.

É exatamente isso que garante que o vídeo seja reproduzível e que a animação bata com o áudio frame a frame.

⚠️
Rede no render = inconsistência

Se um frame dependesse de uma requisição, o resultado mudaria conforme a latência, o estado do servidor ou os dados do momento. O render perderia a previsibilidade — e a sincronia com a narração quebraria.

Conceitos-chave
🔁
Reproduzível
Mesmo resultado
🚫
Sem rede
Nenhum fetch
🎞️
Frame a frame
Tempo controlado
🔗
Áudio batido
Sincronia exata
2

🚫 Nunca o site ao vivo

Como consequência direta do render determinístico, o app jamais é carregado ao vivo dentro do vídeo. Nada de iframe apontando para a URL real durante a renderização.

✓ O jeito certo
  • Screenshots reais salvos em assets/shots/
  • Imagens locais referenciadas no HTML do vídeo
  • Tudo embutido antes do render começar
  • Animação por cima da imagem estática
✗ O que não fazer
  • <iframe src="https://app…"> no vídeo
  • Carregar imagens via URL remota no render
  • Esperar o app responder durante a renderização
  • Depender de fontes via CDN (use as locais)
💡
A moldura disfarça que é print

O screenshot estático entra dentro de uma moldura de navegador (barra + URL) e ganha cursor + zoom por cima. Para quem assiste, parece uma gravação de tela ao vivo — mas é imagem mais animação.

3

📸 Captura-se screenshots reais ANTES

A etapa que faz toda a diferença acontece antes do render: navega-se o app de verdade com o agent-browser e tira-se um screenshot por estado da jornada.

A ordem do pipeline
1
Abrir o app num viewport fixo

agent-browser set viewport 1280 800 e abrir a URL. O viewport é definido uma vez e mantido.

2
Executar a ação do passo

Preencher um campo, clicar num botão, esperar um resultado — a ação que aquele passo demonstra.

3
Tirar 1 screenshot por estado

Cada estado vira um assets/shots/NN-id.png — a base visual daquele passo.

4
Pegar a bounding box do alvo

Junto do shot, mede-se a caixa real do elemento que o cursor vai mirar. Tudo isso vira steps.json.

💡
Dois caminhos para capturar

Automatizado (capture.mjs + actions.json) para apps previsíveis, ou manual dirigindo o agent-browser passo a passo quando há login ou estados dinâmicos. Os detalhes ficam na Trilha 2: Captura.

4

🖼️ O viewport fixo vira o espaço de coordenadas

Este é o conceito mais importante do módulo: o viewport usado na captura define o sistema de coordenadas em que tudo é posicionado depois. Por isso ele é sagrado.

Conceito Principal

Se a captura foi feita num viewport de 1280×800, então o screenshot tem 1280×800 e qualquer coordenada (x, y) refere-se a esse espaço. O cursor, o zoom e a moldura trabalham todos nesse mesmo sistema.

A regra do viewport fixo
# o MESMO viewport para shot e para a box
viewport = 1280 × 800 # definido uma vez
screenshot1280 × 800 px # mesmo tamanho
box.x, box.yrelativos a 1280 × 800

# largura ≤ ~1280 para caber no 16:9
⚠️
Mudar o viewport quebra o alinhamento

Se o screenshot sai de um viewport e a bounding box de outro, as coordenadas não batem: o cursor cai no lugar errado. Por isso o viewport tem que ser idêntico em toda a captura.

5

📦 Bounding boxes viewport-relative

A posição de cada elemento-alvo não é estimada "no olho": vem de getBoundingClientRect, que devolve coordenadas reais relativas ao viewport.

Medindo a caixa real do alvo
# eval no agent-browser pega a box do elemento
const r = el.getBoundingClientRect();
return {
x: Math.round(r.x),
y: Math.round(r.y),
w: Math.round(r.width),
h: Math.round(r.height)
}; # coordenadas no espaço do screenshot
✓ Por que box real importa
  • O cursor cai no centro exato do controle
  • Funciona mesmo se o layout for responsivo
  • O destaque/zoom enquadra o elemento certo
  • É o que dá o ar profissional ao vídeo
✗ Estimar "no olho" falha
  • Coordenadas chutadas erram o controle
  • Quebram a qualquer mudança de layout
  • Não acompanham scroll ou tamanho do elemento
  • Dão aquele aspecto amador de "quase lá"
6

🖱️ O cursor mira as boxes — consistência shot↔coordenada

Com os screenshots e as caixas em mãos, o cursor anima na timeline principal mirando o centro de cada bounding box. O segredo de acertar é a consistência: mesmo viewport, mesmo scroll.

Conceito Principal

O cursor é global (animado na timeline principal, não por cena), com o hotspot na ponta. A ponta desliza até o centro da box do alvo e, no clique, dispara pulse + ripple. Como a box e o shot vêm do mesmo viewport e scroll, a ponta cai exatamente sobre o que aparece na tela.

Conceitos-chave
🌐
Cursor global
Timeline principal
📍
Hotspot na ponta
Cai no centro
💥
Pulse + ripple
No clique
🎯
Mesmo scroll
Box bate com shot
💡
Consistência shot↔coordenada é a regra de ouro

Sempre que o screenshot daquele passo e a bounding box do alvo saírem do mesmo viewport e do mesmo scroll, o cursor estará alinhado. Quebrar essa consistência é a causa nº1 de cursor "fora do lugar".

📋 Resumo do Módulo 1.2

O que você aprendeu
  • O render do HyperFrames é determinístico — sem rede
  • Por isso nunca se carrega o site ao vivo no vídeo
  • Captura-se screenshots reais ANTES, 1 por estado
  • O viewport fixo vira o espaço de coordenadas
  • Bounding boxes vêm de getBoundingClientRect (viewport-relative)
  • O cursor mira as boxes; consistência shot↔coordenada é a regra
Próximo módulo
1.3
🧰 A stack sem API key
As três peças locais que executam o princípio: agent-browser para capturar, HyperFrames para renderizar e Kokoro TTS para narrar — tudo na máquina.
Ir para o módulo 1.3 →