Jump to content
Search Community

Running the same timeline again but with new content (onclick)

Chromium test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

14 hours ago, Chromium said:

I was thinking that on subsequent clicks, I can revert parts of the timeline, kill the timeline, and then re-initialize it with brand new tweens... but maybe this is over-complicating things rather than making them simpler haha.

Yeah, that definitely seems like it'd be over-complicating things. :)

 

14 hours ago, Chromium said:

Ironically, that is literally why I started this post... because I felt like GSAP should be so easy to use, but it's giving me such a hard time nearly every time I've had to deal with spam clicks, so I must be doing something very wrong or missing something.

Yep, it seems to me like you were just misunderstanding a few things and needed to wrap your head around a few pieces of the logic, that's all. Once you saw what was actually happening and understood what kill() does vs. revert(), the light bulb went on...right? 

 

14 hours ago, Chromium said:

Instead (and what I've learned today) is that it seems like I've just been working on edge case after edge case after edge case

As far as I could tell, we were just talking about one edge case, right? That being that you were re-splitting text on EVERY button click and reverting it at the end of the animation in an onComplete. And it's totally possible to do all that, as we've shown - it was just a matter of understanding the mechanics and the logic of what was going on. 

 

14 hours ago, Chromium said:

As for spam click handling, I'd hoped to find some shortcuts, but while I didn't really find any

I guess it depends what you mean by "shortcuts". I've shown you several over the course of this thread like gsap.context() and the original demo I provided where there was conditional logic in the click handler so that it only splits when necessary. Or creating an animation outside the click/hover handler and merely calling play()/restart()/reverse() in the handler. Or the tl && tl.kill() technque.

 

I'm curious what a better shortcut might look like for you. In other words, what would you have wanted GSAP to do in an ideal world? What would that specific API look like? We're always looking to improve. We just have to be very careful not to build the whole tool around specific edge cases in a way that'd cause everyone to pay a heavy kb or performance cost just to make the code slightly simpler for a certain case that only 0.001% of the users would ever run into. See what I mean? 

 

14 hours ago, Chromium said:

GSAP is still a joy to use and one of the greatest things to exist since sliced bread! Keep up the great work!

🥳

Link to comment
Share on other sites

1 hour ago, GreenSock said:

Once you saw what was actually happening and understood what kill() does vs. revert(), the light bulb went on...right?

Exactly! One of the things I wasn't sure about for example is whether .kill() also got rid of the inline styles or not. And whether .revert() did that or not. But the main thing I've learned about .kill() is that it essentially leaves the animation playhead exactly where it's killed, and thus leaves the inline styles on the elements as well. Knowing this, once put to practice, I believe should significantly help me in figuring out exactly which method to choose when handling the spam clicking on my next GSAP task. This does bring to mind though, does .progress(0) also undo the inline styles added by the timeine?

 

1 hour ago, GreenSock said:

As far as I could tell, we were just talking about one edge case, right? That being that you were re-splitting text on EVERY button click and reverting it at the end of the animation in an onComplete.

Correct. However, as far as production code goes, I can assure you that that's probably one of the simplest edge cases for me. 😂
But I definitely feel much better equipped to handle those other edge cases now.

 

1 hour ago, GreenSock said:

I guess it depends what you mean by "shortcuts".

I mean that there probably isn't any shortcuts when it comes to handling spam clicking for many of the edge cases that I've ran into the past few months. See below for examples of what I mean.

 

1 hour ago, GreenSock said:

Or creating an animation outside the click/hover handler and merely calling play()/restart()/reverse() in the handler.

This one is probably the cleanest but I believe it only works if the content inside the tweens doesn't change, right? Annoyingly, the majority of my GSAP tasks involve dynamic content that changes on subsequent clicks. So this method wouldn't work with my earlier example for instance; the typewriter animation that pulls a different TextPlugin value through AJAX on each button click. To give you a brief idea of what I mean, let's say I'm running the following tween in a timeline on the press of a button:

t1.to(_text, {
  text: {
    value: answer
  },
  delay: 1,
  duration: 5,
  ease: 'none',
  stagger: .5,
  onUpdate: () => _text[0].appendChild(_cursor[0]),
});

The tween here pulls an answer variable through AJAX and then animates "typing" the answer value for a duration of 5 seconds. The problem here, is that on subsequent clicks (spam or not), I simply wouldn't want to reverse this tween because it would take 5 seconds to reverse. Additionally, I also cannot use .restart here because it simply will not pull the fresh new value for answer (as expected). So this leaves me with no option but to .kill() the timeline, re-initialize its variable, and then add some other tween to maybe animate the _text node's parent to a height of 0 (over the span of 0.2s) for subsequent/spam clicks instead and then re-add the above tween (but with a fresh new value for the answer). I also do not think gsap.context() would handle this particular problem any better.

 

1 hour ago, GreenSock said:

I'm curious what a better shortcut might look like for you.

Haha, that's the thing, I am not sure that there's one. I think for my edge cases (such as the one above), I'd just have no choice but to handle the problem as I described above. Unless maybe there was a way to fast forward the .reverse() call to the timeline? If I could maybe control the speed of how fast the .reverse() executes... I'm just spitballing though here haha. I hope the example above kinda gives you an idea of what I'm dealing with though. That being said, that tween is only half my problem in production code, I have another tween that has to be handled separately anyway. So if the SplitText CodePen I showed you was an edge case, then this is the edge case's overlord 🤣

Link to comment
Share on other sites

10 minutes ago, Chromium said:

This does bring to mind though, does .progress(0) also undo the inline styles added by the timeine?

No. The whole point of the revert() method is to provide a way to completely revert things (including inline styles) rather than just placing the playhead at the start of the animation which involves state. For example, imagine a .fromTo() - perhaps element.x starts at 0 but you do a fromTo(...{x: -100}, {x: 100}) you'd see x jump to -100 at the very start of that tween. So if you set the playhead to 0, x should be -100. But if you revert() that tween, x would be 0. 

 

15 minutes ago, Chromium said:

Unless maybe there was a way to fast forward the .reverse() call to the timeline?

Sure, that's easy: 

tl.timeScale(-2);

And then when you want to play it forward, 

tl.play().timeScale(1);

 

  • Like 1
Link to comment
Share on other sites

30 minutes ago, GreenSock said:

The whole point of the revert() method is to provide a way to completely revert things (including inline styles)

Ah... I am a little annoyed now. Right after I posted my last reply, I just caught something... that there's a .reverse() and a .revert() for timelines!!! This whole time I've been thinking they were one and the same. I've actually only used .reverse() on a timeline! I think .revert() is a very powerful tool that I've been missing!

Mind elaborating on the difference between the two? Is it just that .revert() also resets the inline styles? Also, .revert() probably also causes an animation jump, right? Is .revert() the only timeline method (out of .reverse, .progress, .kill, .time, .clear(), .restart(), etc) that also resets inline styles?

However (and correct me if I'm wrong), I imagine that .revert() is not sufficient on its own for something like this CodePen:

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


Specifically, I'm referring to this line in the JS:

text.appendChild(cursor)

Because the original DOM state looks something like this:

<span id="text"></span>
<span id="cursor">|</span>

And when that JS line executes, it will move the #cursor node inside of the #text node. So I don't imagine .revert() will undo that? Will there need to be some additional code logic to run after .revert() to undo that as well? I assume this might be a use case for gsap.context() because reverting the context would also revert the DOM structure?

Link to comment
Share on other sites

3 hours ago, Chromium said:

Mind elaborating on the difference between the two? Is it just that .revert() also resets the inline styles? Also, .revert() probably also causes an animation jump, right? Is .revert() the only timeline method (out of .reverse, .progress, .kill, .time, .clear(), .restart(), etc) that also resets inline styles?

I'd encourage you to take a peek at the docs - they should clarify all this stuff. reverse() simply changes the playhead direction to go backwards from wherever it happens to be. So if you've got a 3-second tween and it's halfway into it when you call reverse(), it'll just start going backwards for 1.5 seconds until it hits the start. Basically it's like .timeScale(-1). 

 

revert() is completely different - it IMMEDIATELY rewinds the entire animation all the way back to the start and reverts anything that the tween changed and it kills the entire animation too. So if your element had no inline styles to begin with, and then your tween animated the "opacity" and "width" properties, obviously those inline styles would get added for the tween but revert() would remove them. 

 

3 hours ago, Chromium said:

However (and correct me if I'm wrong), I imagine that .revert() is not sufficient on its own for something like this CodePen:

Right, because the DOM manipulations are happening outside the animation itself (inside an onUpdate call in this case). It's impossible for GSAP to know all that you do in callbacks or wherever, so it's not feasible for it to roll back all the changes you make there. 

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