Este é o segundo artigo de uma série sobre a API de animação do GreenSock e o SVG. Esta 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 Motion Along a Path (Movimento ao longo de um caminho). Hoje, exploraremos brevemente alguns novos recursos do GSAP e, em seguida, iremos além e criaremos uma animação complexa responsiva do início ao fim.



O principal motivo pelo qual uso o GSAP tem a ver com o suporte entre navegadores para transformações SVG. A rotação estável do SVG é muito complicada. Em quase todos os navegadores, os problemas de origem de transformação persistem e não têm suporte algum no IE. Esse problema é claramente exacerbado quando se tenta usar transformações de forma responsiva, pois qualquer pequena anomalia de origem de transformação é exagerada e difícil de ser substituída.



O GreenSock não apenas corrige esse comportamento, mas, com suporte até o IE9, oferece mais algumas ferramentas que tornam o design e o desenvolvimento responsivos particularmente sólidos. Atualmente, as transformações em elementos SVG com tecnologias de renderização nativas (e, posteriormente, outras bibliotecas JS que as utilizam) não suportam a renderização correta com base em porcentagens. A versão mais recente (1.17.0) do GSAP resolve esse problema com cálculos de matriz.



Primeiro, vamos estabelecer que, removendo os valores de largura e altura do próprio SVG, definindo o viewbox e, em seguida, usando CSS ou JS para controlar a largura e a altura do SVG, podemos facilmente fazer com que um SVG se ajuste à porcentagem, ao flexbox ou a qualquer outro tipo de implementação responsiva. O senhor também pode adicionar preserveAspectRatio="xMinYMin meet" para garantir que todas as dimensões correspondentes sejam dimensionadas de forma apropriada e respectivas umas às outras, mas como esse é o padrão, não é estritamente necessário. Aqui está um ótimo playground de Sara Soueidan, se o senhor quiser obter mais informações sobre a caixa de visualização e o dimensionamento.



Há três pontos fortes específicos nessa última versão que se aplica ao SVG, todos empregando o uso de transformações. O primeiro é que, além do transformOrigin, o GSAP agora tem suporte integrado para svgOrigin. Isso significa que o senhor pode escolher se deseja que seu elemento se transforme com base no próprio elemento (ou seja, girando em seu próprio eixo) ou usando uma coordenada no SVG viewbox. Com svgOrigin, o senhor declararia valores de acordo com o viewbox coordenadas. Em outras palavras, se o senhor viewbox for "0 0 400 400" e o senhor deseja girar em torno do centro do SVG, deve declarar svgOrigin: "200 200"; Normalmente, o senhor descobrirá que mover e ajustar um transformOrigin é suficiente. Mas, no caso da caneta abaixo, fiz uma vaca girar em torno da lua em uma determinada parte da caixa de visualização e, como usei um svgOrigin foi muito fácil tornar essa animação responsiva:



TweenMax.set(cow, {
	svgOrigin:"321.05, 323.3",
	rotation:50
});



(Diminua o tamanho da janela horizontalmente para ver a animação se ajustar à janela de visualização)



Veja a caneta Vaca responsiva pula sobre o Moooooon por Sarah Drasner (@sdras) em CodePen.




O próximo grande recurso que abordaremos é o smoothOrigin em elementos SVG. Normalmente, se o senhor alterar a origem da transformação nos elementos depois que eles já tiverem sido transformados, o movimento se tornará complexo e contraintuitivo, conforme mostrado abaixo: (esta caneta é cortesia de Marc Grabinski)



Veja a caneta Empilhamento de transformações com SVG por Marc Grabanski (@1Marc) em CodePen.




Conforme explicado em este vídeo de Carl Schooff, da GreenSock, o smoothOrigin corrige esse problema. Ele garante que, quando o usuário altera a origem da transformação de um elemento SVG e, em seguida, move-o novamente, isso não causa nenhum tipo de salto estranho. Isso soluciona uma grande quantidade de comportamentos contra-intuitivos e de puxar os cabelos ao trabalhar com uma animação responsiva mais longa e complexa. O GSAP também lhe dá a opção de desativar isso com uma linha de código, caso o senhor queira usar a renderização nativa: CSSPlugin.defaultSmoothOrigin = false;



O último grande recurso para animações responsivas complexas no GSAP é a capacidade de fazer animações baseadas em porcentagem, dependendo dos próprios elementos SVG. O CSS e o SMIL não têm um bom suporte para esse tipo de comportamento. Assim como o Motion Along A Path, o GSAP oferece a maior compatibilidade com versões anteriores e suporte entre navegadores para transformações SVG baseadas em porcentagem. Confira esta caneta, cortesia da GreenSock:



Veja a caneta SVG Tradução baseada em porcentagem por GreenSock (@GreenSock) em CodePen.




Minha intenção original neste artigo era discutir como as transformações baseadas em porcentagem no SVG são incríveis e como elas podem ser úteis. Mas, quando comecei a escrever demonstrações para ele, percebi que o que é surpreendente, no entanto, é que o senhor não pode fazer isso, é o fato de que o senhor talvez não precise delas. As transformações do SVG dependem da tela do SVG, não de números inteiros de pixels absolutos definidos pela janela do navegador. Se combinarmos o poder da linha do tempo do GSAP com a facilidade de uso do SVG para escalabilidade, poderemos obter alguns efeitos muito interessantes. Como estamos movendo nossos elementos de acordo com o SVG DOM, os elementos não são a única coisa que é escalável. Todas as transformações e movimentos correspondentes também são:



Veja a caneta Animação complexa fluida e totalmente responsiva por Sarah Drasner (@sdras) em CodePen.




Não há consultas de mídia a serem encontradas. Estou movendo as coisas com base nos eixos x e y da seguinte forma:



tl.staggerFromTo($iPop, 0.3, {
		scale: 0,
		x: 0,
		y: 0
	}, {
	scale: 1,
		x: 30,
		y: -30,
		ease: Back.easeOut
}, 0.1, "start+=0.3")


Observe que não estamos movendo coisas com transformações baseadas em porcentagem. O GSAP está estabelecendo o comportamento com base na caixa de visualização e, portanto, a animação responsiva se torna tão fácil quanto remover a largura e a altura e declará-las em outro lugar.



É bom simplesmente “espremer” uma animação em nossa viewport, mas todos sabemos que o verdadeiro desenvolvimento responsivo é um processo mais complexo do que isso. Vamos usar nossas novas ferramentas brilhantes e combiná-las com o desenvolvimento responsivo, do início ao fim.



Há algumas maneiras de fazer isso. Uma delas é pegar um sprite SVG grande e deslocar a caixa de visualização com um manipulador de eventos de consulta de mídia. Outra opção é projetar nossa animação usando peças interligadas, como as peças de tetrise usar vários SVGs que podem ser reconfigurados. Vamos explorar essa última opção.



Veja a caneta Fábrica responsiva do Huggy Laser Panda por Sarah Drasner (@sdras) em CodePen.




Na caneta acima, Huggy Laser Panda Factory, temos três partes distintas da fábrica. Para manter nosso código organizado, cada seção pode aceitar um tipo de interação do usuário, que aciona sua própria linha do tempo. Manter os SVGs em linha distintos uns dos outros também nos permite recolhê-los e movê-los de acordo com porcentagens ou números inteiros em viewports variáveis, tornando nossa animação flexível tanto para dispositivos móveis quanto para iterações futuras. Desenhamos uma visualização inicial para desktop e também como ela será reconfigurada para telas menores, incluindo um transform:scaleX(-1); para refletir a segunda parte em dispositivos móveis, de modo que ela se encaixe perfeitamente, com uma implementação mobile-first.



@media (max-width: 730px) {
	.second {
		width: 70%;
		top: -90px;
		margin-left: 70px;
		transform: scaleX(-1);
	}
}


@media (min-width: 731px) {
	.second {
		width: 350px;
		margin-left: 365px;
		top: 370px !important;
	}
}



Cada bloco de construção tem sua própria função, nomeada de acordo com a parte da animação a que serve. Isso evita problemas de escopo e mantém tudo organizado e legível. O usuário só pode acionar comportamentos relativos ao mesmo SVG, ou bloco de construção, da animação. Pausamos a linha do tempo inicialmente, mas usamos o botão ou o grupo para reiniciá-la aqui:



//create a timeline but initially pause it so that we can control it via click
var triggerPaint = new TimelineMax({paused:true});
triggerPaint.add(paintPanda());

//this button kicks off the panda painting timeline
$("#button").on("click", function(e){
	e.preventDefault();
	triggerPaint.restart();
});


Tenha em mente que o SVG DOM é um pouco mítico e difere das operações regulares do DOM em alguns casos. O senhor não pode executar operações de classe com jQuery em elementos SVG DOM (embora isso esteja previsto para breve, em versão 3.0.0), portanto, há ocasiões em que o vanilla JavaScript funcionará melhor.



Também temos uma linha do tempo em loop que abrange muitos elementos do documento. Definimos um rótulo relativo para o início dela para que possamos definir loops em vários objetos. Isso é importante porque, se permitirmos que os loops se sigam uns aos outros em uma linha do tempo, apenas o primeiro será disparado, pois será executado para sempre e o segundo aguardará indefinidamente para ser seguido.



function revolve() {
	var tl = new TimelineMax();

	tl.add("begin");
	tl.to(gear, 4, {transformOrigin:"50% 50%", rotation:360, repeat:-1, ease: Linear.easeNone}, "begin");
	tl.to(wind, 2, {transformOrigin:"50% 50%", rotation:360, repeat:-1, ease: Linear.easeNone}, "begin");

	// ...
	return tl;
}

var repeat = new TimelineMax();
repeat.add(revolve());


Agora temos quatro linhas do tempo no total: três que estão associadas de forma limpa a cada seção e a linha do tempo global em loop. Nossa interação e nossas animações são dimensionadas com cada SVG individual, de modo que podemos movê-las e ajustá-las nas configurações que quisermos para diferentes viewports, e o código permanece direto e organizado.



Esta é a segunda 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!