Jump to content
Search Community

Stagger all elements of an SVG

celli test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi, I am trying to stagger the opacity of all of the polygons, lines, etc that are part of an SVG (there are 900 elements). I have a basic codePen set up and I think I would need to make an array for all of the elements inside of my SVG in order to stagger the opacity of each piece, but I'm not really sure that is the way to start. The codepen only has 4 elements to simplify things, but the SVG I wanted to animate has about 900 separate pieces. I want to target all of the pieces inside on my SVG and stagger their opacity efficiently, if I have 900 pieces...


I am finding that with so many shapes, it goes very slow only because there are so many shapes and it takes time for them all to render--so I want to try and overlap them with a large number, so elements would pretty much animate at the same time... or better yet, be able to set a time so that all elements would animate in within 3 seconds... is that possible ?

See the Pen XbqgMa by celli (@celli) on CodePen

Link to comment
Share on other sites

hmm, not really sure what to tell you in addition to what you are already doing. 

Its really just a matter of selecting all the elements properly and passing them into a stagger method.

Maybe there are some tips here: https://css-tricks.com/polylion/


Keep in mind that 900 opacity animations can be quite stressful, so you may hit some performance issues.


This svg demo has about 2000 objects and can definitely get the fans humming http://codepen.io/brondbjerg/details/oXqVrr (move mouse to control animation)


To be clear GSAP can eat 2000 tweens for breakfast and beg for more, but its lot of rendering work for the browser (especially with svg and especially on mobile).

  • Like 2
Link to comment
Share on other sites

I'm not trying to knock the demo that Carl linked to. Mike Brondbjerg did a great job on it, and it's very impressive. But trying to use that many SVG polygons in a normal animation is not going to work. At least not until SVGs become GPU accelerated.  The animation in that demo seems to run pretty good, but there's a little deception going on. You're controlling the frame rate with your mouse. Check out the same animation running as a normal tween.


See the Pen 297954bb0fc3f5afe0ad6c03e7ea85a4 by osublake (@osublake) on CodePen


It's almost unwatchable in Firefox and IE. I can only imagine what would happen if you tried to load that demo on your phone. You might want to explore other ways of doing this, like drawing your SVG elements onto canvas elements, or using a sprite sheet.

Link to comment
Share on other sites

Thanks Guys ! It looks like I will try and merge shapes together in my SVG to get the number way down!


One quick question however. In this code:

tl.staggerFrom(shapes, .5, {transformOrigin:"50% 50%", opacity:0, scale:1.2, drawSVG:"100%"}, -1)

The " .5 " represents the time it takes for each tween to take place, and the " -1 " is the time it will use to stagger or overlap each element, correct ? But when I have a number that controls the overlapping that is twice as large as the animated elements itself, to try and effectively speed up the overall time of the animation... it causes unexpected results (and negative numbers seem to act the same as positive integers). Is this correct in thinking that the stagger number would always need to be a lower number than the animate number ?

Link to comment
Share on other sites



The unwanted behaviour is completely expected.


Keep in mind that stagger() methods return an array of tweens. In the case of a single TweenMax instance those tweens are played with the specific delays. Inside a timeline they're added to the timeline considering he stagger time you've given them. In this case using stagger with a time that is longer than the instance duration seems a little odd to me, specially if you want the next element in your array/collection to start animating before the previous one. In that case I would use a loop to add each instance to the timeline and the position parameter to set the difference between every instance.


As for the negative values in the stagger value acting the same, that's  expected (to me at least). Since you have a bunch of tweens that will start at the same time and you want to set a common delay between them. If you set a negative time you're saying "I want each tween to start 1 second before the previous one", so ok, but what happens with the first one?, that should start 1 second before itself?, and doesn't the second tween starts 1 second before the first one, shouldn't that time be the same time of the first one?, and the third, fourth and so on?.


In that case is better to loop through the elements and start each element 1 second before the previous one's tween has ended using a common from() instance. Now beware that if the instances are being added to the timeline at the start, you'll get some unexpected behaviour, because the first instance will start at 0 and lasts 0.5 seconds and the second instance will be added 1 second before the first one ended, that would be minus 0.5 seconds, and unless a bunch of physics and mathematics throughout the history of mankind are wrong there's no negative time. But in order to not break the space/time continuum GSAP accommodates instances that start in a negative time to appear at the end of the timeline and the other instances should all render at the same time.


As you can see is not an easy scenario and my best advice is to rethink what you want to do and try a different approach.


Happy Tweening!!

  • Like 1
Link to comment
Share on other sites

I wound up grouping multiple polygons together, and animating the groups. It seems to work pretty well.  Do you think that because my SVG still has so many shapes it will slow things up and cause browsers to render it slowly ? I assume it is only the actual animating of elements that would bog things down, so limiting the number of elements that animate should do it--but the SVG code in HTML has so many lines, I worry that it might not be the most efficient practice here, what do you think ?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...