Jump to content
Search Community

immediateRender demystified doc extend with set

RolandSoos 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

hmm, the video you linked to is for helping people with a very specific and somewhat common scenario of having competing from() tweens on the same properties of the same object. 

 

For TimelineLite.set() and TimelineMax.set() immediate render is set to false by default (as long as the start time isn't 0)

If a set() is scheduled to run at 4 seconds into the timeline it will not render immediately at a time of 0.

The engine is smart enough to know that a set() at 4 seconds should wait until its scheduled time.

 

Please change your demo to use this code:
 

TweenLite.set("#demo", {visibility:"visible"})
// it is important to set immediateRender:false when multiple from()-based tweens are animating the same propreties of the the same object.
var immediateRender = true; //switch to true to see the difference

var tl = new TimelineLite();
tl.set(".green", {opacity:0}, 0)
  .set(".green", {opacity:1}, 2)
  .set(".green", {opacity:0}, 4);

 

You'll see that the green item starts with opacity 0, switches to opacity 1 at 2 seconds and goes invisible again at 4 seconds all as expected.

There is no need to change the default value of immediate render on any of those set()s in this situation. 

 

 

  • Like 6
Link to comment
Share on other sites

Thanks Carl! Well, GSAP is too smart for me :) Sometimes in the past when I animated the same element on multiple timelines (not at once, but premade timelines) I stumbled into this. I didn't know that .set() which added to the start of the timeline is immediateRender:true and when it is added any other position immediateRender:false. I will keep it in my mind, thanks! :) 

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

@GreenSock I just learned an interesting fact related to this topic. If I set immediateRender:true on a .set() tween it works like a fromTo tween would work. The tween position on the timeline does not matter and GSAP renders the property instantly. I think this is right. The problem happens when I play again this timeline, the box will stay at x:0 instead of the x:100 from the immediateRender:true

 

In the following example, you can see that

  • the set() X starts with 100, then jumps to 1000, then jumps to 0, then 100. It should jump from 1000 to 100.
  • the fromTo() works as expected, it starts with x:100, then jumps to x:200 and then jumps back to x:100.

 

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

 

 

var originalTl = new TimelineLite({
  onComplete: function() {
    originalTl.pause(0);
  }
});

originalTl.set("div", { x: 100, immediateRender: true }, 3);
originalTl.fromTo("div", 0.0001, { y: 100 }, { y: 100 });

originalTl.set("div", { x: 1000 }, 3);
originalTl.fromTo("div", 0.0001, { y: 200 }, { y: 200, immediateRender:false });

originalTl.set({}, {}, '+=2');

 

 

 

Ps.: Yeah, I know this example makes no sense, it is just to illustrate the problem. I have nested timelines in my app and one of the nested timelines which has shifted position has a .set()  with immediateRender:true

Link to comment
Share on other sites

Hm, I read this a few times and looked at your demo and everything is working exactly as I'd expect. I feel like I must be misunderstanding your point. 

 

x starts at 0, then you put a set() call 3 seconds into the timeline to make it jump to 100 but since immediateRender is true, it also renders that immediately (at the time your set() call is evaluated). But that doesn't change the fact that the actual tween/set is positioned at the 3-second spot. So later, when you jump back to a time of 0, that's BEFORE the 3-second spot, thus the set() reverts to 0 as it should. Am I missing something? 

  • Like 1
Link to comment
Share on other sites

Well, your explanation sound right.

 

My misunderstanding comes from that I assumed setting immediateRender:true on a set based tween gives the same result as the fromTo based tween. But in real, the result is not the same.

 

Real use case:

I have several nested timelines and I can not place my .set() to the top of parent's timelines 0 position, so the set has a non zero position on the timeline. I wanted the use the advantage of fromTo's immediateRender:true, by knowing even if I place an immediateRender:true tween later on the timeline, I can be sure when the parent timeline starts to play again, my immediateRender:true tweens will sets their properties instantly. Here you check it: https://codepen.io/mm00/pen/MZMKdK?editors=0010

 

 

7 hours ago, GreenSock said:

x starts at 0, then you put a set() call 3 seconds into the timeline to make it jump to 100 but since immediateRender is true, it also renders that immediately (at the time your set() call is evaluated). But that doesn't change the fact that the actual tween/set is positioned at the 3-second spot. So later, when you jump back to a time of 0, that's BEFORE the 3-second spot, thus the set() reverts to 0 as it should. Am I missing something? 

 

Check this pen. It has nested timelines one for set tweens and one for fromTo tweens. At second run the set based timeline will differ from the fromTo based timeline.

See the Pen bOPEvO?editors=1010 by mm00 (@mm00) on CodePen

 

Link to comment
Share on other sites

Yeah, that was actually by design. I found this comment in my own code: 

 

Quote

tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from())

 

Also, to be clear, immediateRender:true does NOT mean that every time you rewind the parent timeline, those values will immediately render no matter where the child animation is placed on the timeline. immediateRender is only for literally the first render, when the animation is created. 

 

Does that clear things up? Is there something you can't accomplish with the current API? 

Link to comment
Share on other sites

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

 

This is the example what I needed to solve with a very short duration fromTo tween instead of the .set(). I'm not sure how it would be possible to solve if the parent timeline is not accessible for the code which creates the nested timeline.

 

 

Also I'm curious about the exception what you described. How would an example look like when a from* based tween with immediateRender: true does not render its values after the first render?

Link to comment
Share on other sites

  • 2 weeks later...

Sorry about the delayed response. I was heads-down on some new features for MorphSVGPlugin and as I'm sure you can tell, I'm circling back to your questions now :)

 

Your demo is behaving as I'd expect. #div2.opacity starts out as 1. You flip it to 0 in your nested timeline, and that set() records the starting value so that it can toggle it appropriately when the playhead moves forward/backward over it. So when the parent rewinds, it is correctly setting opacity back to 1. 

 

On 1/19/2019 at 4:12 PM, RolandSoos said:

How would an example look like when a from* based tween with immediateRender: true does not render its values after the first render?

 

Sorry, I don't really understand the question. Can you clarify a bit? I want to help - I'm just fuzzy about what you're asking ?

  • Like 1
Link to comment
Share on other sites

9 hours ago, GreenSock said:

Your demo is behaving as I'd expect. #div2.opacity starts out as 1. You flip it to 0 in your nested timeline, and that set() records the starting value so that it can toggle it appropriately when the playhead moves forward/backward over it. So when the parent rewinds, it is correctly setting opacity back to 1. 

 

Yeah, I think I still have confusion with immediateRender. 

The following two examples shows where my confusion comes:

 

#1 opacity gets the 0 value at create, but on replay it waits until the set position reached.

nestedTl.set("#div2", { opacity: 0, immediateRender: true });

 

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

 

#2 opacity gets the 0 value on the main timeline start for every replay too

TweenLite.set("#div2", { opacity: 0 });
nestedTl.set("#div2", { opacity: 0, immediateRender: false });

 

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

 

I had the wrong conception for imediateRender. As when the immediateRender is true it renders the properties instantly. Like a simple .set() would do. So I used to spare a call with immediateRender:true. But when the timeline plays again, it does not behave like when I set the values in a different call (#2).

 

Probably my confusion with immediateRender comes from the fact, that the immediateRender:true on from* based tweens work like I need and .set with immediateRender:true differs.

#3 opacity gets the 0 value on the main timeline start for every replay too

nestedTl.fromTo("#div2", 0.0001, {opacity:0}, { opacity: 0, immediateRender: true });

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

 

So if I want proper result for my scenario, I have to stick with the #2 solution and that will give good result combined with invalidate() like in this topic:

var t = timeline.time(); //store the current time in a variable
timeline.time(0); // seek back to position 0 which allow invalidate to read the proper values
timeline.invalidate().time(t); //set it back to that time immediately. 

 

---------------------------------------------------------------

9 hours ago, GreenSock said:
On 1/19/2019 at 11:12 PM, RolandSoos said:

How would an example look like when a from* based tween with immediateRender: true does not render its values after the first render?

 

Sorry, I don't really understand the question. Can you clarify a bit? I want to help - I'm just fuzzy about what you're asking ?

 

This question was related to:

On 1/19/2019 at 10:22 PM, GreenSock said:

Also, to be clear, immediateRender:true does NOT mean that every time you rewind the parent timeline, those values will immediately render no matter where the child animation is placed on the timeline. immediateRender is only for literally the first render, when the animation is created. 

 

 

Here is an example from* based example: 

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

You told that immediateRender in this example does not mean that the start value will be properly rendered when the parent timeline rewinds to position 0. But I do not see how your thought affect this example's rewind. Everytime I rewind the parent, Hello World gets opacity 0 no matter what.

Link to comment
Share on other sites

I think I understand what you're saying about the difference in behavior between fromTo() and set(), and I vaguely remember intentionally making things that way but I can't quite remember the exact reason (it was years ago). I don't think it'd be wise for me to alter the behavior now without a compelling reason, as it'd risk breaking functionality people have depended on for years. See what I mean? It sounds like you've got a grasp on things now, though, and you can get whatever behavior you need (right?) 

  • Like 1
Link to comment
Share on other sites

Yeah, my issues solved. And I'm pretty sure it would not be a good idea to change the current implementation. It was just very time consuming and frustrating to understand what happens and why. As you saw in the past weeks I had several edge cases and sometimes I was not sure what is the problem. There was code failures on my end or I had misconception or GSAP had a bug and it was really hard to say which was true :) (And it takes a lot of time to simplify a complex problem into a simple pen.)

 

I think ALL my issues solved (knock knock) and I hope nothing comes up in the next weeks :) Thank you for you and your team for the quick and accurate help! I really appreciate it! :)

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