Design,Tutoriais -

Gráfico / Loader Radial com CSS e Javascript Puro

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.


A partir daí podemos considerar a animação a partir de cada dos vértices da hipotenusa, se abrindo do raio, formando o triângulo retângulo, como no exemplo abaixo:

<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:

0%




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.

Dúvidas?
Entre em um de nossos grupos ou deixe um comentário:

Grupo no Facebook Grupo no Telegram