Secções de vídeo guiadas pelo scroll, sem estragar o desempenho
Como construir uma secção fixada de vídeo e galeria ligada ao scroll que parece cinematográfica mas continua rápida no telemóvel: um único valor de progresso, um único vídeo a reproduzir, sem bibliotecas.
3 min de leituraGryffin Forge
Os sites premium adoram uma secção fixada em que o vídeo se abre com o scroll e as legendas mudam capítulo a capítulo. É também uma das formas mais fáceis de tornar uma página aos solavancos, pesada e gastadora de bateria. Eis como é construída a secção de apresentação da biblioteca de demos para continuar rápida.
Um único valor de progresso controla tudo
A secção é um contentor alto com um palco fixo lá dentro. No scroll, o script calcula um único número — quanto do contentor o visitante já percorreu, de 0 a 1 — e tudo o resto deriva dele:
- a margem do clip-path que abre o vídeo emoldurado a toda a largura,
- uma escala discreta do vídeo ativo,
- que capítulo (clip e legenda) está ativo,
- a largura da barra de progresso,
- o desvanecimento e o deslocamento do título.
Os valores são escritos como propriedades CSS personalizadas e o CSS faz o resto. Não há cronologias de animação por elemento para sincronizar nem nenhuma biblioteca para descarregar.
const p = clamp(-rect.top / (rect.height - innerHeight));
stage.style.setProperty('--p', p);
Leituras e escritas num só frame
Os eventos de scroll chegam mais vezes do que o ecrã se atualiza. O handler apenas agenda o trabalho com requestAnimationFrame, e cada frame lê primeiro o layout e depois escreve os estilos. Misturar leituras e escritas força recálculos repetidos — a causa mais comum de um scroll aos solavancos.
Só um vídeo a reproduzir
Três vídeos a arrancar automaticamente ao mesmo tempo aquecem o telemóvel e gastam dados. As regras:
- O primeiro clip carrega de imediato, para a secção nunca ficar vazia.
- Os outros começam com
preload="none". - Quando um capítulo fica ativo, o seu clip reproduz e o clip seguinte passa a pré-carregar.
- Os clips inativos param depois de terminar o desvanecimento.
- Quando a secção inteira sai do ecrã, tudo para.
Todos os clips são sem som, em loop e playsinline, necessário para a reprodução automática no telemóvel.
Anime propriedades baratas
opacity, transform e clip-path podem ser compostas pela GPU. Animar top, width ou background-position em elementos grandes provoca recálculos ou redesenhos. A galeria horizontal move-se com translate3d, e a paralaxe de cada cartão desloca uma imagem interior através de uma transformação, não mudando a sua posição.
Sirva o vídeo com cabeça
Os clips são 720p, alguns megabytes cada, servidos através de um proxy edge que os põe em cache e suporta pedidos HTTP por intervalos, para o browser poder saltar e fazer streaming. Os posters vêm de imagens estáticas, para aparecer algo com sentido antes de ser descodificado o primeiro frame.
Respeite o movimento reduzido
Quando o visitante pediu ao sistema menos movimento, a secção deixa de ser fixada, a galeria passa a uma linha normal com scroll e o texto aparece sem animação. O conteúdo é idêntico; só a coreografia desaparece.
Defenda os seus estilos
A secção é injetada em muitos modelos diferentes, e um deles tinha uma regra de grelha genérica .gal que encolheu silenciosamente a faixa da galeria. Agora cada classe do componente tem prefixo. Se faz componentes que acabam em páginas que não controla, os espaços de nomes não são opcionais.
Resumo
- Derive tudo de um único valor de progresso.
- Agende com
requestAnimationFrame; leia, depois escreva. - Um só vídeo a reproduzir; pré-carregamento a tempo; pausa fora do ecrã.
- Anime apenas propriedades amigas do compositor.
- Ponha o vídeo em cache e sirva-o por intervalos, na edge.
- Respeite
prefers-reduced-motion. - Dê um espaço de nomes aos estilos injetados.