Jump to content
Search Community

Confused About TimeLine Behavior And ClearProps

iDad5 test
Moderator Tag

Recommended Posts

It all started with me being confused that one of my timeline animation reversed when I wanted it to be able to be 'scroll-scrubbed'

 

What I did was animating a line in from the left and leaving to the right. The way I did it was:

 

 tl.to('#cut-line', {width: '100%', duration: 2});
 tl.set('#cut-line', {right: 0});
 tl.to('#cut-line', {width: '0%', duration: 1});

(you can find it in the CodePen too)

 

Probably not the most elegant way to do it, but it worked.

 

As soon as I added the ScrollTrigger my animations went south, mainly due to additional height added to one or the other container, but I got that fixed as described here:

 

But my 'cut-line' still came in from the right instead of the left. I came to the conclusion that ScrollTrigger (more or less) runs trough the timeline once to prepare smooth workings. So the inline style set by my second line in above code was already set.
I solved the problem by doing the animation an other way. (Moving a 100% width line from left: -100% to left: 100%, as overflow hidden was already in place) 

 

...

 

Still I found said behavior at least noteworthy and wanted:

A: to understand it better and learn ways to deal with it - if not so easily circumvent in other cases

B: to help people to be  aware of the situation in case they are as astonished as I was when seeing it for the first time

 

So i built a CodePen in preparation for the post. When I added a play button (something I didn't have in my original project) I came across the issue already with the second run of the timeline. It behaved just the same as with the ScrollTrigger attached.

That is logical in some way - I'm not sure if totally so.

Obviously all to()-tweens were reversed when I wound back the timeline, but my set()-command was not. (Not sure if that would be possible at all...[?])
 

'No trouble' here I thought, I'll just do i manually so I went:

 

gsap.set('#cut-line', {clearProps: 'all'});

at the start of my play function(); (You can find it the CodePen commented out)

 

But that didn't work. :-(

 

So I went for:

 

 tl.to('#cut-line', {width: '10px', duration: 1, clearProps: 'all'});

 

in my timeline (line three of the first code fragment.) That worked insofar as at the end of the timeline my (rest-)line jumped back to the left and the inline style was cleared (empty.)

 

But to my utter amazement when I replayed the timeline, my line cam in from the right.

I surely miss something (probably trivial) here, I just don't see what.
 

I didn't venture further into ScrollTrigger territory with that issue now, as I think that understanding the timeline working better might help me solve this problem too. Please go ahead and enlighten me.

See the Pen LYbovML by mdrei (@mdrei) on CodePen

Link to comment
Share on other sites

 

I can't give you an elaborate explanation on the why ( obviously someone else would have to do that), but I think the problem is related to not specifying the positioning of your line beforehand (like with a left value).

 

Doing that via CSS and adjusting the .set in your timeline accordingly seems to resolve your issue.

 

See the Pen 52ee6f94d228bad7fa0c447184249668 by akapowl (@akapowl) on CodePen

 

 

  • Like 2
Link to comment
Share on other sites

That‘s an interesting find. Actually I deliberately left out the left, as it‘s default and not to have it conflicting with the right value. Unsetting left is a good way to work around this issue. 
In my simple imagination it seems that reversing your “set”-instruction more complex than mine, but maybe the simplicity is what makes it harder to catch. 
 

I’m very interested to learn mor about it, and I will later try to test your solution with the ScrollTrigger brought into the equation. 

Link to comment
Share on other sites

Technically true, but the behaviour is actually not auto but left:0 which is, according to your source the 'natural' position. Still a good point and maybe a valid reason for the design decision in the GSAPTimeline to handle it like it does.


Still, the more I think about it I can’t see the sense in reversing your two properties when rewinding the timeline and not (successfully) removing the one value I set. 
 

Especially the behavior, when I manually removed the right with clearProps seems still odd. I really would be interested in what @GreenSock would have to say. But as it’s really not a real problem but more of an intellectual curiosity. 

Edited by iDad5
Afterthought
Link to comment
Share on other sites

It looks like iDad5 updated the original demo so that the issue is no longer visible? Please use the "fork" button when updating demos that you've posted to these forums so that context is not lost for future readers. 

 

I'm not sure what "elaborate explanation" you're looking for as the one by Paul seems spot on. It seems to be a logical issue related to the way that left/top are handled.

 

If I were doing this sort of thing I'd likely use scaleX and transformOrigin instead. That way you don't have to change any non-performant properties (left, right). It seems that you default to using these properties when there are better alternatives available, iDad5.

Link to comment
Share on other sites

1 hour ago, ZachSaucier said:

It looks like iDad5 updated the original demo so that the issue is no longer visible? Please use the "fork" button when updating demos that you've posted to these forums so that context is not lost for future readers. 

No I didn't and the issue is still there.

 

1 hour ago, ZachSaucier said:

I'm not sure what "elaborate explanation" you're looking for as the one by Paul seems spot on. It seems to be a logical issue related to the way that left/top are handled.

I beg to differ:

I cannot see a logical issue especially when I remove the Right property with ClearProps and the line moves to the left at the end of a run. It don't think it's expectable that with next run ist starts again on the right.
 

1 hour ago, ZachSaucier said:

If I were doing this sort of thing I'd likely use scaleX and transformOrigin instead. That way you don't have to change any non-performant properties (left, right). It seems that you default to using these properties when there are better alternatives available, iDad5.

I can see that, but that does not explain for me. In that case performance really wasn't something I was concerned about. After some trouble with transform before (you might remember) I opted for width - just comes more naturally to me, as most of the time I work with containers that contain actual content.

 

Edit: I looked at my original project, there the line ist made up of 'stitches' made up by a repeating background-image (alternatively as a border-image) scaling such an element wouldn't work. I could have worked with masks or containers, but in my eyes that would have added unnecessary complexity.  So actually I had a good reason to do it the way I did. Reducing complexity for CodePen sometimes isn't giving one the right (background-) picture. ;-) 


Regardless, I still think that it should have worked and would like very much to understand why it didn't.

Link to comment
Share on other sites

Here's the issue explained...

 

All GSAP tweens (including set() calls which are just zero-duration tweens) must record start and end values so that they can be interpolated. If you check what the browser reports as the computed value for "right" on the element when your .set(...{ right: 0 }) is called, you'll find that it's 0px which is accurate because you've got width: 100%, making the line touch the very right edge. So the .set() call records that accordingly. 

 

Then, when you rewind the playhead past that spot on the timeline, the set() call is like "okay, I should revert that value to what it was when I started...which is 0px". It's doing that correctly, and setting it inline. It doesn't matter that you did a clearProps on your final tween - that just clears the styles at the very end. It's not as if that goes back through all the tweens in the timeline and says "delete all your recorded values and never set things inline again"

 

Your first tween is only animating the width property and since the "right" property is set to 0 inline by the set(), it's animating as if it's stuck to the right side after you rewind past that spot. 

 

It's just one of those scenarios that's virtually impossible to have GSAP automatically discern and do what you're expecting. It can't look backward and think "oh, he's animating width in that prior tween and that affects right/left values so I should force that tween to rewind and then see where right is at the start of that other tween and record it here".

 

However, there's a very easy fix for your demo once you understand what's happening. Just have your first tween handle "right" as well, since that'll cause it to record the initial value (before you do your width animation...because that directly affects the "right" property as well):

// BAD:
tl.to('#cut-line', {width: '100%', duration: 2});
tl.set('#cut-line', {right: 0});

// GOOD:
tl.to('#cut-line', {width: '100%', duration: 2, right:0});

Does that clear things up? 

  • Like 3
  • Thanks 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...