Jump to content
Search Community

FromTo seems to ignore immediateRender = false when nested

Skid X 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


as you can see in the Codepen example, I'm seeing different behaviors when using fromTo() nested in two timelines.

First case (work as expected):

var t1 = new TimelineMax({paused: true, repeat: 2});
  .to("#redBox", 1.5, {x: 300})
  .fromTo("#redBox", 1.5, {y: '+=100'}, {x: '+=250', immediateRender: false}, "+=0.5");

Second case (work as expected only once, then from the second iteration it seems to not reset the "from", ignoring "immediateRender = false" config value).

var t2 = new TimelineMax({paused: true, repeat: 2});
  .to("#blueBox", 1.5, {x: 300})
  .add(new TimelineMax().fromTo("#blueBox", 1.5, {y: '+=100'}, {x: '+=250', immediateRender: false}), "+=0.5");

Is there something wrong in my setup or is it a bug?

Thanks in advance.

Link to comment
Share on other sites



Thanks for the CodePen demo. It is helpful. 


However, since your both your fromTo()'s are malformed its hard to decipher what the intended behavior is and how the outcome varies.


You said the first timeline (red) runs as expected, but I don't see the redbox's y animating from y:"+=100", it actually seems to jump to y:100.


When creating a fromTo() tween you need to set both the from (start) and to (end) values for all properties.



In your case you are doing:

.fromTo("#redBox", 1.5, {y: '+=100'}, {x: '+=250', immediateRender: false});

notice how you only have y in the from vars and only x in the to vars?


You need to do something like this

.fromTo("#redBox", 1.5, {y: '+=100', x:someStartValue}, {y:someEndValue, x: '+=250', immediateRender: false});

Please edit the pen accordingly and let us know if a problem remains. 

  • Like 1
Link to comment
Share on other sites

As you suggested, I have updated the pen without relative values and with x and y values on both begin and end states of fromTo() method, so it is more clear the issue: as you can see, the blue one plays as the red in the first loop iteration, while it does not reset the y correctly on the next iterations. Also when you restart it, it starts from the wrong y position, while the red restarts correctly.

Link to comment
Share on other sites

Hi SkidX,


Thanks a lot for putting in the extra effort to refine the pen. It really did help.

The result and its "unexpected" behavior is now very clear.


I'm not entirely sure it is a bug but here are some thoughts that might explain why this is happning.


Setting immediateRender:false is helpful when when any from()-based tweens (from(), fromTo(), staggerFrom() etc) are scheduled to run in the future on conflicting properties. In your scenario you have 2 tweens on the same element that both affect the x property. This makes it necessary to set immediateRender:false on the fromTo() tween as you specifically do NOT want it to interfere with the first tween (good job BTW).


In your first timeline (t1) the parent timeline had tweens added directly to it. t1's fromTo() method added a tween at a startTime() of 2 (1.5 (duration of first tween) + 0.5 (offset) ). A tween with a startTime(2) is clearly in the future, and with immediateRender set to false, will certainly not render until t1 reaches time(2).


However, your second timeline (t2) creates its fromTo() tween a little differently.


You are creating an anonymous (un-named) TimelineMax inside t2's add() method. Lets just call this sub-timeline Anon. When Anon is created he has no idea that he is going into a parent timeline. 


Anon's FIRST tween is a fromTo() tween with a startTime of 0. So remember, immediateRender:false really only helps us when tweens are scheduled to run in the future. So looking at things from Anon... a tween with a startTime of 0, is just going to render for the first time when it is normally planned to run, so really immediateRender:false has no bearing on the tween in this case.


Also keep in mind that once you create a timeline and it renders for the first time, there really is no way of rewinding to a time of less than 0. The engine doesn't track properties of elements before they were placed in a timeline.


Now we get to the part that since Anon is nested inside of t2, it isn't scheduled to run (or render) until t2. is 2 seconds into its animation.


So why does it appear to work the first time and not the second time. 


I believe it boils down to the fact that since the fromTo() is the first tween in a timeline AND the only recorded value for y is going to be y:100. And this happens as soon as Anon plays for the first time. However, going back in time BEFORE Anon starts (by rewinding t2) does not somehow reset the y values on blueBox. t2 and Anon only know of blueBox having a y of 100... no value before that. 


So in this case, a fix would be to simply offset the start time of your fromTo() tween inside Anon by a very very small amount like so:



  .to("#blueBox", 1.5, {x: 300})

.add(new TimelineMax().fromTo("#blueBox", 1.5, {x: 300, y: 100}, {x: 550, y: 100, immediateRender: false}, 0.00001), "+=0.5");





By scheduling the fromTo() "in the future", now Anon will record a value that existed before the fromTo runs.


So in summary.


Is this a bit confusing? perhaps ;)

Is it a bug? I don't think so, but I will seek further input.

Is there another way to "work around it", we'll see.


Hopefully this makes some sense. We will study this more and give more details if they arise. 

Please be patient though as today is a federal holiday.


Thanks again for the pen!

  • Like 2
Link to comment
Share on other sites

hi, thanks for the answer, no problem for the timing, no hurry, it's not a blocking issue for me.
Yeah, during my experience with your libraries I've seen that using some +0.0001 offset helped me to solve some corner cases quickly.

In this specific case, I'm still thinking that it is a bug because also without considering the first example with red block, in the second one we have different behaviors on the loop iterations after the first one and this is not what a user expects in any case. However it's just my humble opinion, I don't want to push you in any way, my aim is just to let you know that this happens, then you will see how to handle it in the best way :)


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