Site de Rolagem com Vídeo (Scroll Video Website)
Quando usar
Use esta skill quando o usuário desejar:
- criar uma animação de rolagem no estilo Apple a partir de um vídeo;
- construir um site de rolagem controlada ou avanço por rolagem de um vídeo;
- transformar um vídeo de produto em uma landing page cinematográfica;
- criar uma experiência de narrativa visual (scrollytelling) orientada por vídeo;
- converter um vídeo em uma sequência otimizada de imagens para animação por rolagem;
- criar uma revelação de produto baseada em Canvas controlada por rolagem;
- otimizar uma sequência de quadros de vídeo de rolagem já gerada.
Não use isso para backgrounds de vídeo com reprodução automática comuns ou efeitos de rolagem não relacionados.
Crie uma experiência minimalista de página inteira, como um visualizador de animação de produto: a própria página fornece a distância de rolagen enquanto um canvas fixo preenche a viewport e avança por uma sequência de quadros derivada do vídeo do usuário. A animação é a interface, não um fundo atrás de uma landing page convencional.
Invocação
Esta skill tem dois modos: construir um site de rolagem com vídeo a partir de um vídeo, ou otimizar uma sequência de quadros existente. Se o primeiro argumento for optimize, siga references/optimize.md e não execute o fluxo de construção abaixo.
Trate este formato conciso como uma solicitação de construção completa:
$scroll-video-website <caminho/para/video.mp4>
O caminho do vídeo deve ser o primeiro argumento após o nome da skill. Tudo após o caminho é direção opcional do usuário para estilo, layout, texto ou comportamento:
$scroll-video-website ./media/revelacao-produto.mp4
$scroll-video-website ./media/revelacao-produto.mp4 use fundo preto e tipografia condensada
O primeiro exemplo significa: derivar a sequência de quadros e construir o site de animação de rolagem padrão completo descrito abaixo. No segundo, preserve a mesma arquitetura de animação orientada por vídeo enquanto segue a direção visual adicionada. Deixe o agente que usa esta skill interpretar e implementar o restante do prompt; esta skill não define uma gramática de comando separada para opções de estilo.
Interprete o caminho do vídeo como relativo ao diretório de trabalho atual, a menos que seja absoluto. Se contiver espaços, o usuário deve colocá-lo entre aspas. Verifique o caminho exato primeiro. Se um nome de arquivo simples não estiver lá, pesquise no projeto atual por uma correspondência exata de nome de arquivo, excluindo diretórios de dependência, construção, cache e VCS. Continue automaticamente quando houver exatamente uma correspondência. Se não houver correspondências ou houver múltiplas correspondências, peça ao usuário o caminho preciso. Chaves em <caminho/para/video.mp4> ou {caminho_do_video} indicam um placeholder e não fazem parte do caminho real. Não exija ou interprete uma palavra-chave use.
Otimize uma sequência existente exatamente com:
$scroll-video-website optimize
O comando optimize não aceita caminho ou outros argumentos. Inspecione o projeto atual em busca de sequências de quadros geradas. Continue quando exatamente uma sequência for identificável. Se várias forem identificáveis, mostre-as e pergunte qual otimizar. Se nenhuma sequência puder ser encontrada ou reconhecida com confiança, informe ao usuário que a pasta de quadros não foi encontrada e pare.
Estabeleça o projeto e o vídeo de origem
Antes de editar:
- Inspecione a estrutura do projeto, scripts, framework, estilo, roteamento, convenções de assets e instruções locais.
- Localize o vídeo fornecido pelo usuário usando as regras de invocação acima. Se nenhum vídeo ou caminho foi fornecido e nenhum pode ser identificado com confiança, peça-o antes de implementar.
- Reutilize a stack de trabalho existente. Não crie um projeto substituto quando um já funciona.
- Inspecione as dimensões, duração, taxa de quadros, contagem de quadros e tamanho do arquivo do vídeo com
ffprobequando disponível. - Preserve o comportamento não relacionado e faça o menor conjunto coerente de alterações necessário.
Não crie arte substituta ou substitua a filmagem fornecida. Evite duplicar o vídeo de origem, a menos que a construção exija.
Converta o vídeo em uma sequência de quadros
O caminho de renderização padrão é uma sequência de quadros WebP numerados, não video.currentTime. Extraia quadros para a área de assets públicos/estáticos do projeto com nomes com zero à esquerda, como frames/frame_0001.webp.
- Preserve a cadência de origem até 30 fps. Para um clipe longo, amostre-o para aproximadamente 240–300 quadros no total para que o payload permaneça prático.
- Preserve a proporção de aspecto da origem. Use uma qualidade WebP sensata em torno de 78–82 e inspecione o resultado em vez de assumir que a configuração é adequada.
- Registre a contagem real de quadros extraídos na implementação; não deixe uma constante adivinhada.
- Prefira
ffmpegpara extração. Um comando representativo éffmpeg -i input.mp4 -vf fps=30 -c:v libwebp -quality 80 frames/frame_%04d.webp; adapte a entrada, fps, caminho de saída e ferramentas de projeto existentes. - Não exclua ou substitua assets não relacionados. Se o destino já contiver uma sequência, verifique se ela pertence a esta animação antes de substituí-la.
Use a busca direta de vídeo pausado apenas quando a extração de quadros não estiver disponível ou o payload de quadros resultante for claramente inadequado. Se recorrer a esta alternativa, explique a compensação e mantenha o mesmo comportamento de rolagem de estágio fixo, bidirecional e suavizado.
Corresponda à experiência de referência
Quando o usuário não fornecer nenhuma direção adicional de layout ou texto, produza uma página apenas com canvas:
- uma página branca e um estágio fixo com overflow oculto cobrindo
100vwpor100vh; - altura de documento invisível suficiente para uma rolagem deliberada, aproximadamente
400vhpara uma origem de 8 segundos ou aproximadamente 240 quadros; - sem barra de navegação, cartões, cabeçalhos, chamadas para ação, gradientes ou texto de marketing inventado;
- um canvas que preenche o estágio e desenha cada quadro com geometria
cover, centralizado em ambos os eixos; - uma breve revelação de opacidade apenas após o primeiro quadro estar pronto, evitando um flash de quadro em branco;
- tratamento de imagem contido apenas quando adequado à filmagem, como um fundo branco, um ajuste sutil de contraste ou
mix-blend-mode: multiplypara um render de produto com fundo branco.
Se o usuário solicitar conteúdo, mantenha-o esparso e coloque-o sobre ou entre momentos intencionais na animação sem reduzir a dominância visual do canvas. Não introduza uma dependência de animação quando APIs nativas de canvas e navegador forem suficientes.
Implemente o avanço por canvas (canvas scrubbing)
Use um estágio fixo ou sticky contendo um canvas com aria-hidden. Dimensione seu buffer de fundo para a proporção de pixels do dispositivo (device pixel ratio), limitado a aproximadamente 2, mantendo as medidas de desenho em pixels CSS. Redefina a transformação do canvas antes de aplicar uma nova escala DPR ao redimensionar para que o dimensionamento não se acumule.
Mapeie o progresso total da página (com clamp) para a sequência completa de quadros:
const range = document.documentElement.scrollHeight - innerHeight
const progress = range > 0 ? Math.min(1, Math.max(0, scrollY / range)) : 0
targetFrame = progress * (frameCount - 1)
Rolar para frente deve avançar a animação e rolar para trás deve retrocedê-la. Handlers de rolagem e redimensionamento devem apenas atualizar medições baratas ou o alvo. Execute um único loop requestAnimationFrame e suavize um playhead de ponto flutuante com interpolação exponencial independente da taxa de quadros:
const dt = Math.min((now - lastTime) / 1000, 0.1)
const alpha = 1 - Math.exp(-dt * 9)
currentFrame += (targetFrame - currentFrame) * alpha
Desenhe o quadro inteiro em cada lado do playhead e faça crossfade do próximo quadro pelo resto fracionário. Primeiro limpe ou pinte o fundo do canvas, redefina globalAlpha após desenhar e redesenhe ao redimensionar.
Carregue quadros progressivamente
Não bloqueie a primeira pintura em toda a sequência:
- Carregue o quadro 1 primeiro, desenhe-o e revele o canvas.
- Enfileire quadros distribuídos uniformemente ao longo da linha do tempo, por exemplo, a cada oito quadros, para que a busca tenha um fallback próximo no início.
- Enfileire cada quadro restante.
Rastreie quadros solicitados separadamente de quadros carregados para que as passagens de prioridade e restante nunca solicitem a mesma imagem duas vezes. Enquanto um quadro solicitado ainda estiver carregando, desenhe o quadro carregado mais próximo. Trate falhas de carregamento de imagem sem travar o resto da sequência.
Use uma estratégia de URL de asset que funcione com o caminho base e alvo de implantação do projeto. Limpe os listeners de scroll, redimensionamento, media-query, observadores e quadros de animação quando o componente proprietário for desmontado.
Comportamento responsivo e acessibilidade
Mantenha a renderização cover em telas estreitas e aceite crop deliberado; não distorça as imagens. Verifique o posicionamento importante do assunto nos tamanhos desktop e mobile. Considere as mudanças de viewport móvel e áreas seguras se conteúdo visível for adicionado.
Para prefers-reduced-motion: reduce, pare o avanço e mantenha o primeiro quadro adequado. Mantenha qualquer conteúdo da página acessível e não sequestre a rolagem. O canvas decorativo não deve criar conteúdo redundante para leitores de tela.
Verifique o resultado
Execute as verificações do projeto e inspecione o resultado em um navegador quando disponível. Confirme:
- as primeiras e últimas posições de rolagem alcançam os primeiros e últimos quadros extraídos;
- rolagem para frente e para trás parece contínua, sem saltos abruptos, reprodução, piscadas ou canvas em branco visível;
- solicitações de quadro não são duplicadas e quadros ausentes ou lentos usam um fallback carregado próximo;
- o crop cover, redimensionamento DPR e dimensionamento do canvas funcionam nos tamanhos desktop e mobile;
- movimento reduzido mantém um quadro estático e a limpeza do componente está completa;
- a sequência gerada tem a contagem, dimensões, ordenação e tamanho total aceitável esperados;
- o comportamento não relacionado do projeto ainda funciona.
Finalize resumindo a experiência, a contagem de quadros extraídos e payload, verificações executadas e qualquer limitação restante da mídia de origem.