Na segunda parte, animo as letras e defino suas posições e cores.
Animando as letras
Atributos do elemento animate
attributeName
Nome do atributo que mudará durante a animação, o atributo d
no caso desta animação.
values
Sequência de valores usada no decorrer da animação. No caso desta animação, são 3 valores do atributo d
.
Para as letras da primeira fileira: versão normal, versão esticada e versão normal novamente. Na segunda fileira: versão esticada, versão normal e versão esticada novamente.
calcMode
Modo de interpolação (processo que calcula os valores intermediários da animação), que é spline
. Permite usar curvas de Bézier para definir a função de tempo, possibilitando transições suaves.
keyTimes
Sequência de valores que define o ritmo da animação, cada valor fica entre 0
e 1
. Com calcMode spline
, para cada valor de values
, deve existir um valor de keyTimes
.
No caso desta animação, 0; 0.5; 1
. Ou seja, o primeiro valor de values
é usado no início da animação, o segundo valor é usado na metade da animação, e o terceiro valor é usado no fim da animação.
keySplines
Sequência de valores que define as curvas de Bézier (x1, y1, x2, y2
) usadas nos intervalos entre os valores do atributo keyTimes
.
No caso desta animação, 0.45, 0.05, 0.55, 0.95; 0.45, 0.05, 0.55, 0.95
(duas curvas iguais). Ou seja, entre 0; 0.5
o primeiro valor é usado, e entre 0.5; 1
o segundo valor é usado.
begin
Define quando a animação deve começar. Usei para atrasar o início da animação de cada coluna para criar o movimento de onda.
dur
A duração da animação, que é 1s
.
repeatCount
Número de repetições, que é indefinite
(repete-se indefinidamente).
Atributos desta animação
Deixei o atributo d
do elemento path
vazio, visto que ele é definido no atributo values
do elemento animate
. Os únicos atributos do elemento animate
que mudam de uma letra para outra são values
e begin
, os demais atributos têm o mesmo valor em todas as letras.
<svg viewBox="0 0 10 20"> <path d=""> <animate attributeName="d" begin="valor baseado na coluna" dur="1s" repeatCount="indefinite" calcMode="spline" keySplines="0.45, 0.05, 0.55, 0.95; 0.45, 0.05, 0.55, 0.95" keyTimes="0; 0.5; 1" values="desenho de letra; desenho de letra; desenho de letra" /> </path></svg>
Nas visualizações seguintes não defini o atributo begin
, porque ainda estava lidando individualmente com cada letra. Mostro a posição final na seção Definindo as posições.
Nestas seções usei um viewBox
que comporta apenas uma letra:
<svg viewBox="0 0 10 20" width="200"> <!-- demais elementos entrarão aqui --></svg>
Primeira fileira
Em cada visualização, omiti os elementos svg
e path
que se encontrariam em volta do elemento animate
, assim como seus demais atributos, para manter o código conciso.
<animate values=" versão normal; versão esticada; versão normal "/>
Letra G
<animate values=" M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,4.6 L6,4.6 L6,4 C6,3 4,3 4,4 L4,6 C4,7 6,7 6,6 L5,6 L5,5 L10,5 L10,10 L7,10 L6.6,9 Q6,10 4,10 Q0,10 0,6z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,14.6 L6,14.6 L6,4 C6,3 4,3 4,4 L4,16 C4,17 6,17 6,16 L5,16 L5,15 L10,15 L10,20 L7,20 L6.6,19 Q6,20 4,20 Q0,20 0,16z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,4.6 L6,4.6 L6,4 C6,3 4,3 4,4 L4,6 C4,7 6,7 6,6 L5,6 L5,5 L10,5 L10,10 L7,10 L6.6,9 Q6,10 4,10 Q0,10 0,6z "/>
Letra O
<animate values=" M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L4,10 Q0,10 0,6 L4,6 C4,7 6,7 6,6 L6,4 C6,3 4,3 4,4 L4,6 L0,6z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,4 C6,3 4,3 4,4 L4,16 L0,16z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L4,10 Q0,10 0,6 L4,6 C4,7 6,7 6,6 L6,4 C6,3 4,3 4,4 L4,6 L0,6z "/>
Letra D
<animate values=" M0,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L0,10 L0,7 L4,7 Q6,7 6,6 L6,4 Q6,3 4,3 L4,7 L0,7z; M0,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,4 Q6,3 4,3 L4,17 L0,17z; M0,0 L6,0 Q10,0 10,4 L10,6 Q10,10 6,10 L0,10 L0,7 L4,7 Q6,7 6,6 L6,4 Q6,3 4,3 L4,7 L0,7z "/>
Segunda fileira
Em cada visualização, omiti os elementos svg
e path
que se encontrariam em volta do elemento animate
, assim como seus demais atributos, para manter o código conciso.
<animate values=" versão esticada; versão normal; versão esticada "/>
Letra M
<animate values=" M0,0 L4,0 L5,6 L6,0 L10,0 L10,20 L7,20 L7,7 L6,20 L4,20 L3,7 L3,20 L0,20z; M0,10 L4,10 L5,14 L6,10 L10,10 L10,20 L7,20 L7,15 L6,20 L4,20 L3,15 L3,20 L0,20z; M0,0 L4,0 L5,6 L6,0 L10,0 L10,20 L7,20 L7,7 L6,20 L4,20 L3,7 L3,20 L0,20z "/>
Letra O
<animate values=" M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,4 C6,3 4,3 4,4 L4,16 L0,16z; M0,14 Q0,10 4,10 L6,10 Q10,10 10,14 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,14 C6,13 4,13 4,14 L4,16 L0,16z; M0,4 Q0,0 4,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L4,20 Q0,20 0,16 L4,16 C4,17 6,17 6,16 L6,4 C6,3 4,3 4,4 L4,16 L0,16z "/>
Letra D
<animate values=" M0,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,4 Q6,3 4,3 L4,17 L0,17z; M0,10 L6,10 Q10,10 10,14 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,14 Q6,13 4,13 L4,17 L0,17z; M0,0 L6,0 Q10,0 10,4 L10,16 Q10,20 6,20 L0,20 L0,17 L4,17 Q6,17 6,16 L6,4 Q6,3 4,3 L4,17 L0,17z "/>
Definindo as posições
Elementos defs
e use
Defini o atributo id
de cada elemento path
e os coloquei dentro do elemento defs
, para que depois pudesse referenciá-los com elementos use
pelo atributo href
.
Com o elemento use
, defini a posição de cada letra com os atributos x
e y
, seguindo a grade. Pus um número no fim do valor do atributo id
das letras que se repetiam, pois eles devem ser únicos.
<!-- omiti os atributos dos elementos animate para manter o código conciso --><svg viewBox="0 0 63 51"> <defs> <!-- primeira fileira --> <path d="" id="letter-g"><animate /></path> <path d="" id="letter-o-1"><animate /></path> <path d="" id="letter-o-2"><animate /></path> <path d="" id="letter-d-1"><animate /></path> <!-- segunda fileira --> <path d="" id="letter-m"><animate /></path> <path d="" id="letter-o-3"><animate /></path> <path d="" id="letter-o-4"><animate /></path> <path d="" id="letter-d-2"><animate /></path> </defs> <!-- primeira fileira --> <use href="#letter-g" x="10" y="10" /> <use href="#letter-o-1" x="21" y="10" /> <use href="#letter-o-2" x="32" y="10" /> <use href="#letter-d-1" x="43" y="10" /> <!-- segunda fileira --> <use href="#letter-m" x="10" y="21" /> <use href="#letter-o-3" x="21" y="21" /> <use href="#letter-o-4" x="32" y="21" /> <use href="#letter-d-2" x="43" y="21" /></svg>
Definindo o atributo begin
Seguindo a animação original, quando a primeira coluna está esticada para cima, a última coluna está esticada para baixo. Como a animação tem 1s, defini que a primeira coluna tem o atributo begin
como -1
(valores negativos fazem com que não exista delay ao iniciar a animação), e a última coluna como -0.5
. Ou seja, quando a primeira coluna completa um clico de animação, a última coluna completa metade de um ciclo.
Para obter o valor do atributo begin
das demais colunas, calculei o intervalo de tempo que deveria existir entre o início da animação de cada uma das 4 colunas: 0.5 / 3 ≈ 0.1666
. Com isso, calculei o valor do atributo begin
de cada coluna:
- Primeira coluna:
-1
- Segunda coluna:
-1 + 0.1666 ≈ -0.8333
- Terceira coluna:
-0.8333 + 0.1666 ≈ -0.6666
- Quarta coluna:
-0.6666 + 0.1666 ≈ -0.5
<!-- omiti os demais atributos dos elementos animate para manter o código conciso --><svg viewBox="0 0 63 51"> <defs> <!-- primeira fileira --> <path d="" id="letter-g"> <animate begin="-1" /> </path> <path d="" id="letter-o-1"> <animate begin="-0.8333" /> </path> <path d="" id="letter-o-2"> <animate begin="-0.6666" /> </path> <path d="" id="letter-d-1"> <animate begin="-0.5" /> </path> <!-- segunda fileira --> <path d="" id="letter-m"> <animate begin="-1" /> </path> <path d="" id="letter-o-3"> <animate begin="-0.8333" /> </path> <path d="" id="letter-o-4"> <animate begin="-0.6666" /> </path> <path d="" id="letter-d-2"> <animate begin="-0.5" /> </path> </defs> <!-- primeira fileira --> <use href="#letter-g" x="10" y="10" /> <use href="#letter-o-1" x="21" y="10" /> <use href="#letter-o-2" x="32" y="10" /> <use href="#letter-d-1" x="43" y="10" /> <!-- segunda fileira --> <use href="#letter-m" x="10" y="21" /> <use href="#letter-o-3" x="21" y="21" /> <use href="#letter-o-4" x="32" y="21" /> <use href="#letter-d-2" x="43" y="21" /></svg>
Definindo cores
Defini as cores de cada letra no elemento use
, e a cor do plano de fundo com um elemento rect
. A ordem dos elementos importa, o rect
deve ser desenhado antes das letras, do contrário, o rect
seria desenhado por cima das letras.
<div class="wrapper"> <div class="container"> <svg viewBox="0 0 63 51"> <defs> <!-- omiti o conteúdo do elemento defs para manter o código conciso --> </defs> <!-- fundo preto --> <rect width="63" height="51" fill="#000" /> <!-- primeira fileira --> <use href="#letter-g" x="10" y="10" fill="#FFFFFF" /> <use href="#letter-o-1" x="21" y="10" fill="#FFFFFF" /> <use href="#letter-o-2" x="32" y="10" fill="#FFFFFF" /> <use href="#letter-d-1" x="43" y="10" fill="#FFFFFF" /> <!-- segunda fileira --> <use href="#letter-m" x="10" y="21" fill="#FFB200" /> <use href="#letter-o-3" x="21" y="21" fill="#006BF5" /> <use href="#letter-o-4" x="32" y="21" fill="#FD002D" /> <use href="#letter-d-2" x="43" y="21" fill="#FF769F" /> </svg> </div></div>
Para centralizar a animação, adicionei CSS.
/* reset simples */*,*::before,*::after { box-sizing: border-box; margin: 0; padding: 0;}/* o wrapper tem a altura do viewport */.wrapper { display: flex; min-height: 100vh;}/* a animação fica no centro da tela */.container { margin: auto; width: 800px; max-width: 100%;}
Conclusão
Tendo a animação feita e as cores definidas, segui para os filtros: GOOD MOOD parte 3: aplicando filtros.