Jump to content
Search Community

ScrollTrigger snap not snapping directly to center - scroll picker

lrc test
Moderator Tag

Recommended Posts

Hello, I'm trying to create a scroll picker in vue3 with ScrollTrigger. I have an array of options, and a highlight div that as the user scrolls, I want it to snap to the nearest option but also have the selected option snap directly in the center of the highlight div. I'm having difficulty with the consistency of the snapTo functionality in this case, as it doesn't always center in the highlight div.

 

https://stackblitz.com/edit/vitejs-vite-uf2ygv?file=src%2FApp.vue

Link to comment
Share on other sites

Hi @lrc and welcome to the GSAP Forums!

 

The first thing I notice is that you have toggleActions and scrub on every ScrollTrigger instance. Those are not compatible at all since they do completely different things at it's core. Scrub will update the tween/timeline's progress based on the scroll position, so is a gradual update. On the other hand toggleActions will do something on each event (for lack of a better word) on the start and end points, as mentioned in the ScrollTrigger docs:

toggleActions
String - Determines how the linked animation is controlled at the 4 distinct toggle places - onEnter, onLeave, onEnterBack, and onLeaveBack, in that order. The default is play none none none. So toggleActions: "play pause resume reset" will play the animation when entering, pause it when leaving, resume it when entering again backwards, and reset (rewind back to the beginning) when scrolling all the way back past the beginning. You can use any of the following keywords for each action: "play", "pause", "resume", "reset", "restart", "complete", "reverse", and "none".

 

Also is super weird that you have this:

toggleActions: 'play play play play',

That will basically play the instance in all those situations.

 

Also it seems that you're misunderstanding how snap works and the fact that you're creating a single ScrollTrigger instance for each element. This should be as simple as creating a single ScrollTrigger instance that just snaps the scroll position of the scroller, something like this:

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

 

I made some changes in the HTML and CSS since I don't think your current setup will work since it doesn't create the needed scrolling to move the list.

 

Hopefully this helps.

Happy Tweening!

  • Thanks 1
Link to comment
Share on other sites

Hi Rodrigo, thanks so much for your quick response and super clear explanation! I find these forums so helpful. The snap is now working but I'm back with two follow-up questions if you don't mind!


1) Is there a way to know which option is the ‘selected’/ center one, in other words, which option was snapped to? We want to use this in order to update the activeIndex so we can apply different css styling to each option based on how far away it is from the selected option.

 

2) the scroll/snap animation feels a bit buggy in some cases, sometimes it scrolls to a different option than expected, especially when scrolling fast. I've attached an example where I scroll to 'Voluptates?' but it snaps to 'Facere.'

3) (nice to have): if the options are not all the same height, for example if options above and below the selected option are smaller, how does this affect the snapping functionality? i.e. if 'selected option' was 60px but prev-1 & next-1 are 90% of that, prev-2 & next-2 are 70%, and prev-3 and next-3 are 40% of 60px optionHeight.

Here is my code example: https://stackblitz.com/edit/vitejs-vite-o4gumk?file=src%2FApp.vue

Link to comment
Share on other sites

Hi,

 

Yeah having small elements (not enough height) will definitely be an issue because the way browsers handle wheel event the amount of pixels of each wheel event is more than the height of those elements.

 

Maybe you should consider the Vertical Loop helper function in combination with the Observer Plugin, as shown in this demo:

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

 

You can set an onComplete callback to add the active class to the target element.

 

Hopefully this helps.

Happy Tweening!

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