Firmin Martin Posted October 9, 2021 Posted October 9, 2021 Hello, I just made my first steps with gsap + ScrollTrigger, but have struggled to snap to the nearest scene when two scenes are visible (see the pen in the end). That's not something unexpected, as I looped over the scenes and assigned them a snap value 1. But all the variants I tried failed (see the snapTo: 1 / (scenes.length - 1) approach: See the Pen mdMbadp by firmart (@firmart) on CodePen. and the snapTo: "labels" approach: See the Pen YzxKdgO by firmart (@firmart) on CodePen. ). I'm aware of the given examples See the Pen YzyaKrq by GreenSock (@GreenSock) on CodePen. See the Pen XWmEoNg by GreenSock (@GreenSock) on CodePen. But the former seems to rely on the CSS properties scroll-snap-typeandscroll-snap-align(I believe that it can be done with gsap alone) and the latter has a hardcoded width (not sure whether it's relevant). How can I snap to the nearest scene (upper scene's end or lower scene's beginning) when the scroller is between two scenes ? Thanks See the Pen oNeveJy by firmart (@firmart) on CodePen.
Solution akapowl Posted October 9, 2021 Solution Posted October 9, 2021 Welcome to the forums @Firmin Martin I would probably do things a bit different altogether. For one you don't really need two different forEach-loops, you can create the timelines with scrollTriggers for your containers from within that first forEach-loop you have for the sections by just targetting the sections container element. For the snapping I would probably juts create one extra ScrollTrigger, that 'spans' across the whole page-scroll. For the logic of the snapping, think about it this way: You have two states (starting-state and end-state of the animation of each section) with the duration of the pinning being equal to the duration of the free-scrolling in between sections (i.e. the window's height) so you could just take the number of your scenes, multiply that by 2 (because of the two 'states') and then in the end substract 1 (because snapping to 0 will be added automatically and you have to consider that). ScrollTrigger.create({ start: 0, end: "max", //snap: [0, 0.2, 0.4, 0.6, 0.8, 1] snap: 1/(scenes.length * 2 - 1) }); That could then look something like this: See the Pen be907573a8ade3f0eea9076ce04a1083 by akapowl (@akapowl) on CodePen. That works just fine, but with a scenario like this you will run into following issue: Since you will be snapping to points where the pinning is just about to start/end and after snapping you continue scrolling up or down (depending on where you snapped to) you will be seeing nasty jumps of the pinned container - which is nothing ScrollTrigger can do much about because scrolling and js-processing are handled on two different threads by the browser. So here is another version including a suggested workaround for that by @GreenSock from this thread where it just offsets the snapping by a little bit depending on where you snap to. I'm not exactly sure if this is the simplest implementation of that workaround (because I had to also work around how JS is handling small numbers) but it works just about right. I Hope that will help Cheers. See the Pen 42a73ce2154cb620af866c6e3d90a394 by akapowl (@akapowl) on CodePen. 3
Firmin Martin Posted October 10, 2021 Author Posted October 10, 2021 @akapowl Many thanks for your answer and the workaround for an issue I've not even think about! I have some further questions: You used end: "max" in the extra ScrollTrigger, but I didn't find max documented, is that an accepted value ? The two states thing is due to the .from method + an implicit .to method (which set every property to the default value, e.g. scale: 1) along with pin: true , thus making the height twice as it would be without pin: true , right ? Thanks. 1
akapowl Posted October 10, 2021 Posted October 10, 2021 Happy to help 1) It really isn't in the docs, didn't know that - I picked it up here in the forums. And yes, it is an accepted value; you can even see @GreenSock suggesting the use of it in this thread here. 2) By two "states" I meant The position of the container's top meeting up with the window's top edge and The position when the animation/pinning has finished in other words the ScrollTrigger's end "+=100%" - which is one window-height later. So basically you are right with regard to the pinning being responsible for it working like that. The equal heights of the pinSpacing added and the sections themselves are what's making the calculations I used work. 2
Firmin Martin Posted October 10, 2021 Author Posted October 10, 2021 @akapowl Thanks for the helpful comments!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now