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!