Jump to content
Search Community

Combines ScrollTrigger Horizontal and Vertical Scroll Snap

goyounj test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

Hi, I'm new to GSAP and am exploring some basics especially for Scroll Trigger. I want to try implementing one of the examples of full page scroll trigger, scroll snap vertically and horizontally. I have an overview of the flow of moving sections based on scroll as shown below:

image.thumb.png.c50148d498af5bb0f620868d170d01fd.png

From section A to section D1, the vertical scroll snap has been successful. Then from section D1 to section D4 with a horizontal scroll snap has also been successful. But there is a problem when I add a code to scroll snap vertically from section D4 to section E.

 

There is a kind of delay when moving sections to D1-D4 (when I scroll once, it doesn't immediately move to the full section, but displays half of the section first, then displays the full section). Then when I scroll up from section E to section D4, the screen displays the sections between sections D3 and D4.

 

There seems to be a mistake when I write the value for the snap property, but I haven't found a solution yet. Any ideas to try something?

Also any feedback to improve my GSAP code would be perfect.

 

Thanks!
 

See the Pen YzRaYWE by Enragest-21 (@Enragest-21) on CodePen

Link to comment
Share on other sites

  • Solution

Hi @goyounj and welcome to the GreenSock forums!

 

There are a few issues in your setup, mostly in your final ScrollTrigger instance.

gsap.timeline({
  scrollTrigger: {
    trigger: ".lastHorizontalSection",
    start: "right right",
    endTrigger: ".divE",
    end: "bottom bottom",
    snap: 0.1,
  }
});

First your start point. Horizontal start/end points are only available with Container Animation, not in the regular vertical setup, like the one you have in place:

https://greensock.com/3-8#containerAnimation

 

Second your trigger element. Since you're using an invalid start point it defaults to "top bottom" which will happen as soon as you get to the horizontal section.

 

Third your snap value will snap to 10% increments of the ScrollTrigger instance's progress which might not be what you're looking for.

 

Finally there is no need to create three different GSAP Context instances in this case since the scope for all of them seems to be mainRef, so creating a single one should suffice. Sure enough there is no problem in creating three and there shouldn't be a performance issue but is a redundancy, just an FYI.

 

Here is a fork of your codepen that seems to work the way you intend:

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

 

Hopefully this helps.

Happy Tweening!

  • Like 2
Link to comment
Share on other sites

Hi, @Rodrigo. Thank you very much for your help. Sometimes I'm still confused about determining the start and snap values. Then I have also fixed to write only 1 time GSAP Context because it's still in the same ref. I will explore more in more detail on this. Once again thank you very much for the help!

Link to comment
Share on other sites

Hi, @Rodrigo. I want to ask again about the related example of Scroll Trigger that I have made. Currently I'm trying to get the current section by using useRef and window.addEventListener() to get the section.currentRef.offsetTop value to differentiate the current section. But in the section that uses the horizontal scroll snap on the divD, the value of section.currentRef.offsetTop is always 0. When I comment the gsap code for the horizontal scroll snap on the divD, the value of section.currentRef.offsetTop is no longer 0. I have tried using the .kill() method and ScrollTrigger.addEventListener() instead of using window.addEventListener(), but that also doesn't work.

 

See the Pen gOQKYyO by Enragest-21 (@Enragest-21) on CodePen

 

What causes this to happen? Is there something from the gsap code that I made that makes the value of section.currentRef.offsetTop always 0 when using window.addEventListener()?

 

Thank You

Link to comment
Share on other sites

Hi,

 

This is not entirely GSAP related. It is in the way that for pinning GSAP wraps the element in what's called a pin spacer element. Then is just about the way offsetTop works:

returns the distance of the outer border of the current element relative to the inner border of the top of the offsetParent, the closest positioned ancestor element.

Since the element is wrapped in this pin spacer the distance from the top border to that parent is always zero. What you can do is get the parent element's offsetTop:

dRef?.current?.parentNode.offsetTop

Now if you want to do something when the specific section is in the viewport and since you are using a snap object configuration, you can leave that to ScrollTrigger (far more precise and reliable as well). You can use either the onStart or onComplete callbacks the snap config object offers:

  • 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):
    • snapTo [Number | Array | Function | "labels"] - determines the snapping logic (described above)
    • delay [Number] - the delay (in seconds) between the last scroll event and the start of the snapping animation. Default is half the scrub amount (or 0.1 if scrub isn't a number)
    • directional [Boolean] - by default (as of version 3.8.0), snapping is directional by default meaning it'll go in the direction the user last scrolled, but you can disable this by setting directional: false.
    • duration [Number | Object] - the duration of the snapping animation (in seconds). duration: 0.3 would always take 0.3 seconds, but you can also define a range as an object like duration: {min: 0.2, max: 3} to clamp it within the provided range, based on the velocity. That way, if the user stops scrolling close to a snapping point, it'd take less time to snap than if the natural stopping point is far from a snapping point.
    • ease [String | Function] - the ease that the snapping animation should use. The default is "power3".
    • inertia [Boolean] - to tell ScrollTrigger not to factor in the inertia, set inertia: false
    • onStart [Function] - a function that should be called when snapping starts
    • onInterrupt [Function] - a function that should be called when snapping gets interrupted (like if the user starts scrolling mid-snap)
    • onComplete [Function] - a function that should be called when snapping completes

If your snapTo calculation is correct (which right now it is) you can do something when the snap is completed in order to add an indication of when that particular section is in the viewport.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

Hi, @Rodrigo thanks a lot for the help. I've tried using parentNode and it has worked. Then right now I'm still trying to use onStart or onComplete because after I tried there was a slight delay in determining the active section, but I'll explore this more deeply. Once again, thank you.

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