Ativando animações durante o scroll
uma implementação eficiente
Para animar os elementos durante o scroll conforme entram na tela precisamos :
- Selecionar os elementos
- Uma função que verifique quais elementos estão na tela
- Ativar as animações desses mesmos elementos
- Chamar a função sempre que rolar a página
Selecionando os elementos
document.querySelectorAll retorna uma NodeList com os nodes selecionados. Para manipular essa lista (com funções próprias de arrays) precisamos transformar-la em um array com a função Array.from().
Uma boa prática é colocar o prefixo js nas classes usadas pelo javascript. Assim separamos apresentação da lógica e evitamos equívocos quando formos editar o css.
Determinando quais elementos estão na tela
Uma das maneiras de descobrir é comparar a posição da base do elemento e da base da tela. Se a da tela for maior, o elemento está dentro.
element.getBoundingClientRect()
O método retorna um objeto DOMRect, cuja propriedade bottom contém a coordenada Y (em relação ao viewport) da base do elemento.
window.scrollY
propriedade com o número de pixels que o documento já rolou na vertical.
window.innerHeight
Tamanho em pixels do viewport.
Eliminando redundâncias
Olhando o código com cuidado percebemos que o valor window.scrollY aparece nos dois lados da comparação. Podemos condensar em uma função:
O código funciona porque DOMRect.top e DOMRect.bottom representam coordenadas em relação à origem* do viewport.
Sabemos que o elemento está na tela quando: bottom for maior que a altura da tela e top for maior que zero (valor negativo estaria acima do viewport).
*Coordenada (0, 0) no canto superior esquerdo
Ativando as animações
No nosso exemplo usamos uma animação reveal que realiza um fade-in trazendo o elemento de baixo(30px) para sua posição original.
Para animar posicionamento de elementos, sempre use os transforms do css. Ao animar propriedades como top e left, o browser é forçado a recalcular o layout, operação que consome bastante memória quando abusada.
Exemplo de CSS:
Javascript:
playAnimation( element)
Inicia a animação ao mudar a propriedade animation-play-state do elemento para “running”.
forEach(playAnimation)
Aplica a função playAnimation em cada elemento do array players.
Um loop equivalente seria:
Otimizando os eventos scroll
O problema com window.addEventListener(“scroll”, callback) é disparar eventos em excesso. O callback pode ser chamado centenas de vezes em segundos.
Para resolver isso usamos throttle, uma função que impede que outra função seja executada mais de uma vez a cada X milissegundos.
Comparação Throttle vs Simples:
Como Javascript não possui essa função implementada nativamente, importaremos de uma biblioteca chamada lodash.
Instalação e uso
// Via NPM
npm install --save lodash// Via cdn, insira na tag <head>
<script src=”https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js”></script>
Implementação Final
Demo
Bibliotecas
Algumas bibliotecas que implementam esse efeito com muitas opções:
- Choreographer.js (bastante interessante, vai muito além do scroll)
- Waypoints.js
- AOS.js