Na segunda parte, animo as letras e defino suas posições e cores.
GOOD MOOD (série de 6 partes)
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.