Jump to content
Search Community

staggerTo on master timeline, with nested tweenMax

processprocess 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

Thanks Jack!


This makes a lot more sense and is way more readable. However It's less performant than what I was doing before and there's visible jank when this is implemented in my project.


Before implementing the stagger as a gsap timeline, I was running the array through a set timeout that would stagger the sets before feeding them to a function. This gave a smoother frame rate in my project.


Here's a codepen of the way I was doing this before, which is the most performant solution i've found thus far:

See the Pen BWvLPG?editors=1010 by philipbell (@philipbell) on CodePen


I need a callback function to know when the animations are all complete.

That's a main reason why I was hoping the gsap timeline would work for this.

It's possible with promises but it's looking a little crazy to me:

See the Pen gmZLOZ by philipbell (@philipbell) on CodePen


Is there another way to get the callback when all animations are complete without using a gsap timeline?

Link to comment
Share on other sites

I'm curious why you think that technique is more performant. How are you measuring? 


I'm pretty confident that when you start pushing things harder, the setInterval() or setTimeout() will start to fall apart. The nice thing about centralizing everything in GSAP is that there's a single requestAnimationFrame loop that drives EVERYTHING, whereas if you start doing a bunch of setIntervals or setTimeouts, it's kinda like creating another clock each time. If you've got 500 clocks going, that can get a lot more expensive than just one RAF that's looping through a linked list of 500 objects. At least that has been my experience. 


Also, the way my brain works, this would be a more intuitive way for me to structure things:



One function to handle a single left/right set animation, and another that weaves those together in a bigger group. Nothing wrong with the way you're doing it - my brain just works differently :) 

  • Like 2
Link to comment
Share on other sites

I just wrote about using promises here...



But it's mostly about executing one promises at a time. To aggregate multiple promises into one, simply pass in an array of promises to Promise.all().

Promise.all([promise1, promise2, promise3]).then(() => console.log("done"));


See the Pen adcf67a87861ef26dd8471654c3eb116?editors=0010 by osublake (@osublake) on CodePen



  • Like 2
Link to comment
Share on other sites

Hey Jack!


Thanks for sharing the sample. It's awesome to see different angles on solutions. 


I understand your clock example. I thought one clock would be better too, but when pushed, set timeout is more performant in this case.

I'm measuring using the timeline in Chrome Dev Tools. I'm capturing 3 animation cycles. Screenshots:



long frames throughout. Visible jank. 




some long frames but they aren't visible. It looks smooth.


Do you know more precise measuring tools? I want to keep a closer eye on this while I'm building.


Blake thanks for the promise references!

Using a promise all makes way more sense for this, I'm going to try to write this that way.



Link to comment
Share on other sites

Hmm, I'd have to see the apples-to-apples comparison code-wise to investigate what's causing the performance difference. It sounds very odd to me that you'd somehow see a slowdown simply by scheduling your tweens (in a timeline). I suspect something else is at play. 


If you're really concerned about performance, typically 90%-99% of the bottleneck has to do with rendering performance in the browser (totally unrelated to GSAP), so you might want to try using PIXI.js (canvas) or something like that. Rendering a lot of DOM nodes can be expensive whereas canvas is just a blob of pixels. Nothing "wrong" with using DOM nodes at all, and sometimes it makes the most sense. But if you're running into performance issues, <canvas> might be worth experimenting with. 

  • Like 3
Link to comment
Share on other sites

I'd second a vote for PIXI.js.


Blake had talked about it for quite some time, but I finally started diving into it a few weeks ago. I'm blown away with its performance. You can push loads of sprites around without even breaking a sweat. It plays nicely with GSAP too.


It's pretty easy to pick up the syntax. Plus, Blake has a $1.00/answer service if you need help.  ;)


Happy tweening


  • Like 2
Link to comment
Share on other sites

Hello processprocess


If you add rotation: 0.01 in all tweens that are animating the x property, that will help. That will allow GSAP to trigger transform matrix3d(), instead of what its using now transform matrix(). It should be much smoother since using matrix3d() or translate3d() triggers hardware acceleration.


Plus that slight rotation: 0.01 helps with a browser translation bug in Firefox, IE11, and MS Edge to translate in x (translateX) smoother. That browser bug causes really bad jank (lost frames) when translating x or y using matrix() or translate().


Try testing again with google dev tools and without google dev tools to see the improvment. Also keep in mind the chrome dev team recommends that you must be in private browsing mode when testing performance so you don't skew results.


When i added the slight rotation it translated like butter in Firefox, IE11, and MS Edge.. even Chrome was more buttery.


Happy Tweening :)

  • Like 2
Link to comment
Share on other sites

Thanks guys! 


Jack -  

It's likely that something else is at play. 

I agree with you and PointC, a better rendering engine is the way to go. 


PointC -

that's awesome to hear. I've seen amazing stuff done with PIXI.js 

Blake's answering service is about to make a lot of money lol.

Do you feel like you need a solid foundation with canvas to get running with pixi.js?


Jonathan - 

I'm going to try that out right now, thanks!

Link to comment
Share on other sites

I wouldn't say you'd need much canvas knowledge going into it. I've been entirely focused on SVGs lately and had almost no experience with canvas before starting PIXI and it's all been going well for me. It freaked me out a little when I did my first GSAP tween rotation in PIXI, but failed to realize rotation should be in radians rather than degrees. It took me a minute to figure out why that sprite was spinning so much.  :lol:  It just requires thinking a bit differently. There are no elements - only objects.  You're gonna love the GPU acceleration. 


Once you follow a few tutorials and reverse engineer a couple of the examples on the PIXI site, it all makes sense pretty quickly.


Here's the examples page.



There is also a GSAP PIXI plugin:



Be careful though - that plugin has a bug causing tweens in a timeline to be skipped. Blake said he was going to ask Jack about it, but I'm not sure if he's had a chance to do that yet.


Good luck and happy tweening.


  • Like 2
Link to comment
Share on other sites

Thanks PointC!


I'm working on transferring my project to pixi. I have my elements animating position and it's INSANELY fast and smooth. Even with 30x the elements.


position and scale properties seem to be working great with gsap tweening. I'm running into problems with color though, the colorPropsPlugin works for tints on the background shape, but I have black pngs with transparent backgrounds that I need to tween the color of also.


The only way I've found to modify the color of the black pngs is to edit their colorMatrix.

I wonder if there's a way to tween the color matrix. Or maybe there's a better way?

  • Like 2
Link to comment
Share on other sites

@PointC, I hadn't heard anything about a bug in that plugin. Any chance you (or Blake or anyone) could provide a demo? I can't imagine why putting the tweens in a timeline would suddenly cause them to be skipped. I glanced at the code and didn't notice anything odd. 

Link to comment
Share on other sites

Hey Jack,


I should elaborate a bit. It doesn't skip the tween, but the second tween in a timeline seems to kill the first tween if they overlap at all. A further oddity is that it only happens on the first run. On my first day with PIXI I made a quick demo just to make sure I was understanding the syntax and the plugin was working correctly and I discovered the issue:


See the Pen 1d4005c78b83d843f10f38067d179d0c by PointC (@PointC) on CodePen


You can see that the sprite should scale and rotate at the same time, but on first click, the rotation tween doesn't work. All clicks after that work fine. I thought the first tween was getting skipped, but Blake forked my demo and expanded the experiment a bit:


See the Pen 4f433f008b6a7f5f38ec2032065cd7b5 by osublake (@osublake) on CodePen


He's got some good notes about what's happening. You can see it's not skipping the first tween, but as soon as the second tween in the timeline fires, it seems to kill the first one. Again, only on the first run. A bit strange...




Have you tried tinting? If you look at Blake's fork of my demo above, you can see how easy it is to tint the dog sprite. I guess that wouldn't work too well with black pngs, but if they could start as another color you could tint them black.

  • Like 1
Link to comment
Share on other sites

IIt freaked me out a little when I did my first GSAP tween rotation in PIXI, but failed to realize rotation should be in radians rather than degrees. It took me a minute to figure out why that sprite was spinning so much.  


I forget that sometimes, especially when it comes to the BezierPlugin if you want it to auto rotate. You can see how to do it here. Pixi also has some constants you you can use to convert between radians and degrees.


  • Like 2
Link to comment
Share on other sites



Tinting works great for white objects. The pngs start as black though and i'm pulling them from an API so I can't color them by hand.


I can use color matrix to make them white, but then I tried to add tint and it's having no effect. 


You would need to use a RenderTexture for that because the filter is being applied after the tinting. Using a render texture, you can apply a filter to something render it to a texture, and then have other sprites use that texture. Check out this demo. Only the robot in the top-left corner has the twist filter applied to it. 

See the Pen ?editors=0010 by osublake (@osublake) on CodePen


And you can animate the color filter...

See the Pen ?editors=0010 by osublake (@osublake) on CodePen


You can even animate the matrix directly using the EndArrayPlugin...

See the Pen wJNgoW by osublake (@osublake) on CodePen


And you can tint your textures white using the CanvasTinter...

See the Pen 3b4d397fc631ed7660857260943247e0?editors=0010 by osublake (@osublake) on CodePen





  • Like 3
Link to comment
Share on other sites

@PointC, thanks for the details about the problem with that plugin. I took a peek and it's due to the fact that they listed every property as an "overwrite", meaning that for example a "rotation" tween would overwrite a "scaleX" tween on the same target (and any other property). 


I took a crack at rebuilding my own version of that plugin with the following enhancements: 

  1. Fixes the overwriting bug
  2. Defines rotation in degrees instead of radians (it does the conversion internally). I think this is much more intuitive. Agree? 
  3. Permits you to use any of these properties: x, y, scaleX, scaleY, scale, anchorX, anchorY, anchor, pivotX, pivotY, pivot, skewX, skewY, tileX, tileY, tilePositionX, tilePositionY, tileScaleX, tileScaleY, tileScale, or any other standard property. As a convenience, "positionX" and "positionY" are aliases for "x" and "y". 
  4. Supports ColorMatrixFilter values: saturation, hue, colorize, contrast, brightness, or pass in your own custom ColorMatrixFilter instance. 
  5. Supports BlurFilter values: blur, blurX, blurY.
  6. Supports color-related properties like tint, lineColor, and fillColor. In fact, you can define the colors in almost any format you want, like: "red" | "#F00" | "#FF0000" | "rgb(255,0,0)" | "hsl(0, 100%, 50%)" | 0xFF0000. You can even do relative HSL values! “hsl(+=180, +=0%, +=0%)”.
  7. Supports function-based values
  8. Supports NPM/CommonJS/AMD
  9. Smaller, more efficient code

I tossed it up at https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/PixiPlugin.min.js for testing and I recreated your demo using it here: 






Got any other ideas for enhancing it? 

  • Like 2
Link to comment
Share on other sites

That is really cool Jack!  B) 


You're always going above and beyond with the service at GreenSock. 


Yes - the rotation in degrees is just more intuitive for me as it's how I work in GSAP, AE and C4D. That's a terrific addition. I'll play with it and see if I have any other ideas to enhance it. I'm guessing other members will like this and may have ideas too. I'm seeing the word PIXI in more threads around here so I think this is gonna be quite useful to many people.


Thanks very much for fixing this for us.


  • Like 1
Link to comment
Share on other sites

  • 2 months later...

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...