Jump to content
Search Community

ScrollTrigger snapping: add element to snapped-to item?

fionchadd test
Moderator Tag

Recommended Posts

Hi there, 

 

I'm trying to build a kind of vertical-scrolling / slot-machine type animation. 

 

I've got the bones of it, it's rotating on scroll and snapping to the list items, which is what I want. What I'd like to do now is, when it's snapped to an item, give that item a class so I can style it differently. 

 

I've tried a workaround with an additional scroll-trigger event which fires on onComplete inside the snap object, which seems to work some of the time, but sometimes more than one item will be given the active class, or it won't properly remove the active class when I start scrolling again. 

I'm guessing more than one item is given the class because of the way I've wrapped the list items around back on themselves, so there are technically two items in the center. So I was wondering if it was possible to add a class to the snapped-to item instead of looking for the item in the center of the screen? I've read through all the docs on snapping but I can't work out if this is something that's possible. 

 

Thanks! 

Hannah

See the Pen yLEbpEo by fionchadd (@fionchadd) on CodePen

Link to comment
Share on other sites

There is the onSnapComplete callback, I would certainly hook something on to there. Every animation is the same length right? So you could maybe extrapolate which item is active based on the current progress value. Max progress (eg 1) / number of items 20, so for every 0.05 in the process value it is a specific index in your list.  This is what the  onSnapComplete progress logs: 0.6262631655654176 / 0.05 = 12.5252633113 so the 12 or 13th in the list? I'm bad at math. 

 

Function - A callback for when the snapping has completed. This only applies when there's a snap defined. A snap will be cancelled if/when the user (or anything else) interacts in any way with scrolling, so the onSnapComplete would not be triggered at all in that case. The callback receives one parameter - the ScrollTrigger instance itself which has properties/methods like progress, direction, isActive, and getVelocity(). Example:

onSnapComplete: ({progress, direction, isActive}) => console.log(progress, direction, isActive)

 

Hope it helps and happy tweening! 

  • Like 2
Link to comment
Share on other sites

I think the onComplete property inside the snap Object is the same as onSnapComplete, right? I was trying to work out if there's a difference! 

 

Currently I'm using a snap object: 

Object - Like snap: {snapTo: "labels", duration: 0.3, delay: 0.1, ease: "power1.inOut"}, fully customizable with any of the following properties (only "snapTo" is required):

  • onComplete [Function] - a function that should be called when snapping completes

and I'm calling a function with onComplete inside the snap object, which sounds like it does the same thing as calling the function with onSnapComplete?

 

Interesting idea to link it to progress of the animation, I'll give that a try! Thank-you :-) 

Link to comment
Share on other sites

And now it's a slot machine! 

See the Pen xxzdvNQ by fionchadd (@fionchadd) on CodePen

 

 

I had to do some quite heavy tinkering to select the active element - because the items loop round in a 3d circle there are two items in each wheel on the center point when the animation stops. But the one behind is *slightly* smaller so there's a small amount of the browser window where the front one is present and the back one isn't, so once I got the offset *just* right it worked! It feels like there should maybe be a better way to do that but I'm not clever enough to work out what it is. 

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