Jump to content
Search Community

ScrollTrigger timeline snapping with "label" doesn't snap precisely to label position

cmal test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

I've been working on a GSAP animation using ScrollTrigger + SplitText to make a timeline animation. The animation consists of a handful of sentences that animate in one after the other, with a timeline label existing at the start of each sentence.

 

I've noticed that when setting snap.snapTo to "labels" or "labelsDirectional" that the position the timeline snaps to will very often not be the exact label position, but a couple frames before or after the label, resulting in characters that should be visible (e.g. the period at the end of a sentence) being invisible, or characters that shouldn't be visible (the first letter of the next sentence) being visible.

 

You can see this either in the linked CodePen or in the attached video where I added visual click indicators to point out the places where this is happening.

 

I'm pretty sure I know the reason why this is happening: browser scroll position has a finite amount of precision because scroll position is set in whole pixel increments, while the exact position of a label within a timeline may be an infinitely precise progress decimal, and so there's no way to represent every possible amount of progress using scroll. But regardless of the reason, this presents a pretty significant obstacle for snapping to label positions when the exact animation state at that position needs to be precise, such as my case.

 

This inability to snap precisely to a label also creates issues when using other label-related functionality, such as .previousLabel() or .currentLabel() on the timeline, which will often be different from the label that you are supposedly snapped to.

 

I haven't been able to find a way to work around this, and would really appreciate any help pointing me in the best direction to handle this.

 

It also feels like there should probably be some sort of built-in way to address this, even if is a one-off scroll trigger parameter like "forceSnap" or something which ensures that label positions map cleanly to the scroll even if that would mean fudging a couple of frames within the timeline to ensure that that happens. I can't think of many situations where I'd be wanting to snap a timeline to a label and would be okay with that snap position being off by a frame or two in either direction.

See the Pen d74557b0c16477a1444a7bb11f9c28eb by cmalven (@cmalven) on CodePen

Link to comment
Share on other sites

  • Solution

You're exactly right about the problem being the scroll position of the browser being limited in "resolution", thus you might be specifying a snapping point that's literally impossible for the browser to hit (like telling the browser to scroll to exactly 201.35 pixels from the top...it's just gonna round that to 201 because it can't do partial pixels). 

 

You're technically asking the timeline to get out of synch with the scroll position, so it wouldn't be a true scrub. However, here's a way to get the result you're requesting: 

See the Pen qBgRxwK?editors=0010 by GreenSock (@GreenSock) on CodePen

 

I added some comments to the code to help make it clearer. You can set the range for snapping. I chose 0.1 but you can do whatever you need. Basically, when it gets within that distance (in seconds) from the snapping destination on the timeline, it'll stick there (sorta like rounding it to that spot). 

 

Is that what you were looking for? 

Link to comment
Share on other sites

Thank you @GreenSock! I've tested this both in CodePen and in my actual project implementation (which is much more complicated in terms of animation) and this worked perfectly in both.

 

The only thing I ran into is that I'm using Typescript and TS complains that the "snapTo" method does not accept an argument of "self" in 

 

snapTo: (progress: number, self: GSAPTimeline)

 

…but that is a fairly minor thing. Thank you so much for investigating this and helping figure out a solution.

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