Jump to content
Search Community

Can I update the scrollerProxy base on locomotiveScroll?

Pollux Septimus test
Moderator Tag

Recommended Posts

Hello,

I need some help from someone that knows and understand more about gsap scrollperProxy than I do because I am stuck with a problem that I can't seem to get around it.  And honestly, I don't know if this is a gsap related question, and if it isn't I apologize in advance. 

 

In project I am using React Router and React Router keeps the same offsetHeight position when changing routes and I would like when the route has changed to have a scroll that scrolls to the Top.

 

The issue is that I am using locomotive-scroll in combination with gsap's scrollTrigger. In order for the scrollTrigger to work with locomotive-scroll I have created a custom hook (which I will leave the code at the end because it's quite long), where I essentially tell scrollTrigger what the current locomotive-scroll, scroll position is using scrollerProxy.  

 

Unfortunately, if I try to scroll to the top of the page, for example, I can't. And the console doesn't even throw an error. I tried both using gsap scrollToPlugin and locomotive-scroll's scrollTo function but they only work If I don't use the hook that I've created. 

 

using gsap:
 

  useLocoScroll(true);

  const { pathname } = useLocation();

  useEffect(() => {
    gsap.registerPlugin(ScrollToPlugin);
    gsap.to('.App', { duration: 0, scrollTo: 0, delay: 0, ease: 'none' });
  }, [pathname]);

using loco scroll:

  useLocoScroll(true);

  const { pathname } = useLocation();

  const scrollRef = useRef(null);

  useEffect(() => {

    const scroll = new LocomotiveScroll();
    scrollRef.current = scroll;

    if (scrollRef.current) {
      scrollRef.current.scrollTo('top', {
        offset: 0,
        duration: 600,
        easing: [0.25, 0.0, 0.35, 1.0],
        disableLerp: true,
        callback: () => {
          scrollRef.current.on('scroll', ScrollTrigger.update);
        },
      });
    }
  }, [pathname]);

(Both of the options above work if useLocoScroll is set to false / `useLocoScroll(false)`)

 

Locomotive-scroll scrollTo function also takes in an object with a callback where I tried to update the ScrollTrigger in various ways but nothing worked.

 

So I was wondering if there is a way I could update the locomotive-scroll base on where the ScrollToPlugin is. Basically, doing the reverse of what I did in the custom hook? 

 

Here is the code for the custom hook:

import { useLayoutEffect } from 'react';
import LocomotiveScroll from 'locomotive-scroll';
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';

const useLocoScroll = (start) => {
  gsap.registerPlugin(ScrollTrigger);

  useLayoutEffect(() => {
    if (!start) return;

    const scrollEl = document.querySelector('.App');

    let locoScroll = new LocomotiveScroll({
      el: scrollEl,
      smoothMobile: false,
      smooth: true,
      multiplier: 1,
    });

    locoScroll.on('scroll', ScrollTrigger.update);

    ScrollTrigger.scrollerProxy(scrollEl, {
      scrollTop(value) {
        if (locoScroll) {
          return arguments.length
            ? locoScroll.scrollTo(value, 0, 0)
            : locoScroll.scroll.instance.scroll.y;
        }
        return null;
      },
      scrollLeft(value) {
        if (locoScroll) {
          return arguments.length
            ? locoScroll.scrollTo(value, 0, 0)
            : locoScroll.scroll.instance.scroll.x;
        }
        return null;
      },
      getBoundingClientRect() {
        return {
          top: 0,
          left: 0,
          width: window.innerWidth,
          height: window.innerHeight,
        };
      },

      pinType: document.querySelector('.App').style.transform
        ? 'transform'
        : 'fixed',
    });

    const locoScrollUpdate = () => {
      if (locoScroll) {
        locoScroll.update();
      }
    };

    new ResizeObserver(() => {
      if (locoScroll) {
        locoScroll.update();
      }
    }).observe(document.querySelector('[data-scroll-container]'));

    ScrollTrigger.addEventListener('refresh', locoScrollUpdate);
    ScrollTrigger.refresh();

    return () => {
      if (locoScroll) {
        ScrollTrigger.removeEventListener('refresh', locoScrollUpdate);
        locoScroll.destroy();
        locoScroll = null;
      }
    };
  }, [start]);
};

export default useLocoScroll;

 

Link to comment
Share on other sites

Hi,

 

Unfortunately I have no experience with Locomotive, but as far as I can tell you should be able to set the scroll position of the DOM node used as proxy in the ScrollTrigger configuration. That should be something the people of Locomotive should be able to answer IMHO.

 

Another option could be to use the Scroll Restoration component React Router has:

https://reactrouter.com/en/main/components/scroll-restoration

 

Sorry I can't be of more assistance. 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...