Jump to content
Search Community

How to make the horizontal scroll effect with full width

Santhosh02 test
Moderator Tag

Go to solution Solved by Rodrigo,

Recommended Posts

I want to create an horizontal scroll for a particular section as in this sandbox code url. But I cannot achieve the effect by when I scroll once, The next element should come with full of it's width and so on. Here it is scrolling little by little. I want to make it to scroll the each slide with it's full width like carousel. Any help on this would be appreciated.

Link to comment
Share on other sites

Hi @Santhosh02 when you share a Codesandbox link please share the link that includes your GSAP code, right now you share "style.css" which does not include any GSAP code (of course). I had to hunt for your js file with the code which is ScrollSection.jsx.

 

Right now you're using ScrollTrigger, ScrollTrigger is built for animating something tied to the visitors scrollbar, which means when the scrollbar moves the animation plays. You could say that the scrollbar would be the playhead if we compare it to playing a video. From your description this is not what you want, so ScrollTrigger is not the right fit for your solution.

 

Have you seen the Observer plugin https://gsap.com/docs/v3/Plugins/Observer/ it can watch for scroll events and then do some logic. See pen below 

 

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

 

You could try to get closer the Observer effect with ScrollTrigger using snap, but it will never come as close as the Observer plugin. See the snap property on the docs https://gsap.com/docs/v3/Plugins/ScrollTrigger/

 

Quote

Number | Array | Function | Object | "labels" | "labelsDirectional" - Allows you to snap to certain progress values (between 0 and 1) after the user stops scrolling. So snap: 0.1 would snap in increments of 0.1 (10%, 20%, 30%, etc.). snap: [0, 0.1, 0.5, 0.8, 1] would only let it come to rest on one of those specific progress values. It can be any of the following...

 

I anticipate your next question will be how to mix the Observer plugin with scroll, there for check out this demo. Hope it helps and happy tweening! 

 

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

Link to comment
Share on other sites

  • Solution

Hi,

 

The problem is that you're not using GSAP Context in your app:

https://gsap.com/docs/v3/GSAP/gsap.context()

 

Please check the learning resources we have in this page:

https://gsap.com/resources/React

 

Finally this seems to work the way you expect:

useEffect(() => {
  gsap.registerPlugin(ScrollTrigger);
  let allowScroll = true; // sometimes we want to ignore scroll-related stuff, like when an Observer-based section is transitioning.
  let currentIndex = 0;

  const ctx = gsap.context(() => {
    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 swipePanels = gsap.utils.toArray(".swipe-section .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, {
        xPercent: 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
      },
    });
  });
  return () => ctx.revert();
}, []);

Hopefully this helps.

Happy Tweening!

Link to comment
Share on other sites

@Rodrigo Hi, Thanks for the help. My last question is, When I go up and down past the section, There is an effect like it's slowly comes back to the section again. Can we remove it and make it as pin at the start of the section without that effect ? or is it a default value ? I've tried a lot but it's breaking the UI. 

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