Este é o segundo artigo de uma série sobre a API GreenSock de Animação e SVG. Esta série não é destinada para iniciantes, mas sim um mergulho profundo em alguns dos recursos mais interessantes e menos conhecidos com que se pode trabalhar depois de ter conseguido passar pela introdução inicial. O primeiro artigo era sobre movimento ao longo de um caminho. Hoje vamos explorar brevemente alguns novos recursos GSAP e, em seguida, ir mais longe e criar uma animação responsiva complexa do início ao fim.
A razão número um pela qual eu uso GSAP tem a ver com o suporte cross-browser para transformações SVG. A rotação do SVG estável é muito complicada. Em quase todos os navegadores, ao transformar a origem, os problemas persistiam, e são completamente não suportados no IE. Esse problema é claramente agravado quando existe a tentativa de usar as transformações de uma forma responsiva, como quaisquer pequenas anomalias que transformam a origem e são exageradas e difíceis de substituir.
O GreenSock não apenas corrige esse comportamento, mas com o apoio para IE9, oferece mais algumas ferramentas que tornam o design e o desenvolvimento responsivo particularmente sólidos. Atualmente, transformações de elementos SVG com tecnologias de renderização nativas (e, posteriormente, outras bibliotecas JS que os utilizam) não suportam a renderização correta com base em percentuais. A versão mais recente (1.17.0) do GSAP resolve esse problema com os cálculos de matrizes.
Vamos primeiro estabelecer que, retirando os valores de largura e altura do próprio SVG, definindo a viewbox e, em seguida, usando CSS ou JS para controlar a largura e a altura do SVG, podemos facilmente fazer uma SVG ajustar a porcentagem, flexbox, ou qualquer outro tipo de implementação responsiva. Você também pode adicionar preserveAspectRatio = “xMinYMin meet” para garantir que todas as dimensões correspondentes serão dimensionadas de forma adequada e respectiva umas com as outrss, mas uma vez que isso é o padrão, não é estritamente necessário. Está aqui um grande parque de diversões, de Sara Soueidan, caso você queira obter conhecimento mais profundo em viewbox e escalação.
Há 3 pontos fortes nessa última versão que se aplica ao SVG, todos empregando o uso de transformações. O primeiro é que, além de transformOrigin, o GSAP agora tem suporte embutido para svgOrigin. Isso significa que você pode escolher se quer que seu elemento se transforme com base no próprio elemento (ou seja, girando sobre seu próprio eixo) ou usando uma coordenada no SVG viewbox. Com svgOrigin, você iria declarar valores de acordo com as coordenados viewbox. Em outras palavras, se o seu viewbox é “0 0 400 400” e você quer girar em torno do centro do SVG, você declararia svgOrigin: “200 200”; normalmente, você verá que a mudança e os ajustes em um transformOrigin é suficiente. Mas, no caso do pen abaixo, fiz uma rodada em torno da lua em uma determinada parte do viewbox, e porque eu usei um svgOrigin como coordenada, foi muito fácil de fazer esta animação responsiva:
TweenMax.set(cow, { svgOrigin:"321.05, 323.3", rotation:50 });
(tamanho da janela para baixo horizontalmente para assistir a animação ajustar a viewport)
See the Pen Responsive Cow Jumps Over the Moooooon by Sarah Drasner (@sdras) on CodePen.
A próxima grande característica nós vamos cobrir é smoothOrigin em elementos SVG. Normalmente, se você alterar a origem da transformação em elementos depois que eles já foram transformados, o movimento torna-se complexo e contraditório como visto abaixo: (este pen é cortesia de Marc Grabinski): See the Pen Stacking Transforms with SVG by Marc Grabanski (@1Marc) on CodePen.
Como explicado neste vídeo por Carl Schooff da GreenSock, o smoothOrigin corrige esse problema. Ele garante que quando você altera a origem de transformação em um elemento SVG e posteriormente o move novamente, não causará qualquer comportamento estranho. Isso resolve uma enorme quantidade de comportamento contraintuitivo e funciona muito bem quando se trabalha com uma animação mais longa, complexa e responsiva. O GSAP também deixa a opção de desativar isso com uma linha de código, caso você gostaria de usar a renderização nativa: CSSPlugin.defaultSmoothOrigin = false;.
O último grande recurso para animações responsivas complexas em GSAP é a capacidade de fazer animações baseadas em percentuais dependentes dos próprios elementos SVG. CSS e SMIL não têm um bom suporte para esse tipo de comportamento. Assim como movimento ao longo de um caminho, o GSAP oferece o suporte com mais compatibilidade para versões anteriores e cross-browser para transformações SVG baseadas em percentuais. Confira este pen cortesia de GreenSock:
See the Pen SVG Percent-based translation by GreenSock (@GreenSock) on CodePen.
Minha intenção original neste artigo foi discutir como surpreendentes transformações com base em percentuais sobre SVG são e como eles podem ser úteis. Mas quando comecei a escrever demos para ele, eu percebi que o que é surpreendente, porém, é o fato de que você pode não precisar deles. As transformações do SVG dependem do canvas SVG, não absoluta, integers de pixel e janela de navegador definidos. Se nós compararmos o poder da linha de tempo do GSAP com a facilidade de uso para a escalonabilidade do SVG, podemos obter alguns efeitos muito interessantes. Porque nós estamos movendo nossos elementos de acordo com o SVG DOM, elementos não são a única coisa que é escalonável. Todas as transformações correspondentes e movimento são assim também: See the Pen Completely Responsive, Fluid Complex Animation by Sarah Drasner (@sdras) on CodePen.
Não há consultas de mídia para serem encontradas. Estou mudando as coisas com base nos eixos x e y, assim:
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")
Note que não estamos movendo coisas com as transformações baseadas em percentuais. O GSAP está estabelecendo comportamentos baseados no viewbox e, portanto, a animação responsiva torna-se tão fácil como remover a largura e a altura e declará-las em outro lugar.
É bom apenas para “esmagar” uma animação na nossa janela, mas todos nós sabemos que o verdadeiro desenvolvimento responsivo é um processo mais complexo do que isso. Vamos dar nossas novas ferramentas brilhantes para um desenvolvedor e ajudá-lo com algum desenvolvimento respnsivo, do início ao fim.
Existem algumas maneiras sobre como nós podemos fazer isso. Uma delas é tomar um grande sprite SVG e deslocar o viewbox com um manipulador de eventos consulta de mídia. Outra é projetar nossa animação usando partes de bloqueio, bem como peças de Tetris,e usar vários SVGs que podem ser reconfigurados. Vamos explorar o último.
See the Pen Responsive Huggy Laser Panda Factory by Sarah Drasner (@sdras) on CodePen.
No pen acima, Huggy Laser Panda Factory, temos 3 partes distintas da fábrica. A fim de manter o nosso código organizado, cada seção pode aceitar um tipo de interação com o usuário, que então aciona a 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 a percentagem ou inteiros em viewports variáveis, tornando a nossa animação flexível para ambas as iterações móveis e futuras. Planejamos uma view inicial para desktop, assim como a forma que vai ser reconfigurada para telas menores, incluindo transform:scaleX(-1); para a refletir na segunda opção no mobile, de forma que fique bem, 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 para qual parte da animação serve. Isso evita quaisquer problemas de escopo e mantém tudo organizado e legível. O usuário só pode desencadear comportamentos em relação ao mesmo SVG ou bloco de construção da animação. Fazemos uma pausa na linha do tempo inicialmente, mas utilize o botão ou grupo para reiniciá-lo 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 como um animal mítico, e difere de operações DOM regulares em alguns casos. Você não pode executar operações de classe com jQuery em elementos DOM SVG (embora isso seja feito em breve, na versão 3.0.0), de forma que há momentos em que o JavaScript irá funcionar melhor.
Temos também uma linha do tempo em loop que abrange muitos elementos no documento. Montamos um rótulo em relação ao início do mesmo modo para que nós possamos definir loops em vários objetos. Isso é importante porque se deixarmos loops em sequência em uma timeline, apenas um será disparado, e ele vai rodar para sempre e o segundo vai esperar eternamente para a sequência.
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 são corretamente associadas com cada seção, e cronograma de looping global. Nossa interação e animações escalonam com cada SVG individual, e por isso estamos livres para movimentá-los e ajustá-los nas configurações que nós gostamos de diferentes viewports, e o código ficará claro e organizado.
Esta é a segunda parte de uma série. À medida que avançamos aprendendo cada uma destas técnicas, vamos arranjar juntos maneiras diferentes de trabalhar para criar um trabalho cada vez mais complexo e envolvente. Fique atento!