Jump to content
Search Community

How to see if there are animations running?

Zokdok 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

We are in the process of migrating from Velocity to GSAP. And one of those things different is that Velocity adds a classname when it is handling an animation (`.velocity-animating`). We use this in our Selenium tests so it can wait for the animations to be done before trying to select certain elements on the page.

I was wondering how this can be achieved with GSAP (globally)? I really don't want to add classnames to every animation definition, but I would more see it as a setting for the TweenLite calls. I've been Googling and searching the forums/docs, but I can't find any reference to this.

Another solution would be to sort of disable TweenLite/TweenMax so animations are done instantaneous, this would not require to have us check for a classname or wait for animations to complete. Bad side of this would be testing without animations and thus not real world scenarios.

 

Thanks in advance,

Joeri van Oostveen

Link to comment
Share on other sites

Hello @Zokdok and Welcome to the GreenSock Forum!

 

There are number of ways to detect if an animation, tweens, or timeline is running using the GSAP isActive() method.

 

Found here in the GSAP Docs:

 

.isActive( ) : https://greensock.com/docs/TimelineMax/isActive()

 

  • .isActive( ) : Boolean

    Indicates whether or not the animation is currently active (meaning the virtual playhead is actively moving across this instance's time span and it is not paused, nor are any of its ancestor timelines). So for example, if a tween is in the middle of tweening, it's active, but after it is finished (or before it begins), it is not active. If it is paused or if it is placed inside of a timeline that's paused (or if any of its ancestor timelines are paused), isActive() will return false. If the playhead is directly on top of the animation's start time (even if it hasn't rendered quite yet), that counts as "active".
     

    You may also check the TweenMax.progress() or TweenMax.totalProgress(), but those don't take into consideration the paused state or the position of the parent timeline's playhead.

Example of usage:

 

See the Pen Pwzomo by GreenSock (@GreenSock) on CodePen

 

Hopefully that helps.. Happy Tweening! :)

 

 

 

  • Like 2
Link to comment
Share on other sites

Thanks, but this is on a single tween, not overall/globally.

From the testing point of view, I don't want the tests to know anything about specific animations, I just want to check if (for example when the element in question can't be found) an animation is currently animating and the testing framework simply has to wait for the animation to complete (thus: any animation, not a specific animation) before checking for the element again.

 

PS. I know see this has been counted as my first post since 2009 when I joined the forums :). Guess my history is gone from the forums ?.

Link to comment
Share on other sites

Hi again @Zokdok

 

isActive() can work on a single tween, or a timeline.

 

You can see in that codepen example that its using the tween variable that is referencing a single tween to check if its active (running)

 

var tween = TweenLite.to(box, 2, {x:endX, ease:Linear.easeNone});

if(!tween.isActive()){
    //only reverse the direction if the tween is not active
    // do something with tween
}

 

that could have happened when the site was migrated to a new forum system, sorry about the inconvenience for missing forum history.

 

Happy Tweening! :)

 

 

 

  • Like 2
Link to comment
Share on other sites

I understand the isActive(), but the issue is, I don't have access to any timeline of tween. I've tried if TweenLite fills the window._gsQueue with running animations, but no luck there. I want to check if there are any ongoing animations from outside the code.

 

For example, in our current driver, this code can be found:

public void WaitForAnimationsToComplete()
{
  //Wait for all velocity animations to complete
  _webDriver.WaitUntil(() => !_webDriver.FindElements(By.CssSelector(".velocity-animating")).Any());
}

 

I'm trying to see if there is a GSAP equivalent :).

Link to comment
Share on other sites

If you really need something that'll report if there are any active tweens, here's a function that I whipped together for you that is **not** officially supported, but should get you what you need (if I understand your goal correctly):

 

var root = TweenLite.to({}, 0.1, {}).timeline;
//reports whether or not there are active animations on the root timeline (global)
function isAnimating() {
    var child = root._first;
    while (child) {
        if (child.isActive()) {
            return true;
        }
        child = child._next;
    }
    return false;
}

 

So you'd just call isAnimation() anytime and it'll return a boolean. 

 

This doesn't take into account gaps inside nested timelines (meaning it'd still report true when the playhead is over the gaps), but I'm guessing you don't need that anyway. 

 

Happy tweening!

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

  • 1 year later...

I was wondering what is the best solution to check if there are any animations running on the page with GSAP v3.

With the globalTimeline now available, would it suffice to check with gsap.globalTimeline.isActive().

The previous solution did loop through all the children of the timeline checking is any of them isActive...

  • Like 1
Link to comment
Share on other sites

41 minutes ago, Zokdok said:

With the globalTimeline now available, would it suffice to check with gsap.globalTimeline.isActive().

The globalTimeline is always running (unless you do something specifically to make it stop). 

 

41 minutes ago, Zokdok said:

what is the best solution to check if there are any animations running on the page with GSAP v3.

Why do you need to do this? There may be a better way to structure things depending on your needs.

 

41 minutes ago, Zokdok said:

The previous solution did loop through all the children of the timeline checking is any of them isActive...

That's the best way that I can think of is to use 

gsap.globalTimeline.getChildren().filter(tween => tween.isActive())

If you just want to get tweens affecting DOM elements you could do this instead:

gsap.getTweensOf("*").filter(tween => tween.isActive())

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

The use case is to allow tests to check if the application is in an idle state, i.e. no animations are moving panels in/out etc, before continuing and trying to click things that are animating or in things that are animating.

I must say the use case is somewhat obsolete now, as I now do a timescale of MAX_SAFE_INTEGER on the globalTimeline when I detect the CI environment (actually, when prefers reduced motion: reduce is detected). But the code I currently have, is still hit by some of the older/yet to be translated tests so it would be nice to at least make it work.

Link to comment
Share on other sites

1 hour ago, Zokdok said:

The use case is to allow tests to check if the application is in an idle state, i.e. no animations are moving panels in/out etc, before continuing and trying to click things that are animating or in things that are animating.

Generally speaking it's better to keep track of the animations that are relevant and only check those. Theoretically looping through all animations could be intensive but in the vast majority of scenarios it's probably fine. We just really like making things performant here :) 

Link to comment
Share on other sites

In this case, the code to check if animations are running is not something being called during normal use, so the performance cost is acceptable. We're moving away from this construct anyway.

 

When I look at the documentation for the `globalTimeline`, it mentions it is of type Timeline, and when I look up the `isActive()` in Timeline, it is stated the `isActive()` would return `true` only when there is a running animation. Maybe it is worth mentioning in the `globalTimeline` docs, that it differs from the Timeline behaviour?

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