22 de julho de 2015 • 8 min de leitura
#13 - Animando SVG com SMIL
Aprenda a criar animações usando só SVG e nada mais!
Introdução
Enquanto escrevo esse post vou ouvindo Deftones, mudar para um som mais pesado para animar um pouco.
Já faz um tempinho que não escrevia sobre SVG, então vou dar uma quebra nos outros posts e voltar a falar um pouquinho sobre. Se você ainda não conhece SVG sai daqui, dá uma olhadinha na série que eu escrevo nesse blog.
Esse post foi baseado num apanhado de informações de vários cantos:
Animações
Não é de hoje que animações são as queridinhas nos sites e apps, seja pela melhoria em algum aspecto na usabilidade, seja pela beleza que a animação pode proporcionar.
O SVG é tão incrível que permite vários tipos de animações, já falei sobre animações usando css e agora irei falar sobre um tipo específico do SVG, que é a animação usando SMIL.
Mas o que é SMIL? É de comer?
SMIL ou Synchronized Multimedia Integration Language é uma linguagem baseada em XML que permite escrever interações para os elementos. A sua sintaxe é basicamente representada pelos tempos de animações, mudanças dos elementos e inicializações dos comportamentos.
Obs.: funciona em todos os browsers exceto IE caniuse
Por que usar esse treco aí?
A animação em SMIL é declarativa, ou seja, você declara transições e estados para os elementos. A vantagem é que os browsers podem otimizar esse tipo de animação, não pesando tanto na renderização. A grande desvantagem de animações declarativas é que, em geral, elas não são tem tanto poder e não fazem tantas coisas. Eis que o SMIL brilha, ele tem a facilidade e otimização que o CSS permite com o poder de manipulação que só o JS teria.
Como o SMIL é mais poderoso, ele permite animar propriedades que o CSS não conseguiria, como, por exemplo, as formas das Paths.
Outra coisa bastante bacana é que animações feita em SMIL funcionam até mesmo quando o SVG é inserido na tag img
! =)
E também conseguimos manipular as animações com eventos! Convencido?
Comandos básicos
Assim como as diferentes tags que o SVG possui para suas formas, ele também possui algumas poucas tags para realizar essas animações, que são:
<animate>
: permite animar atributos e propriedades num determinado período de tempo.<animateTransform>
: usado para animar a transformação dos atributos num período de tempo.<animateMotion
: para mover um elemento ao longo de um path.<set>
: usado também como um "shorthand" para oanimate
, é útil para definir valores não numéricos para animação e propriedades, como a propriedade devisibility
.
Sintaxe
<animate
id="myAnim"
attributeName=" "
from=" "
to=" "
dur=" "
begin=" "
fill=" "
...
/>
Para o animate
temos os principais atributos:
attributeName
: o atributo do qual iremos alterar, pode ser umfill
oupoints
de umpath
.from
: de onde se inicia.to
: para onde vai a animação.dur
: a duração da animação.begin
: é a "trigger" de inicialização da animação. Podemos colocar comoclick
para dizer que só inicia com um click ou podemos colocar comobegin=2s
, onde dizemos que a animação só irá começar 2s depois de ter carregado.fill
: não confunda com preenchimento, esse atributo serve para dizer se a animação deve parar em seu estado final (freeze
) ou a animação ser removida quando alcançar o estado final (remove
).repeatCount
: como o nome já diz a quantidade de vezes que a animação vai repetir, se quiser que seja infinito, basta usarindefinite
.repeatDur
: marca o tempo de duração da repetição, a notação é conforme relógio normal, exemplo,1:30
significa 1 minuto e 30 segundos.
Modos de uso
Existem duas formas de se aplicar animações, que são:
Especificando um target
<rect id="myRect" ... /> <animate xlink:href="#myRect" ... />
Aninhando dentro do elemento
<rect id="myRect" ...>
<animate ... />
</rect>
Um outro detalhe muito importante é que para cada animate
só podemos animar um atributo principal, que é determinado pelo attributeName
. Portanto se quisermos fazer 2 tipos diferentes de animação, iremos precisar de 2 elementos animate
para cada atributo.
Exemplo
<svg width="500" height="100">
<circle id="orange-circle" r="30" cx="50" cy="50" fill="orange" />
<animate
xlink:href="#orange-circle"
attributeName="cx"
from="50"
to="450"
dur="1s"
begin="click"
fill="freeze"
/>
</svg>
No exemplo acima, determinamos que vamos alterar o atributo cx
do círculo, ou seja, sua posição no eixo x
, passando de 50
para 450
, com a duração de 1s
após haver o click
e tendo animação finalizada pelo freeze
ao final da movimentação.
Segue abaixo um exemplo da mudança de posição e de cor, note que utilizamos 2 animate
:
Controlando animações com keyTimes e values
Assim como nos keyframes do css, no SMIL também podemos criar um conjunto de valores e tempos para criar a animação da forma que desejarmos.
Segue um exemplo utilizando:
values="50; 490; 350; 450" keyTimes="0; 0.5; 0.8; 1"
Como pode perceber, no tempo 0
o círculo está na posição 50
, aos 0.5
é onde ele vai mais longe, 490
, depois ele retorna para 350
e então avança para 450
, exatamente como os valores informados. Sempre obedecendo a proporção de uma mudança para um tempo.
Mudando as formas de uma path
Como disse no início do post, a vantagem do SMIL é poder manipular propriedades que o CSS não muda, como, por exemplo a forma de um path.
Vamos pensar num primeiro exemplo, onde queremos transformar um quadrado em um círculo.
Nós iremos trabalhar no attributeName=d
, que é onde desenhamos a path e teremos 2 passos, from
, que contém a forma de um quadrado e o to
, que contém a forma de um círculo, definimos um tempo para a animação ocorrer e pronto, a mágica acontece.
Agora vamos pensar numa situação em que eu tenho um quadrado virando um triângulo e este virando um círculo, ou seja, 3 etapas. Para trabalhar com mais de uma etapa, basta definir mais valores dentro de values
e casos queiramos mudar o tempo de acordo com a mudança, podemos usar o keyTimes
. Segue um exemplo dessa transição:
Mas e se eu quisesse além de mudar os 3 visuais, também quisesse mudar de cor? Basta adicionar mais um animate, passando os values
do attributeName=fill
. Segue um exemplo colorido:
Aplicação prática em UX
Pow Willian, isso tudo aí é muito legal, muito maneiro, mas não vejo utilidade nenhuma nisso aí. Onde eu poderia aplicar um treco desses no meu site?
Podemos, por exemplo, aplicar uma mudança de um ícone para dar um feedback para o usuário. Segue um botão seguindo esse tipo de interação:
As animações realizadas para o botão acima ficam separadas em:
- Transformar no check
- Mudar para cor verde
- Transformar na estrela
- Mudar para cor amarela
Para cada uma dessas animações utilizamos a tag animate
sempre definindo o to
, que significa para onde estamos transformando. O JS utilizado no exemplo é só para adicionar o textinho (salvar -> salvo!) e iniciar as animações. Mas lembramos que podemos utilizar o begin=click
para fazer esse tipo de trigger para inicialização.
Conclusão
Bom pessoal, esse post serviu para mostrar mais uma habilidade exclusiva e super interessante que o SVG possui. Lembre-se que animações para conseguir melhorar a usabilidade do usuário são sempre boas adições e o SVG pode te prover isso muito bem. Existem muitas coisas sobre SMIL, portanto não fique somente neste post e busque ainda mais informação, qualquer coisa, também pergunte nos comentários.