Jump to content
Search Community

Scroll snap for specific section and wait before snapping

TruongNH test
Moderator Tag

Recommended Posts

I have been stuck here for a week.

 

I'm trying to make a scroll snap from section 1 to section 2 with a delay time for exit animation and reverse. From section 2 to section 4 it can be a normal scroll.

 

I'm using overflow: hidden that I can't let it go. This is the reason that I think it prevents me from scrolling snap and normal scroll.

 

The scroll way I try to achieve is exactly the same as this website: David | Creative Developer (david-hckh.com)

 

Here is the codesandbox : https://codesandbox.io/s/scroll-rfjx9k

 

How can I achieve this ? 

 

 

Please help me with this....

Link to comment
Share on other sites

Hi @TruongNH and welcome to the GreenSock forums!

 

Actually that site is not using scrolling at all if you inspect with devtools. Is actually moving things on the Y axis.

 

For that you can use the Observer Plugin:

https://greensock.com/docs/v3/Plugins/Observer

 

That doesn't mean that this can't be done with ScrollTrigger. You can combine it with the ScrollTo Plugin in order to achieve this effect:

https://stackblitz.com/edit/vitejs-vite-d73sck?file=src%2Fviews%2FLayers.jsx

 

Navigate to the Layers Section route in order to see it in action.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

On 9/26/2023 at 7:06 AM, Rodrigo said:

Hi @TruongNH and welcome to the GreenSock forums!

 

Actually that site is not using scrolling at all if you inspect with devtools. Is actually moving things on the Y axis.

 

For that you can use the Observer Plugin:

https://greensock.com/docs/v3/Plugins/Observer

 

That doesn't mean that this can't be done with ScrollTrigger. You can combine it with the ScrollTo Plugin in order to achieve this effect:

https://stackblitz.com/edit/vitejs-vite-d73sck?file=src%2Fviews%2FLayers.jsx

 

Navigate to the Layers Section route in order to see it in action.

 

Hopefully this helps.

Happy Tweening!

Thanks for giving a solution. I have tried to use Observer to snap between landingpage(section 1) and scroll-container (section 2) .

 

But I have a problem I can't scroll snap between section 1 and section 2 and freescroll for scroll-container.

 

Where am I wrong and where am I lacking?

 

Here is the code sandbox: scroll - CodeSandbox

Link to comment
Share on other sites

Hi,

 

There are a few things to notice here.

 

The site you posted as an example doesn't use scrolling at all. That doesn't mean that is not possible, is just weird to have natural scroll, having the scroll bar visible and not being allowed to scroll. These examples combines ScrollTrigger with Observer:

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

 

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

 

Finally you are using your ScrollManager file as a React component. While I can see the value of abstraction and keeping your code more organized IMHO I don't see that as a good and solid approach. Keep in mind that in React child component are rendered first and then their parents, so the code in that particular file runs before the DOM elements are mounted in the DOM on t he first run, so you could get some errors there. Also you are not using effect hooks, GSAP Context or doing proper cleanup in your app. I'd strongly recommend you to create your GSAP code in the same file it'll be used at first and then start abstracting away and micro-optimizing your code. First make it work the way is supposed and make it as easy to follow as possible (comments are helpful here), then make it pretty. Finally read the resources in this page:

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

On 9/27/2023 at 10:51 PM, Rodrigo said:

Hi,

 

There are a few things to notice here.

 

The site you posted as an example doesn't use scrolling at all. That doesn't mean that is not possible, is just weird to have natural scroll, having the scroll bar visible and not being allowed to scroll. These examples combines ScrollTrigger with Observer:

 

 

 

 

 

 

Finally you are using your ScrollManager file as a React component. While I can see the value of abstraction and keeping your code more organized IMHO I don't see that as a good and solid approach. Keep in mind that in React child component are rendered first and then their parents, so the code in that particular file runs before the DOM elements are mounted in the DOM on t he first run, so you could get some errors there. Also you are not using effect hooks, GSAP Context or doing proper cleanup in your app. I'd strongly recommend you to create your GSAP code in the same file it'll be used at first and then start abstracting away and micro-optimizing your code. First make it work the way is supposed and make it as easy to follow as possible (comments are helpful here), then make it pretty. Finally read the resources in this page:

 

Hopefully this helps.

Happy Tweening!

@Rodrigo Thanks for your instructions. I have tried with your instructions and I have reached the snap between section 1 and section 2. But for a normal scroll from section 2 I have overflow: hidden. So I'm trying to make a normal scroll by Y. Currently I'm using auto-increase height. I want to make it scroll value height.

 

How can I reach that? 

This is what I have reached: https://codesandbox.io/s/scroll-rfjx9k

 

Link to comment
Share on other sites

Hi,

 

Your example is a quite convoluted IMHO. Again I don't see the benefit of that ScrollManager.js file that you are using like a component. If you want to use that approach I would suggest a custom hook, but not a component.

 

You're still not using GSAP Context, as suggested in the articles you can read in the link I provided in my previous post.

 

Unfortunately we don't have te time resources to create custom solutions for our users, solve complex logic issues or comb through large codebases trying to find errors and or issues, so I can't create a port to React of this example at the moment. The best I can do is create a Codepen example fo multiple Observer sections:

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

 

The JS logic is not out of this world and you should be able to port it to React by following our guide to use GSAP in React environments.

 

I think your best alternative is to create something as simple as possible and start adding enhancements to it as you go along.

 

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

  • 2 months later...
On 9/27/2023 at 5:51 PM, Rodrigo said:

Hi,

 

There are a few things to notice here.

 

The site you posted as an example doesn't use scrolling at all. That doesn't mean that is not possible, is just weird to have natural scroll, having the scroll bar visible and not being allowed to scroll. These examples combines ScrollTrigger with Observer:

 

 

 

 

 

 

Finally you are using your ScrollManager file as a React component. While I can see the value of abstraction and keeping your code more organized IMHO I don't see that as a good and solid approach. Keep in mind that in React child component are rendered first and then their parents, so the code in that particular file runs before the DOM elements are mounted in the DOM on t he first run, so you could get some errors there. Also you are not using effect hooks, GSAP Context or doing proper cleanup in your app. I'd strongly recommend you to create your GSAP code in the same file it'll be used at first and then start abstracting away and micro-optimizing your code. First make it work the way is supposed and make it as easy to follow as possible (comments are helpful here), then make it pretty. Finally read the resources in this page:

 

Hopefully this helps.

Happy Tweening!

Hello, is this imported to React? I'm trying this myself and can't get it to work, this is my code:

 useGSAP(() => {
    let allowScroll = true; // sometimes we want to ignore scroll-related stuff, like when an Observer-based section is transitioning.
    let scrollTimeout = gsap.delayedCall(1, () => (allowScroll = true)).pause(); // controls how long we should wait after an Observer-based animation is initiated before we allow another scroll-related action
    let currentIndex = 0;
    let swipePanels = gsap.utils.toArray(".panel");

    // set z-index levels for the swipe panels
    gsap.set(swipePanels, { zIndex: (i) => swipePanels.length - i });

    // create an observer and disable it to start
    let intentObserver = ScrollTrigger.observe({
      type: "wheel,touch",
      onUp: () => allowScroll && gotoPanel(currentIndex - 1, false),
      onDown: () => allowScroll && gotoPanel(currentIndex + 1, true),
      tolerance: 10,
      preventDefault: true,
      onEnable(self) {
        allowScroll = false;
        scrollTimeout.restart(true);
        // when enabling, we should save the scroll position and freeze it. This fixes momentum-scroll on Macs, for example.
        let savedScroll = self.scrollY();
        self._restoreScroll = () => self.scrollY(savedScroll); // if the native scroll repositions, force it back to where it should be
        document.addEventListener("scroll", self._restoreScroll, {
          passive: false,
        });
      },
      onDisable: (self) =>
        document.removeEventListener("scroll", self._restoreScroll),
    });
    intentObserver.disable();

    // handle the panel swipe animations
    function gotoPanel(index, isScrollingDown) {
      // return to normal scroll if we're at the end or back up to the start
      if (
        (index === swipePanels.length && isScrollingDown) ||
        (index === -1 && !isScrollingDown)
      ) {
        intentObserver.disable(); // resume native scroll
        return;
      }
      allowScroll = false;
      scrollTimeout.restart(true);

      let target = isScrollingDown
        ? swipePanels[currentIndex]
        : swipePanels[index];
      gsap.to(target, {
        yPercent: isScrollingDown ? -100 : 0,
        duration: 0.75,
      });

      currentIndex = index;
    }

    // pin swipe section and initiate observer
    ScrollTrigger.create({
      trigger: ".swipe-section",
      pin: true,
      start: "top top",
      end: "+=200", // just needs to be enough to not risk vibration where a user's fast-scroll shoots way past the end
      onEnter: (self) => {
        if (intentObserver.isEnabled) {
          return;
        } // in case the native scroll jumped past the end and then we force it back to where it should be.
        self.scroll(self.start + 1); // jump to just one pixel past the start of this section so we can hold there.
        intentObserver.enable(); // STOP native scrolling
      },
      onEnterBack: (self) => {
        if (intentObserver.isEnabled) {
          return;
        } // in case the native scroll jumped backward past the start and then we force it back to where it should be.
        self.scroll(self.end - 1); // jump to one pixel before the end of this section so we can hold there.
        intentObserver.enable(); // STOP native scrolling
      },
    });
  }, []);

Link to comment
Share on other sites

On 12/24/2023 at 7:31 PM, GreenSock said:

@skole is this related to your other post?: 

 

 

Please make sure you're not posting about the same issue in multiple threads. 

 

If you need help, make sure you provide a minimal demo (like a Stackblitz) that clearly illustrates the issue. Here's one you can fork: https://stackblitz.com/edit/react-cxv92j

 

Good luck!

Oh yea, I forgot about that, thanks for answering.

Unfortunately I can't provide demo because it's private project that I'm working on, but it's using NextJS, and css is standard. So sorry, but if you could help in some way I would appreciate it.  

Link to comment
Share on other sites

1 hour ago, skole said:

Unfortunately I can't provide demo because it's private project that I'm working on, but it's using NextJS, and css is standard. So sorry, but if you could help in some way I would appreciate it.  

Oh, we definitely don't want you to just share your whole project. The proper way to do this is to just recreate the issue in the most minimal way possible, with simple colored <div> elements, for example. No need to have any real artwork, logos, or anything like that from your "real" project. I already gave you a link to a starter template you can fork, so hopefully it's pretty easy for you. We really can't troubleshoot blind - we've gotta see the issue in context in order to offer solid advice. 

Link to comment
Share on other sites

On 12/28/2023 at 9:27 PM, GreenSock said:

Oh, we definitely don't want you to just share your whole project. The proper way to do this is to just recreate the issue in the most minimal way possible, with simple colored <div> elements, for example. No need to have any real artwork, logos, or anything like that from your "real" project. I already gave you a link to a starter template you can fork, so hopefully it's pretty easy for you. We really can't troubleshoot blind - we've gotta see the issue in context in order to offer solid advice. 

But if I strip everything, it works, I'm using AOS for some animations and stuff, maybe is that?

 

Could code you provided be translated to react?

Link to comment
Share on other sites

23 hours ago, skole said:

But if I strip everything, it works, I'm using AOS for some animations and stuff, maybe is that?

I'm not at all familiar with AOS, but it certainly sounds like that could be the culprit if you strip it out and everything else works. That's the key with troubleshooting - isolate, isolate, isolate. Create a minimal demo with the bare bones basics, then start building it up to be closer and closer to your "real" project until it breaks and then you know exactly what caused the break. 

 

I'm curious why you're using AOS in addition to GSAP (instead of just GSAP). Maybe there's a great reason; I'm just unfamiliar with it so I figured I'd ask.

 

23 hours ago, skole said:

Could code you provided be translated to react?

Absolutely. GSAP is completely framework agnostic. Works great in React or anywhere. We've got a useGSAP() hook for React that makes it even simpler. See https://gsap.com/react for details. 

Link to comment
Share on other sites

On 12/31/2023 at 12:08 AM, GreenSock said:

I'm not at all familiar with AOS, but it certainly sounds like that could be the culprit if you strip it out and everything else works. That's the key with troubleshooting - isolate, isolate, isolate. Create a minimal demo with the bare bones basics, then start building it up to be closer and closer to your "real" project until it breaks and then you know exactly what caused the break. 

 

I'm curious why you're using AOS in addition to GSAP (instead of just GSAP). Maybe there's a great reason; I'm just unfamiliar with it so I figured I'd ask.

 

Absolutely. GSAP is completely framework agnostic. Works great in React or anywhere. We've got a useGSAP() hook for React that makes it even simpler. See https://gsap.com/react for details. 

For some reason, I don't know how to translate to react the code that you provided in sandbox, it just doesnt work, is there and available examples or translations for that?

Link to comment
Share on other sites

2 hours ago, skole said:

For some reason, I don't know how to translate to react the code that you provided in sandbox, it just doesnt work, is there and available examples or translations for that?

For what?  Which code that I provided? What CodeSandbox? 

 

Did you read this article?: https://gsap.com/react

 

It's beyond the scope of help we can provide in these free forums to build a React project for you, but if you create a minimal demo that clearly illustrates a GSAP-related issue, we'd be happy to take a look at that and offer some advice. Here's a React starter template: 

https://stackblitz.com/edit/react-cxv92j

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