Este é o terceiro artigo de uma série sobre a API de animação do GreenSock e o SVG. Essa série não se destina a iniciantes, mas sim a um mergulho profundo em alguns dos recursos mais interessantes e menos conhecidos com os quais se pode trabalhar depois de passar pela introdução inicial. O primeiro artigo foi sobre Movimento ao longo de um caminho. A segunda foi sobre Animação responsiva complexa. Hoje, exploraremos brevemente alguns novos recursos do GSAP e os usaremos para criar uma animação mais complexa.
Ciclo de escalonamento
O primeiro recurso que abordaremos é o ciclo de escalonamento. O recurso de escalonamento em muitas bibliotecas de animação JavaScript tende a ser uma ferramenta incrivelmente útil para a criação de animações elegantes e é, sem dúvida, uma vantagem em relação ao fluxo de trabalho do CSS para criar o mesmo efeito. Para criar um efeito de escalonamento no CSS, o senhor aumenta o atraso usando o elemento ou pseudoelemento com os mesmos keyframes:
@keyframes staggerFoo {
to {
background: orange;
transform: rotate(90deg);
}
}
.css .bar:nth-child(1) { animation: staggerFoo 1s 0.1s ease-out both; }
.css .bar:nth-child(2) { animation: staggerFoo 1s 0.2s ease-out both; }
.css .bar:nth-child(3) { animation: staggerFoo 1s 0.3s ease-out both; }
.css .bar:nth-child(4) { animation: staggerFoo 1s 0.4s ease-out both; }
.css .bar:nth-child(5) { animation: staggerFoo 1s 0.5s ease-out both; }
.css .bar:nth-child(6) { animation: staggerFoo 1s 0.5s ease-out both; }
E, no SASS, o senhor poderia SECAR um pouco:
@keyframes staggerFoo {
to {
background: orange;
transform: rotate(90deg);
}
}
@for $i from 1 through 6 {
.sass .bar:nth-child(#{$i} ) {
animation: staggerFoo 1s ($i * 0.1s) ease-out both;
}
}
No entanto, com o GSAP, o senhor pode criar esse efeito com uma única linha de código:
TweenMax.staggerTo(".gsap .bar", 1, { backgroundColor: "orange", rotation: 90, ease: Sine.easeOut}, 0.1);
Veja a caneta aqui por Sarah Drasner (@sdras) em CodePen.
A concisão é uma vantagem para o fluxo de trabalho, especialmente se for necessário fazer ajustes no futuro.
Com o ciclo de escalonamento, agora podemos passar vários valores para escalonar entre eles, algo que seria exponencialmente complexo em CSS. A sintaxe exige uma matriz de valores:
TweenMax.staggerTo(".foo", 1, {
cycle: {
y: [75, 0, -75]
},
ease: Power4.easeInOut
}, 0.05);
Que o senhor também pode randomizar, para obter efeitos ainda mais interessantes.
var coord = [40, 800, 70, -200];
TweenMax.staggerTo(".foo", 1, {
cycle: {
x: function(i) {
return coord[Math.floor(Math.random() * coord.length)];
}
},
ease: Power4.easeInOut
}, 0.1);
Na caneta a seguir, eu simplesmente escalonei entre três valores para cada elemento e apliquei isso somente a um elemento no SVG. Com muito pouco código (22 linhas de JS), o senhor pode fazer muito:
Veja a caneta SVG com escalonamento de ciclo por Sarah Drasner (@sdras) em CodePen.
Animação de cores HSL relativas
Este é relativamente simples. O senhor entendeu? Relativo? Caramba. A capacidade de interpor quantidades relativas de cores HSL é fantástica, pois se o senhor pretende criar efeitos de cores sofisticados facilmente na animação, é preciso fazer um pequeno ajuste:
produz efeitos visuais muito poderosos. Digamos que o senhor queira transformar uma cena inteira, cada elemento com uma cor ligeiramente diferente, do dia para a noite, lentamente. Anteriormente, a maneira mais fácil de fazer isso era alterar lentamente o valor da cor de cada um desses elementos individualmente. O senhor poderia colocar uma sobreposição em todo o contêiner, mas isso carece de sofisticação e realismo. Ou, talvez, usar um filtro de matriz de fe SVG, que é muito pouco semântico e não é muito intuitivo de animar. Ou até mesmo um filtro CSS, que, até o momento, não tem muito suporte. Agora, em um pequeno trecho de código, o senhor pode, de maneira uniforme e com grande compatibilidade com versões anteriores, pegar centenas de elementos e torná-los um pouco mais escuros, diminuir a saturação relativa e ajustar lentamente o matiz para transformá-los em uma tonalidade ligeiramente diferente. O Tweening HSL também tem a vantagem de poder ser usado tanto para background (para divs) ou fill (para SVG) porque não é opinativo em relação a um determinado tipo de propriedade. 13;
Aqui está uma pequena demonstração para mostrar como ele funciona:
Veja a caneta Tartarugas que mostram o Relative HSL tweening por Sarah Drasner (@sdras) em CodePen.
Tantas opções! Qual é um bom caso de uso? Vamos deixar isso para o seu visualizador. Podemos juntar o ciclo de escalonamento e a interpolação de cores HSL com alguma interação. Mas, em vez de uma cena noturna, vamos deixá-la um pouco mais selvagem.
Como estamos interpolando valores relativos, podemos combinar efeitos nos botões e obter vários resultados. Criaremos dois botões diferentes com efeitos relativos ligeiramente diferentes. Também vale a pena mencionar que finalmente temos o operação de classe em SVG na versão 3.0.0 do jquery e podemos controlar facilmente nossos tweens na interação:
//button hue
function hued() {
//keeps the fill and background consistent relative hue changes
var ch1 = "hsl(+=110%, +=0%, +=0%)",
tl = new TimelineMax({
paused: true
});
tl.add("hu");
tl.to(mult, 1.25, {
fill: ch1
}, "hu");
//tweens for background because of divs and css
tl.to(body, 1.25, {
backgroundColor: ch1
}, "hu");
//the gauge responds to the action in the scene as if it's showing pressure
tl.from(gauge, 2, {
rotation: "-=70",
transformOrigin: "50% 50%",
ease: Bounce.easeOut
}, "hu");
return tl;
}
var hue = hued();
//same thing for the tweens for button saturation (has some relative hue as well)
function saturation() {
var ch2 = "hsl(+=5%, +=2%, -=10%)",
tl = new TimelineMax({
paused: true
});
tl.add("sated");
tl.to(body, 1, {
backgroundColor:ch2
}, "sated");
tl.to(mult, 2, {
fill:ch2
}, "sated");
tl.from(gauge, 2, {
rotation: "-=100",
transformOrigin: "50% 50%",
ease: Bounce.easeOut
}, "sated");
return tl;
}
var sat = saturation();
// ...
//detect class and either start or reverse the timeline depending
$(but1).on('click', function(e) {
e.preventDefault();
$(this).toggleClass('a-s');
if ($(this).hasClass('a-s')) {
sat.restart();
} else {
sat.reverse();
}
});
$(but2).on('click', function(e) {
e.preventDefault();
$(this).toggleClass('a-h');
if ($(this).hasClass('a-h')) {
hue.restart();
} else {
hue.reverse();
}
});
Também faremos com que a cena seja escalonada com um pouco mais de nuance com o novo ciclo de escalonamento. Mas como queremos que todos os elementos entrem e tenham a mesma aparência, faz mais sentido usar um staggerFrom do que um staggerTo:
tl.staggerFrom(city, 0.75, {
y: -50,
scale: 0,
cycle:{
x:[300, 100, 200],
opacity:[0.5, 0.3, 0.2, 0.8],
rotation:[50, 100, 150],
},
transformOrigin: "50% 50%",
ease: Back.easeOut
}, 0.02, "in");
E isso se torna nosso conjunto de construtores de cidades:
Veja a caneta Local de construção da cidade por Sarah Drasner (@sdras) em CodePen.
Há mais um recurso importante nesta versão: interpolação e transformação de valores complexos baseados em strings. No entanto, esse é um recurso tão incrível que dedicaremos um artigo futuro a ele.
Esta é a terceira parte de uma série de várias partes. À medida que avançarmos no aprendizado de cada uma dessas técnicas, uniremos diferentes maneiras de trabalhar para criar trabalhos cada vez mais complexos e envolventes. Fique ligado!