Disclaimer: If you are coming from an english or international chat/group, please roll to jsfiddle at the end of this post and get all comments and explanations in english or access jsfiddle link.
Bibliotecas de gráficos existem aos montes. A maioria pesada e com poucas (ou complexas) opções de personalização. De modo que, pensei, será que é possível usar a animação do CSS para criar um gráfico leve? Como exercício, talvez eu pudesse desenvolver uma solução de gráfico radial que pudesse funcionar bem. Esse questionamento veio a partir da pergunta de uma pessoa, em um grupo, que queria criar um loading infinito com CSS.
Criando o CSS
Para poder criar a animação do load, pensei em diversas formas que já são usadas como solução, como o gradient ou gambiarras com contornos, mas eles não usam realmente o conceito da animação do raio a partir do centro. Para resolver, pensei em apelar para a trigonometria. Dividi então o círculo em 4 triângulos retângulos.

<style> .triangulo{ width: 200px; height: 200px; background-color: #c1f347; margin:0 auto; animation: triangle 3s infinite alternate; } @keyframes triangle { from { clip-path: polygon(50% 0%, 0% 100%, 0 100%); } to { clip-path: polygon(50% 0%, 0% 100%, 100% 100%); } } <style>
OK, conseguimos criar os triângulos com o clip-path do CSS. Graças ao ele podemos colocar caminhos de uma imagem a partir de vértices. Mas como colocar isso nos 4 triângulos? Não faria o menor sentido colocar os triângulos um do lado do outro. Como fazer então para utilizar um caminho completo para dar o efeito de transição radial?
Para isso, basta fazermos um cálculo simples. Quantos vértices seriam necessários para criar um polígono que dê a volta? Bem, basta contarmos o vértices do quadrado (4) mais um ao centro que define os triângulos e mais um para fechar a animação. Ou seja, precisamos de um hexagono.
<style> .hexagono{ width: 250px; height: 250px; background-color: #f98b2a; margin: 0 auto; animation: hexagon 3s infinite alternate; } @keyframes hexagon { from { clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 0% 60%, 10% 20%); background-color: #2af9f7; } to { clip-path: polygon(50% 0%, 100% 0, 100% 60%, 100% 100%, 0 100%, 0% 60%, 0 0); } } <style>
Agora basta manipular os vértices do hexagono para se comportar similar ao triângulo retângulo, levando os pontos do vértice, em fila, sempre ao próximo ponto do quadrado.
<style> .quadrado{ width: 250px; height: 250px; background-color: #f98b2a; margin:0 auto; animation: square 3s infinite alternate; } @keyframes square { 0% { clip-path: polygon(100% 0, 100% 0%, 100% 0%, 100% 0%, 100% 0%, 50% 50%); background-color: #36ff9a; } 25% { clip-path: polygon(100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 50%); background-color: #fccf40; } 50%{ clip-path: polygon(100% 0, 100% 100%, 0% 100%, 0% 100%, 0 100%, 50% 50%); background-color: #f40696; } 75% { clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 0%, 0 0, 50% 50%); background-color: #55aadd; } 100% { clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 0, 100% 0, 50% 50%); background-color: #36ff9a; } } <style>
Basta colocar agora a animação como linear, para evitar as pausas (o padrão possui um ease) e adicionar um elemento acima com um overflow: false e um border-radius: 50%, de forma a ficar realmente circular:
Controlando com Javascript
Podemos fazer um jeitinho para que o Javascript controle a animação. Para isso, podemos usar algumas propriedades que controlam a animação. Em especial, vamos poder pausar e continuar a animação, através do parâmetro animationPlayState.
O código completo está disponível pelo jsFiddle. O código está todo comentado e pode ser testado diretamente abaixo:
Obs. Não use filtro blur ou muitas sombras se quiser compatibilidade com o Safari iOS.
Provavelmente, esta não é a melhor solução para criação de um gráfico radial. Mas é interessante vermos que podemos desenvolver novas soluções, e mais leves, a partir de tecnologias mais recentes. Se você gostou, compartilhe, se tem alguma dúvida, comente. Aproveite para curtir nossa página do Facebook e entrar no grupo, através do link abaixo.