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

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

×