Jump to content
Search Community

Can Timeline be dynamically 'refreshed' to recognize dynamically removed and added animation targets?

JoeTierney test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

I have a Timeline working fine on a hierarchical tree (DOM document) in which selected classes of SVG elements are animated. However, the tree is collapsible, and when a node is collapsed, the element that is animated in that node is removed from the DOM. That's Ok, no problem. But when that node is expanded again via a mouse click on its parent, the element gets added again to the DOM, but the Timeline does not, of course, act upon the newly-created element to animate it.

 

Is there a way to make the Timeline aware of elements that are dynamically created and whose class does fit the Timeline target parameter?

 

I am hoping that I won't need to actually create a new Timeline to animate these dynamically created elements - for then I would have multiple Timelines targeting the same class of elements, and that seems problematic to me.

 

I have tried a number of things to solve the issue, but to no avail. I either get what appears to be multiple instances of the Timeline colliding with each other, or else new elements animating as desired while existing elements (that have not been disturbed) not animating at all after some other node has been dynamically created.

Link to comment
Share on other sites

Without seeing the context or a minimal demo, it's tough to say precisely how I'd engineer things, but at the most basic level it seems appropriate to just:

yourTimeline.killTweensOf(".removedStuff");

To dump the now-irrelevant tweens, and then only create new tweens for the new elements you're adding in, and put them directly into the existing timeline at the appropriate time using the position parameter

yourTimeline.to(".newStuff", {...}, 0.5);

You could even have a function that handles animating the various types of elements, so it's all organized nicely and you call the appropriate function to have it spit back an animation that you plop into your timeline or whatever. Lots of options. 

 

If you still need some help, maybe create a minimal demo and explain where the rough spots are for you and we'd be glad to chime in. 

  • Like 1
Link to comment
Share on other sites

I tried the suggestions made but I could not get them to work properly. I think that's due to the very fluid nature of the DOM in this scenario.

 

However, I sort of have this working fairly well by using two separate Timelines - one for the class of elements that have not been dynamically removed/re-added, and another Timeline for those that have been. Whenever I remove an element, and then it gets re-added, I give it a class different from what the static elements have, and animate these new elements with the 2nd Timeline. This works pretty well except for one issue. It looks like my two Timelines are not running simultaneously, but rather sequentially with respect to each other. The animations in the first Timeline will run, then those in the second Timeline run, instead of both groups of animations running at the same time. The longer the duration I set for each Timeline, the more noticeable this issue is, of course. I have them defined separately, like this:

<script>
            var tl = gsap.timeline({repeat: 0});
            tl.eventCallback("onComplete", triaRefresh);
            var tl2 = gsap.timeline({repeat: 0});
            tl2.eventCallback("onComplete", trianewRefresh);
</script>

And in my two separate onComplete callbacks I simply do tl.restart() and tl2.restart() respectively so that the animations appear to run continuously for each group of elements.

 

I start each Timeline like this, for example:

 
            gsap.set(".tria", {transformOrigin: "50% 65%", scale: 0.9});
            tl.to(".tria", {duration: .5, rotation: 360, ease: "bounce"});

So except for the issue I mentioned above where the two Timelines seem to run sequentially to each other rather than simultaneously with each other, this is working. I don't know if there's a better, cleaner way to do this - perhaps nested Timelines? I'm a newbie to gsap so I'm still feeling my way thru this.

 

 

 
Link to comment
Share on other sites

It's super difficult to troubleshoot blind - would you be able to provide a minimal demo? Please don't post all your code - just see if you can isolate the one problem with as little code as possible and we'd be glad to help. Something tells me you're just structuring things in a funky way. Once we see the minimal demo, we'll be able to offer a better answer. 

  • Like 1
Link to comment
Share on other sites

Understood - by way of explanation, this is a d3.js collapsible tree, which of course significantly complicates things. It's not feasible to try to construct a minimal example because all the present code is needed in order to get the collapsible functionality. I did not think it would be fair to dump that on you. So that's why I have instead tried to pose questions and limit the scope of what I'm asking help on. I know that hampers things.

 

I'm doing more experimentation, and it seems that reusing the same Timeline isn't working as expected. Using the .killTweensOf() method to remove the animations on elements that are deleted, then doing a .to(".class", ...) to get animations going again for elements that have been added, results in a Timeline that animates the undisturbed elements first, then the newly-added elements afterward, rather than all simultaneously. And each time I collapse-then-expand the tree, the time lag between the two groups gets longer. It's as if the Timeline is getting expanded via 'dead time' segments being inserted between the tweens for the groups of elements. Nothing I have tried resolves the issue. I am tempted to not reuse the same Timeline, but instead create an new one to hold the tweens each time the user collapses/expands some part of the tree. But I'm not quite sure how to implement that w/o making a garbage collection nightmare. I will keep at it to see if I can make any progress and report back. Any suggestions, no matter how oblique (due to the limited information on your side) would be appreciated. Thanks!

Link to comment
Share on other sites

  • Solution
2 hours ago, JoeTierney said:

then doing a .to(".class", ...) to get animations going again for elements that have been added, results in a Timeline that animates the undisturbed elements first, then the newly-added elements afterward, rather than all simultaneously.

Sounds like you just forgot to use the position parameter to put them where you want (I assume at the beginning of the timeline?) like I showed in my first answer. By default, the insertion point for any new animations is at the END of the timeline. But it's super easy to put them wherever you want. 

 

2 hours ago, JoeTierney said:

I am tempted to not reuse the same Timeline, but instead create a new one to hold the tweens each time the user collapses/expands some part of the tree. But I'm not quite sure how to implement that w/o making a garbage collection nightmare.

In my experience, people are way too worried about garbage collection and they tend to try reusing instances when that just makes things more cumbersome. Not always, of course - at times it can be very useful to reuse things. But in practical usage, unless you're literally creating 5,000+ new animations per second or something, you'll probably never notice any GC issues or slowdowns at all. We built GSAP to be very GC-friendly and highly performant. 

 

It sounds to me like you may just be misunderstanding how timelines work or how to place animations into them the correct way. 

 

Again, without a minimal demo it makes it very difficult for us to offer solid advice or troubleshoot your issues but hopefully this gets you moving in the right direction. 

 

Happy tweening!

  • Like 2
Link to comment
Share on other sites

Thanks so much for the direction!

 

I paid attention to the position parameter as you suggested and now I have this working much better. I'm also going to go ahead and use separate Timelines to make this cleaner.

 

I have to say that this help forum is the most responsive, educational and problem-solving forum I've seen for a long time - kudos to GreenSock and to the senior members here. Special thanks to you, Jack!

 

I'm just getting started with GreenSock, but what a carefully engineered, performant and downright beautiful product!

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, JoeTierney said:

I have to say that this help forum is the most responsive, educational and problem-solving forum I've seen for a long time - kudos to GreenSock and to the senior members here. Special thanks to you, Jack!

I love hearing that - we put a lot of effort into making these forums a special place where everyone is treated with respect (no "dumb" questions or arrogant smack-downs) and we do our best to make sure all GSAP-related questions get answered. It's nice when someone like you notices the different vibe around here and takes time to comment on it. 

 

1 hour ago, JoeTierney said:

I'm just getting started with GreenSock, but what a carefully engineered, performant and downright beautiful product!

Favorite comment of the day. Thanks @JoeTierney!

 

Good luck with the project. 

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