Voltar à vitrine ↖

PROJETO 003 / HERO INTERATIVA

PIPOCA
& CIA.

Um filhote, um clipe de 10 segundos e um cursor para seguir.

Do vídeo aos 240 frames em grade: como o personagem passou a olhar para o mouse sem nenhuma pose inventada, e por que a primeira versão mostrava frames sobrepostos.

Entrar no site ↗

Pipoca & Cia é uma marca fictícia criada para este estudo. Não há produtos, vendas ou cadastro.

O filhote da Pipoca & Cia segurando um biscoito no hero do site, virando a cabeça na direção do cursor CAPTURA DO SITE REAL · PRÉVIA MUDA

Um prompt curto, um vídeo e a pergunta: como fazer o olhar acompanhar?

O Jorge enviou um clipe de 10 segundos e pediu uma hero interativa em JavaScript puro. O resultado usa o vídeo original em loop no fundo; ao mover o mouse, uma sprite com todos os frames assume no mesmo instante e o filhote vira a cabeça para onde o cursor está, a partir de um mapa de olhar montado pela análise dos frames. Quando o mouse para, o vídeo retoma da pose. A página Raio-X do próprio site ensina a reproduzir tudo, do FFmpeg ao código.

240frames do clipe na sprite, nenhum geradoREADME.md · grade 60×4, 384×216

42 msentre frames vizinhos no cross-fadesrc/data/raio-x.js · Etapa 2 (antes: 167 ms)

1,07 spara assentar de uma ponta à outrasimulação a 60 fps do motor · sem overshoot

  • Olhar que segue o mouseMapa cursor → instante do clipe com keypoints em ordem cronológica; o easing atravessa poses reais do vídeo.
  • Handoff no frame exatoVídeo e sprite compartilham a linha do tempo: pausa, quantiza a 1/24 s, canvas assume; parado 900 ms, o vídeo volta do mesmo ponto.
  • Raio-X reproduzívelNove etapas com comandos FFmpeg, decisões, erros, o prompt ajustado e o código-fonte completo, dentro do próprio site.

Os dois prompts, na ordem em que foram usados.

Primeiro o vídeo nasce de uma imagem no Google Flow; depois o Claude transforma esse vídeo na hero interativa. Os textos abaixo são os que geraram este projeto, sem edição.

1. Gerar o vídeo no Google FlowAbra o Google Flow, adicione a imagem do personagem como imagem inicial e cole:
Trate a imagem enviada como uma referência rígida. Mantenha o personagem, a expressão, as proporções, a iluminação, o ângulo da câmera, o enquadramento e o fundo exatamente como mostrado. A câmera deve permanecer totalmente travada: sem zoom, pan, rotação, reenquadramento ou qualquer mudança de cena em nenhum momento. Anime apenas o personagem. Nunca adicione cursor, ponteiro, ponto, inseto, brinquedo, mão, sombra, partícula ou qualquer outro elemento novo no quadro. O personagem deve reagir como se algo estivesse flutuando ao seu redor, percorrendo 360 graus completos da sua atenção. Os olhos iniciam o movimento, e a cabeça acompanha um instante depois. As orelhas giram sutilmente, o pescoço se move de forma natural, e os bigodes apresentam um leve movimento secundário. Faça com que ele olhe para a extrema esquerda, depois para a parte inferior esquerda, depois para a parte superior esquerda, retornando suavemente pelo centro; em seguida para a extrema direita, parte inferior direita, parte superior direita, e por fim volte exatamente para a pose inicial e coma um pedaço do biscoito (isso deve parecer real). Inclua pequenas pausas antes de cada mudança de direção, um leve excesso natural de movimento (overshoot) e transições suaves com desaceleração/aceleração fluida (easing) em todos os movimentos. O corpo, os ombros, o peito, as patas e a postura sentada devem permanecer quase totalmente imóveis. Não faça alongamento, deformação facial, giros, rotações exageradas, respiração visível ou movimento de bombeamento do tronco. O primeiro e o último frame devem ser idênticos, para que o clipe possa ser reproduzido em loop de forma limpa, quadro a quadro.
2. Criar a hero com o ClaudeEnvie o vídeo gerado junto com:
Crie uma hero section interativa a partir da animação enviada. Use FFmpeg para extrair todos os frames do clipe e reuni-los em uma única sprite sheet em grade (todos os frames, na taxa original do vídeo, distribuídos em várias linhas para respeitar o limite de largura dos navegadores). Depois, crie um sistema de animação baseado em frames usando JavaScript puro (vanilla JavaScript), desenhando em canvas com cross-fade entre frames vizinhos. Coloque o vídeo original em loop no fundo. Quando o mouse se mover, pause o vídeo e faça a sprite assumir exatamente no mesmo frame, sem sobreposição; quando o mouse parar ou sair da área, o vídeo retoma a partir da pose em que o personagem ficou. Carregue o vídeo como Blob para o seek ser preciso. Faça o personagem olhar para o cursor de verdade: antes de programar, analise os frames e identifique em que instantes ele olha para a esquerda, direita, frente, cima e para o objeto que segura. Monte um mapa cursor → instante do clipe com esses pontos, e percorra a sprite com interpolação com easing (amortecimento dependente de dt, velocidade máxima limitada). Mantenha a composição original, preserve o personagem centralizado em paisagem e em retrato, e faça toda a interação transmitir uma sensação premium, fluida e responsiva. Teste no navegador antes de entregar.

Sobre o Blob: carregar o vídeo como Blob resolve o seek em servidores de desenvolvimento sem HTTP Range. Atrás de uma CSP com media-src self, como neste programa, usa-se src direto e confere-se que o servidor devolve 206.

NÃO É UM BOTÃO MÁGICO.

É UMA SEQUÊNCIA
DE DECISÕES.

O raio-X mostra inclusive o que foi reprovado. Porque saber o que corrigir também é construir.

  1. 01

    Pesquisar a marca

    Referências, linguagem e fidelidade do produto antes da ferramenta.

  2. 02

    Escrever a experiência

    Um roteiro de cenas, transições e intenção de cada momento.

  3. 03

    Dirigir a arte

    Gerar, compor, comparar e corrigir as imagens no contexto.

  4. 04

    Dar movimento às imagens

    Frames aprovados, prompts de UGC e seleção das saídas do Flow.

  5. 05

    Construir com código

    Astro, 3D, movimento de scroll e alternativas por capacidade do dispositivo.

  6. 06

    Revisar de verdade

    Rótulo, recortes, teclado, contraste, carga e comportamento.

  7. 07

    Preparar a publicação

    SEO, segurança, artefatos estáticos e entrega para integração.

RAIO-X

O resultado tem bastidores.

8 recortes de um único projeto: o clipe, a análise dos frames, a sprite em grade, o mapa de olhar, o handoff, a correção da dupla exposição, o retrato e a página Raio-X. Artefatos reais e instruções documentadas.

RAIO-X / Pipoca & Cia · hero

Um clipe de 10 segundos virou o hero.

O Jorge enviou um clipe gerado por IA (1280×720, 24 fps, 240 frames) e uma imagem de referência. Nenhuma pose foi gerada: o filhote que olha para o cursor é sempre um frame real do vídeo. Em repouso quem aparece é o vídeo original, mudo e em loop, na resolução completa; a sprite só entra quando o ponteiro se move.

Frame de repouso do clipe (t = 4,0 s)
Frame de repouso do clipe (t = 4,0 s)
Hero em produção, cursor à esquerda
Hero em produção, cursor à esquerda
Ferramenta / modelo · conforme registro
Google Flow gerou o clipe a partir da imagem (prompt abaixo); FFmpeg 7.1 (binário do pacote imageio-ffmpeg) para frames e sprite; Claude Fable 5.1 escreveu o motor em JavaScript puro (canvas, sem bibliotecas).
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · 1. Gerar o vídeo no Google Flow
Trate a imagem enviada como uma referência rígida. Mantenha o personagem, a expressão, as proporções, a iluminação, o ângulo da câmera, o enquadramento e o fundo exatamente como mostrado. A câmera deve permanecer totalmente travada: sem zoom, pan, rotação, reenquadramento ou qualquer mudança de cena em nenhum momento. Anime apenas o personagem. Nunca adicione cursor, ponteiro, ponto, inseto, brinquedo, mão, sombra, partícula ou qualquer outro elemento novo no quadro. O personagem deve reagir como se algo estivesse flutuando ao seu redor, percorrendo 360 graus completos da sua atenção. Os olhos iniciam o movimento, e a cabeça acompanha um instante depois. As orelhas giram sutilmente, o pescoço se move de forma natural, e os bigodes apresentam um leve movimento secundário. Faça com que ele olhe para a extrema esquerda, depois para a parte inferior esquerda, depois para a parte superior esquerda, retornando suavemente pelo centro; em seguida para a extrema direita, parte inferior direita, parte superior direita, e por fim volte exatamente para a pose inicial e coma um pedaço do biscoito (isso deve parecer real). Inclua pequenas pausas antes de cada mudança de direção, um leve excesso natural de movimento (overshoot) e transições suaves com desaceleração/aceleração fluida (easing) em todos os movimentos. O corpo, os ombros, o peito, as patas e a postura sentada devem permanecer quase totalmente imóveis. Não faça alongamento, deformação facial, giros, rotações exageradas, respiração visível ou movimento de bombeamento do tronco. O primeiro e o último frame devem ser idênticos, para que o clipe possa ser reproduzido em loop de forma limpa, quadro a quadro.

Documento de origem: E:\Dogs\PROMPT.md · 1. Gerar o vídeo no Google Flow

Entrada: Character_tracking_and_eating_co….mp4
Saída: public/media/puppy-loop.mp4

RAIO-X / Pipoca & Cia · análise

Primeiro olhar, depois código.

Um mapeamento linear do mouse para a linha do tempo faria o personagem passar por todas as poses em qualquer ordem. Antes de programar, grades de contato (1 miniatura a cada 0,6 s e a cada 0,33 s) e recortes de frames-chave registraram os instantes: esquerda em 1,0–2,3 s, frente em 4,0 s, direita em 5,0–5,7 s, olhar para cima em 6,0–6,7 s, mordida em 8,0–8,6 s.

Grade de contato: 16 miniaturas, uma a cada 0,6 s
Grade de contato: 16 miniaturas, uma a cada 0,6 s
Frames-chave com o instante anotado
Frames-chave com o instante anotado
Ferramenta / modelo · conforme registro
FFmpeg (filtros fps + tile) e Pillow para os recortes anotados; leitura visual pelo Claude.
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · Etapa 3 — Analisar os frames antes de programar
ffmpeg -i clipe.mp4 -vf "fps=3,scale=400:-1,tile=6x5" -frames:v 1 grade-densa.jpg — depois recortar os frames 1, 25, 41, 57, 73, 97, 121, 137, 145, 161, 201 e 217 com o instante anotado.

Documento de origem: E:\Dogs\src\data\raio-x.js · Etapa 3 — Analisar os frames antes de programar

Entrada: frames/frame_001.jpg … frame_240.jpg
Saída: public/raio-x/frames-chave.webp

RAIO-X / Pipoca & Cia · sprite

Todos os 240 frames, em grade.

Navegadores não decodificam imagens com mais de cerca de 32.767 px de largura. Os 240 frames numa linha só caberiam com 136 px cada. A sprite final é uma grade de 60 colunas por 4 linhas (23.040×864 px, ~20 MP, 2,8 MB em JPEG), gerada com o filtro tile do FFmpeg. O frame i fica na coluna i mod 60 e na linha ⌊i / 60⌋.

Versão anterior: 60 frames a 6 fps, com dupla exposição
Versão anterior: 60 frames a 6 fps, com dupla exposição
Recorte das 6 primeiras colunas da grade final
Recorte das 6 primeiras colunas da grade final
Ferramenta / modelo · conforme registro
FFmpeg 7.1: scale=384:216:flags=lanczos,tile=60x4.
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · Como a sprite sheet foi gerada
ffmpeg -i clipe.mp4 -vf "scale=384:216:flags=lanczos,tile=60x4" -frames:v 1 -qscale:v 3 puppy-sprite.jpg

Documento de origem: E:\Dogs\README.md · Como a sprite sheet foi gerada

Entrada: frames/
Saída: public/media/puppy-sprite.jpg

RAIO-X / Pipoca & Cia · olhar

O cursor vira um instante do clipe.

O eixo horizontal do cursor é convertido em tempo do clipe por keypoints interpolados com smoothstep: 1,05 s na borda esquerda, 4,0 s no centro, 5,7 s na borda direita. Como a sequência está em ordem cronológica no vídeo, quando o alvo muda de uma ponta à outra o motor atravessa poses intermediárias reais e a transição parece movimento, não corte. Faixa superior da tela leva ao olhar para cima; a região do biscoito, à mordida.

Cursor na borda esquerda (t ≈ 1,1 s)
Cursor na borda esquerda (t ≈ 1,1 s)
Cursor na borda direita (t ≈ 5,7 s)
Cursor na borda direita (t ≈ 5,7 s)
Ferramenta / modelo · conforme registro
JavaScript puro: gazeTime(x, y), amortecimento exponencial dependente de dt (rate 9/s) e velocidade máxima de 6 s de clipe por segundo.
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · 2. Criar a hero com o Claude
Crie uma hero section interativa a partir da animação enviada. Use FFmpeg para extrair todos os frames do clipe e reuni-los em uma única sprite sheet em grade (todos os frames, na taxa original do vídeo, distribuídos em várias linhas para respeitar o limite de largura dos navegadores). Depois, crie um sistema de animação baseado em frames usando JavaScript puro (vanilla JavaScript), desenhando em canvas com cross-fade entre frames vizinhos. Coloque o vídeo original em loop no fundo. Quando o mouse se mover, pause o vídeo e faça a sprite assumir exatamente no mesmo frame, sem sobreposição; quando o mouse parar ou sair da área, o vídeo retoma a partir da pose em que o personagem ficou. Carregue o vídeo como Blob para o seek ser preciso. Faça o personagem olhar para o cursor de verdade: antes de programar, analise os frames e identifique em que instantes ele olha para a esquerda, direita, frente, cima e para o objeto que segura. Monte um mapa cursor → instante do clipe com esses pontos, e percorra a sprite com interpolação com easing (amortecimento dependente de dt, velocidade máxima limitada). Mantenha a composição original, preserve o personagem centralizado em paisagem e em retrato, e faça toda a interação transmitir uma sensação premium, fluida e responsiva. Teste no navegador antes de entregar.

Documento de origem: E:\Dogs\PROMPT.md · 2. Criar a hero com o Claude

Entrada: src/sprite-hero.js
Saída: .qa/pipoca-follow-right.png

RAIO-X / Pipoca & Cia · handoff

Vídeo e sprite, mesma linha do tempo.

Sprite e vídeo compartilham os mesmos 10 segundos. Ao mover o mouse, o vídeo pausa, o tempo é quantizado ao frame (round(t × 24) / 24), o canvas desenha esse frame e aparece em 70 ms já mostrando a mesma imagem. Parado 900 ms ou fora da área, o vídeo recebe currentTime igual ao tempo da sprite, espera o seeked e volta a tocar; o canvas some em 220 ms. Em desenvolvimento o seek caía em 0 porque o servidor Python não responde a HTTP Range; em produção o nginx devolve 206.

Repouso: o vídeo em loop
Repouso: o vídeo em loop
Cursor sobre o biscoito: a sprite na mordida
Cursor sobre o biscoito: a sprite na mordida
Ferramenta / modelo · conforme registro
Máquina de estados video → follow → resume → video em JavaScript puro; simulação em Node confirmou assentamento em 1,07 s de ponta a ponta sem overshoot.
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · Etapa 5 — Vídeo em loop e a troca sem emenda
Quando o ponteiro se move: pause o vídeo, quantize o currentTime ao frame exato, desenhe esse frame no canvas e mostre o canvas em ~70 ms; só então o alvo passa a seguir o cursor. Parado por ~900 ms: currentTime = tempo da sprite, seeked, play(), fade do canvas.

Documento de origem: E:\Dogs\src\data\raio-x.js · Etapa 5 — Vídeo em loop e a troca sem emenda

Entrada: src/sprite-hero.js
Saída: public/media/puppy-loop.mp4

RAIO-X / Pipoca & Cia · correção

Frames sobrepostos tinham causa: 6 fps.

A primeira sprite tinha 1 frame a cada 4 (60 frames, tira única de 30.720 px). O cross-fade entre vizinhos a 167 ms de distância virava dupla exposição nas viradas de cabeça, e no início do handoff a sprite já se movia enquanto o canvas aparecia sobre o vídeo parado. A correção: todos os 240 frames em grade (vizinhos a 42 ms) e alvo travado no frame exato do vídeo durante a entrada do canvas.

Cross-fade a 6 fps: frames 121 + 125 a 50%
Cross-fade a 6 fps: frames 121 + 125 a 50%
Cross-fade a 24 fps: frames 121 + 122 a 50%
Cross-fade a 24 fps: frames 121 + 122 a 50%
Ferramenta / modelo · conforme registro
Reconstrução do defeito com Pillow: mistura a 50% dos frames 121 e 125 (6 fps) contra 121 e 122 (24 fps).
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · "deixa a transição sprite/vídeo mais suave"
Deixa a transição sprite/vídeo mais suave: quando eu movo o mouse eu vejo ainda frames sobrepostos.

Documento de origem: Conversa de produção, 16/09/2026 · "deixa a transição sprite/vídeo mais suave"

Entrada: frames/frame_121.jpg + frame_125.jpg
Saída: frames/frame_121.jpg + frame_122.jpg

RAIO-X / Pipoca & Cia · retrato

Em retrato, o eixo x muda de régua.

O corte cover em retrato deixava o filhote gigante e cortado. A composição ficou ancorada no topo com 66% da altura e o texto desceu para o fundo escuro. Como só o centro do quadro 16:9 aparece, as poses laterais ficavam inalcançáveis: o eixo x do cursor passou a cobrir a largura visível, e não a largura da composição.

Quadro 16:9 original
Quadro 16:9 original
Retrato em produção (720×1300), cabeça virada à direita
Retrato em produção (720×1300), cabeça virada à direita
Ferramenta / modelo · conforme registro
layout() e toComposition() em src/sprite-hero.js; o <video> é posicionado por JavaScript no mesmo retângulo do canvas.
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · Etapa 6 — Composição, retrato e o que fica em volta
const x = portrait ? px / w : (px - dest.x) / dest.w;

Documento de origem: E:\Dogs\src\data\raio-x.js · Etapa 6 — Composição, retrato e o que fica em volta

Entrada: src/sprite-hero.js
Saída: .qa/pipoca-mobile-follow.png

RAIO-X / Pipoca & Cia · raio-x

O passo a passo é parte do site.

O pedido do Jorge foi que quem acessar o raio-X consiga reproduzir o mesmo resultado. A página /pipoca-cia/raio-x/ tem nove etapas: entrada, FFmpeg, análise, motor, handoff, layout, QA, o prompt ajustado e o arquivo sprite-hero.js inteiro. Todo o texto vive em src/data/ e é renderizado em HTML estático no build, sem script inline.

Abertura da página Raio-X
Abertura da página Raio-X
Etapa 2: a grade de olhares e a tabela de instantes
Etapa 2: a grade de olhares e a tabela de instantes
Ferramenta / modelo · conforme registro
Vite + plugin de conteúdo próprio (scripts/content-plugin.mjs); botões "Copiar" progressivos.
Tempo de produção
Não documentado. Não estimado.
Prompt ou instrução real · raioX.steps
Detalhe passo a passo para quem acessar o raio-X do projeto consiga reproduzir o mesmo resultado.

Documento de origem: E:\Dogs\src\data\raio-x.js · raioX.steps

Entrada: src/data/raio-x.js
Saída: dist/raio-x/index.html

O PRÓXIMO PROJETO PODE SER O SEU.

DE “COMO FIZERAM?”
PARA “EU FIZ”.

Aprenda a conectar direção de arte, IA e código. Comece pelo processo, não pela lista de ferramentas.

Quero aprender a fazer isso