Jump to content
Search Community

tweenFromTo doesn't trigger tweens that have not yet been reached by normal .play()

annam 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

Hello,

 

I'm having an issue with tweenFromTo.

 

I create a timeline, onto which I add some tweens, some with delay. I play() this timeline, but it might be paused before completion.

 

Then, I use the tweenFromTo() method to manually reverse the timeline back to 0.

 

If all the tweens start playing before the timeline is paused, then this works perfectly. I can use the tweenFromTo() to reverse the timeline from any seek position with no problems, even if the tweens had not originally completed before pausing the timeline.

 

However, if I pause the timeline before some of the tweens have started running, and then use tweenFromTo() on the timeline with a from time after the pause time, where other tweens are expected to run, then these extra tweens don't run, even though they are added to the timeline. It's like the delayed tweens are not there at all.

 

Here's a JS fiddle:

 

http://jsfiddle.net/annam/Jz69s/

 

(Using reverse() is not an option for me, and the same goes for restart(), which is why you will see that I'm rebuilding the timeline every time in the jsfiddle. Notice that I'm retrieving the seek position of the latest timeline, to reverse seamlessly, but the tweenFromTo always uses the first timeline that was created)

 

The expected transition is:

 

On "go!" mouseover:

- Top and Left is transitioned, duration 1 delay 0

- Background color is transitioned, duration 1 delay 1 (as soon as top and left are done transitioning)

 

On "go!" mouseout, the mouseover transition is manually reversed, but from the point where the last mouseover transition has left off

 

so if the mouseover transition had time to complete:

- Background color is transitioned, duration 1 delay 0

- top and left is transitioned, duration 1 delay 1

 

but if the mouseover transition only run for 1.5 seconds:

- Background color is transitioned, duration 0.5 delay 0

- top and left is transitioned, duration 1 delay 0.5

 

 

To see the issue:

 

Mouse over "go!" and keep the mouse on "go!" for 2 seconds, until the transition completes. Then, mouseout. Try to mouseover and mouseout again, without waiting the full 2 seconds each time - eg wait for 0.5 seconds, then mouseout, then mouseover again for 1.5 seconds, then mouseout. This functionality is correct.

 

Rerun the JSfiddle

 

Now Mouse over "go!" but only keep the mouse on "go!" for less than a second, before the background color starts tweening. Now try to mouseover and mouseout repeatedly again, and also try to leave the mouse over for the full 2 seconds. You will notice that the background color never transitions back to light gray, it is stuck to the dark gray.

 

 

This seems to happen because the original timeline never completed during the first, normal play(). However, when initializing, the tweens are there! 

 

could you help me understand why this is happening? it doesn't seem to be the desired functionality, what if i've added the tweens to the timeline but don't want to run it sequentially?

 

Thanks a lot!

Link to comment
Share on other sites

Okay, I see the issue. It's not a problem with GSAP (as far as I can tell) - it's just a logic issue with your code, although I don't blame you for being a bit confused by the behavior. Let me explain...

 

One of the really nice things about GSAP and its to() behavior is that you can create complex sequences that say "animate to these values....then these values...then these" and it doesn't force you to define the starting values up front - it'll read them when the tween NEEDS them (typically when the tween renders for the first time). Of course you can define the starting values if you want, using fromTo() instead of just to(). 

 

Anyway, in your case, you've got a tween set up later in your timeline and when you rollout quickly and basically reverse the timeline, that tween never even started (no rendering at all), so the starting values didn't get recorded. Again, this is by design. Then, later, you create ANOTHER tween that does the same thing (animates backgroundColor to #333) and that runs fine, but then you try to go back to the ORIGINAL timeline (with the tween that never rendered even once) and ask it to start from a particular spot. When it does, it says "okay, this tween needs to go from the current values (#333 in this case) to a final value of #333..." so obviously it looks like it's not doing anything but it actually is doing its job correctly. 

 

See the issue? 

 

The solution is easy. You can force the timeline to record all its starting values by simply moving the virtual playhead to the end once and then jumping back to the beginning. Specifically:

t.seek(t.totalDuration()).play(0); 

Or you could use fromTo() tweens instead so that the starting and ending values are hard-coded.

 

Here's the revised (and somewhat simplified) code from your jsfiddle:

var ts = [];

$('#trigger').mouseover(function(){
	var t = new TimelineMax({
		paused: true
	});
	t.to('#box', 1, { top: 100, left: 100}, 0);
	t.to('#box', 1, { backgroundColor: '#333'}, 1);
	t.seek(t.totalDuration()).play(0); //this causes all of the tweens to instantiate so that the starting/ending values are recorded.
	ts.push(t);
})
.mouseout(function() {
	var time = ts[ts.length-1].time();

	for(var i =0; i<ts.length; i++) {
		ts[i].pause();
	}

	ts[0].tweenFromTo(time, 0);
});

Lastly, I'd highly recommend using the latest version of the GSAP files. I noticed you're using a pretty stale version.

 

Happy tweening!

  • Like 1
Link to comment
Share on other sites

thanks for the explanation, sounds right, and the fix works like a charm :)

 

i was also wondering what you think of the performance overhead that will be caused by instantiating a new timeline instance every time we want to trigger the animation, and possibly storing these timeline variables in an array as in the sample code (although we will try to kill and delete as many as possible for optimization) - do you think it could create a performance or memory problem?

 

again, thanks a lot :) really good support! :)

Link to comment
Share on other sites

Oh, I wouldn't worry about it unless you're literally creating thousands or something in a very short amount of time. The system is generally very efficient and optimized, plus when animations hit performance bottlenecks, it is rarely JS execution that's the culprit (at least with GSAP) - it's graphics rendering in the browser. So my recommendation would be to not worry so much about creating a few extra instances of timelines, and focus your energy on identifying any true performance bottlenecks and squash those. Feel free to do some experiments/tests. Let us know if you find anything odd. GSAP has been put under very heavy pressure by some of the biggest brands and most aggressive gaming companies and it handles things quite well. 

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