Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
mdolnik

How to find out whether Animation is currently playing in reverse with yoyo=true

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

Is there any way to find out whether an animation is playing in reverse at any given point when yoyo=true and repeat=-1 ?

 

I know there is the method myAnimation.reversed(); but as the docs say: This value is not affected by yoyo repeats

Link to comment
Share on other sites

I'm also not sure if OnComplete is ever called in a yoyo infinite-repeats situation so I just settled for something like this:

slideReversed = false;

slideTL = new TimelineMax({onComplete:changeReversed, onReverseComplete:changeReversed });

function changeReversed(){
	if(slideReversed){
		slideReversed = false;
	}else{
		slideReversed = true;
	}
	slideTL.reversed(slideReversed);
}

Link to comment
Share on other sites

Hi,

 

onComplete is never called on a repeating tween.

 

And yes, a tween that is yoyo-ing still has its playhead moving forward and like you found in the docs... is not ever reversed. Determining whether the tween is in a forward or psuedo-reversed iteration can be determined by assessing the animation's totalTime, totalDuration and duration of repeatDelay (theres a formula floating around the forums which I'll look for)

 

Regardless, your solution is quite good. Toggling the reversed() state can be achieved a little simpler though:

slideTL.reversed(!slideTL.reversed())

see it in action:

 

http://codepen.io/GreenSock/pen/tbCBc

 

And also, you could use the same technique on a TweenMax or TimelineMax

  • Like 3
Link to comment
Share on other sites

  • 2 weeks later...

Stumbled across this looking for a similar solution, ended up creating this function:

 

    var playBackwards = function(timeline) {
      var retval = false;


      retval ^= timeline.reversed();


      if (timeline.yoyo()) {
        retval ^= timeline.totalTime() / (timeline.duration() + timeline.repeatDelay()) % 2 > 1;
      }


      return !!retval;
    };

 

Perhaps this should be brought into GSAP itself.

Link to comment
Share on other sites

I think this method is a bit more bullet-proof, as it factors in nesting (like if you nest a reversed tween inside a reversed timeline that's in a reversed timeline, etc.):

 

EDIT: The function was revised in a later post...scroll down for a better one.

function isReversedGlobally(animation) {
	var timeline = animation.timeline,
		reversed = animation.reversed(),
		totalTime = animation.totalTime(),
		cycleDuration;
	//loop through ancestor timelines up to the root and determine the global reversed state
	while (timeline) {
		if (timeline.reversed && timeline.reversed()) {
			reversed = !reversed;
		}
		timeline = timeline.timeline;
	}
	//if the animation is repeated and yoyo'd and not finished, determine whether or not it's in one of its yoyo's.
	if (animation.repeat && animation.yoyo() && animation.repeat() && totalTime < animation.totalDuration()) {
		cycleDuration = animation.duration() + animation.repeatDelay();
		if (((totalTime / cycleDuration) | 0) & 1) {
			reversed = !reversed;
		}
	}
	return reversed;
}

So then if you want to know if it's playing backwards in a global way, you can just check: 

if (isReversedGlobally(yourAnimation)) { ... }

Is that what you were looking for? 

  • Like 1
Link to comment
Share on other sites

@GreenSock interesting: I'd overlooked nesting. I haven't tested that code, but it looks to me as though parent timelines could also be in their *yoyo state* and your function doesn't consider it...?

Link to comment
Share on other sites

Excellent point - here's an even more concise function that factors in all ancestor timelines and their yoyo states:

function isPlayingBackwards(animation, globally) {
	var reversed = animation.reversed(),
	    totalTime = animation.totalTime(),
	    cycleDuration;
	if (animation.repeat && animation.yoyo() && animation.repeat() && totalTime < animation.totalDuration()) {
		cycleDuration = animation.duration() + animation.repeatDelay();
		if (((totalTime / cycleDuration) | 0) & 1) {
		    reversed = !reversed;
		}
	}
	if (globally && animation.timeline && isPlayingBackwards(animation.timeline, globally)) {
	    reversed = !reversed;
	}
	return reversed;
}

Notice you can check its local or global state by using that second parameter. Nice and flexible :)

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