Jump to content
Search Community

staggerFrom and From broken with requestAnimationFrame?

beliy333 test
Moderator Tag

Go to solution Solved by Carl,

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

For some reason when I use from or staggerFrom with requestAnimationFrame, the animation jumps and actually acts as if it's doing a "To" tween. When I use the code outside of my requestAnimationFrame, it works fine. Why is this? I need to use within a requestAnimationFrame because I trigger the tween when scroll is at a certain position and I need requestAnimationFrame to determine that position (I was advised that's the correct way to do it instead of attaching to scroll).


Here's my tween:

TweenMax.staggerFrom(".box", 1, { x:100, autoAlpha: .5}, .5);

I made a quick codepen demonstrating this issue.




See the Pen xZXLLV by anon (@anon) on CodePen

Link to comment
Share on other sites

  • Solution

Hi and welcome to the forums and Club GreenSock.


Thanks so much for the clear demo, it makes things so much easier for us.


from() tweens (or staggerFrom()) are a little tricky if you are creating them multiple times. In your case, even though you are using requestAnimationFrame your condition

if (distance < 64) {  console.log("make tweens")// happens many times
  TweenMax.staggerFrom(".box", 1, { x:100, autoAlpha: .5}, .5);

is still going to be true many times in quick succesion, and you do not want to be creating from() tweens many times. The solution is that you want to create your animation once and then it is safe to play it many times. Or you can create to() tweens (as you have found).


Let me explain.


a from() tween animates something from where you specify to where it already is.


Your tweens basically say animate these divs FROM 100 to where they are now (0).

The first time your condition is true you create tweens that start animating from x:100 to x:0

However, a few milliseconds later you run that same code again creating new from tweens.

Now you are creating tweens that animate from x:100 to x:98 (estimate, remember they only had time to move a little bit since the first tween was created)


So over time as you scroll a bunch of tweens are getting created that virtually move no distance at all.


If you use to() tweens you can create a bunch of those over time and they will always say, "move from where you are now to where ever I tell you". However this isn't really efficient. Since they all go to the same value, they will continue to run and get created until the end value is reached.


My solution for you is to create your staggerFrom() in a TimelineLite outside of your raf function and then just tell it play() whenever that condition is true.


var timeline = new TimelineLite({paused:true});
timeline.staggerFrom(".box", 1, { x:100, autoAlpha: .5}, .5);

function heroToNav() {
    var scrollTop = $(window).scrollTop(),
      elementOffset = $('.main-content-container').offset().top,
      distance = (elementOffset - scrollTop),
      box = $(".red, .blue")

      //when page top reaches content container
      if (distance < 64) {
      } else {


Please see:




Sidenote: I had to create a TimelineLite because TweenMax.staggerFrom() creates an Array of "loose" tweens and there is no way to really target them and control them as a whole. TimelineLite/Max solve that: http://greensock.com/timelinelite

  • Like 3
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...