Exemplos de animações CSS de alto desempenho

Nesta postagem, descubra como algumas animações populares encontradas no CodePen foram criadas. Todas essas animações usam as técnicas eficientes discutidas em outros artigos desta seção.

Consulte Por que algumas animações são lentas? para saber a teoria por trás dessas recomendações e o Guia de animações para dicas práticas.

Animação de carregamento do assistente

Ver a animação de carregamento do assistente de visualização no CodePen

Essa animação de carregamento é criada totalmente com CSS. A imagem e toda a animação foram criadas em CSS e HTML, sem imagens ou JavaScript. Para entender como ele foi criado e como funciona, use o Chrome DevTools.

Inspecionar a animação com o Chrome DevTools

Com a animação em execução, abra a guia "Performance" no Chrome DevTools e grave alguns segundos da animação. No resumo, você vai notar que o navegador não está realizando nenhuma operação de layout ou pintura ao executar essa animação.

Resumo no DevTools
O resumo após a criação de perfil da animação do assistente.

Para saber como essa animação foi criada sem causar layout e renderização, inspecione qualquer um dos elementos em movimento no Chrome DevTools. Use o painel "Animações" para localizar os vários elementos animados. Clique em qualquer elemento para destacá-lo no DOM.

O painel "Animações" mostrando as várias partes da nossa animação.
Visualização e seleção de itens no painel de animação do Chrome DevTools.

Por exemplo, selecione o triângulo e observe como a caixa do elemento se transforma durante a jornada no ar, enquanto gira e retorna à posição inicial.

Vídeo mostrando como rastrear o caminho do triângulo no Chrome DevTools.

Com o elemento ainda selecionado, confira o painel "Estilos". Lá, você pode ver o CSS que desenha a forma do triângulo e a animação usada.

Como funciona

O triângulo é criado usando o pseudoelemento ::after para adicionar conteúdo gerado, usando bordas para criar a forma.

.triangle {
    position: absolute;
    bottom: -62px;
    left: -10px;
    width: 110px;
    height: 110px;
    border-radius: 50%;
}

.triangle::after {
    content: "";
    position: absolute;
    top: 0;
    right: -10px;
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 0 28px 48px 28px;
    border-color: transparent transparent #89beb3 transparent;
}

A animação é adicionada com a seguinte linha de CSS:

animation: path_triangle 10s ease-in-out infinite;

No Chrome DevTools, role para baixo no painel "Estilo" para encontrar os keyframes. Lá, você vai descobrir que a animação é criada usando transform para mudar a posição do elemento e girá-lo. A propriedade transform é uma das propriedades descritas no Guia de animações, que não faz com que o navegador execute operações de layout ou pintura (as principais causas de animações lentas).

@keyframes path_triangle {
  0% {
    transform: translateY(0);
  }
  10% {
    transform: translateY(-172px) translatex(10px) rotate(-10deg);
  }
  55% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  58% {
    transform: translateY(-172px) translatex(10px) rotate(-365deg);
  }
  63% {
    transform: rotate(-360deg);
  }
}

Cada uma das diferentes partes móveis dessa animação usa técnicas semelhantes. O resultado é uma animação complexa que funciona sem problemas.

Círculo pulsante

Ver círculo pulsante no CodePen

Esse tipo de animação às vezes é usado para chamar a atenção para algo em uma página. Para entender a animação, use o Firefox DevTools.

Inspecionar a animação com o Firefox DevTools

Com a animação em execução, abra a guia "Performance" no Firefox DevTools e grave alguns segundos da animação. Pare a gravação. Na cascata, você vai notar que não há entradas para Recalculate Style. Agora você sabe que essa animação não causa recálculo de estilo e, portanto, operações de layout e pintura.

detalhes da animação na hierarquia do Firefox
A cascata do Firefox DevTools.

Ainda no Firefox DevTools, inspecione o círculo para ver como essa animação funciona. O <div> com uma classe de pulsating-circle marca a posição do círculo, mas não desenha um círculo em si.

.pulsating-circle {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
    width: 30px;
    height: 30px;
}

O círculo visível e as animações são criados usando os pseudoelementos ::before e ::after.

O elemento ::before cria o anel opaco que se estende para fora do círculo branco, usando uma animação chamada pulse-ring, que anima transform: scale e opacity.

.pulsating-circle::before {
    content: '';
    position: relative;
    display: block;
    width: 300%;
    height: 300%;
    box-sizing: border-box;
    margin-left: -100%;
    margin-top: -100%;
    border-radius: 45px;
    background-color: #01a4e9;
    animation: pulse-ring 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;
}

@keyframes pulse-ring {
  0% {
    transform: scale(0.33);
  }
  80%, 100% {
    opacity: 0;
  }
}

Outra maneira de ver quais propriedades estão sendo animadas é selecionar o painel Animações no Firefox DevTools. Em seguida, você vai ver uma visualização das animações em uso e das propriedades que estão sendo animadas.

Com o pseudoelemento ::before selecionado, podemos ver quais propriedades estão sendo animadas.

O círculo branco é criado e animado usando o pseudoelemento ::after. A animação pulse-dot usa transform: scale para aumentar e diminuir o ponto durante a animação.

.pulsating-circle::after {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 15px;
  box-shadow: 0 0 8px rgba(0, 0, 0, 0.3);
  animation: pulse-dot 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;
}

@keyframes pulse-dot {
  0% {
    transform: scale(0.8);
  }
  50% {
    transform: scale(1);
  }
  100% {
    transform: scale(0.8);
  }
}

Uma animação como essa pode ser usada em vários lugares do aplicativo. É importante que esses pequenos toques não afetem o desempenho geral do app.

Esfera 3D em CSS puro

Ver esfera 3D CSS pura no CodePen

Essa animação parece incrivelmente complicada, mas usa técnicas que já vimos nos exemplos anteriores. A complexidade vem da animação de um grande número de elementos.

Abra o Chrome DevTools e selecione um dos elementos com uma classe de plane. A esfera é composta por um conjunto de planos e raios rotativos.

O avião parece estar girando.

Esses planos e raios estão dentro de um wrapper <div>, e é esse elemento que está girando usando transform: rotate3d.

.sphere-wrapper {
  transform-style: preserve-3d;
  width: 300px;
  height: 300px;
  position: relative;
  animation: rotate3d 10s linear infinite;
}

@keyframes rotate3d {
  0% {
    transform: rotate3d(1, 1, 1, 0deg);
  }
  25% {
    transform: rotate3d(1, 1, 1, 90deg);
  }
  50% {
    transform: rotate3d(1, 1, 1, 180deg);
  }
  75% {
    transform: rotate3d(1, 1, 1, 270deg);
  }
  100% {
    transform: rotate3d(1, 1, 1, 360deg);
  }
}

Os pontos podem ser encontrados aninhados nos elementos plane e spoke. Eles usam uma animação que usa transformação para dimensionar e traduzir. Isso cria o efeito de pulsação.

O ponto gira com a esfera e pulsa.
.spoke-15 .dot,
.spoke-21 .dot {
  animation: pulsate 0.5s infinite 0.83333333s alternate both;
  background-color: #55ffee;
}

@-webkit-keyframes pulsate {
  0% {
    transform: rotateX(90deg) scale(0.3) translateZ(20px);
  }
  100% {
    transform: rotateX(90deg) scale(1) translateZ(0px);
  }
}

O trabalho envolvido na criação dessa animação foi acertar o tempo e criar o efeito de rotação e pulsação. As animações são bem simples e usam métodos de alta performance.

Para saber como essa animação funciona, abra o Chrome DevTools e grave o desempenho enquanto ela está em execução. Após o carregamento inicial, a animação não aciona layout ou pintura e é executada sem problemas.

Conclusão

Com esses exemplos, você pode ver como animar algumas propriedades usando métodos eficientes pode criar animações muito legais. Ao usar os métodos de performance descritos no guia de animações, você pode criar o efeito desejado sem se preocupar em deixar a página lenta.