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.