react-locomotive-scroll icon indicating copy to clipboard operation
react-locomotive-scroll copied to clipboard

Example of using this to bind locomotive as a proxy for GSAP ScrollTrigger

Open samuelgoddard opened this issue 4 years ago • 6 comments

Long shot but does anyone have an example of how I would add Locomotive as a proxy for GSAP scrolltrigger with this package (as seen here with vanilla JS) -> https://codepen.io/GreenSock/pen/zYrELYe

samuelgoddard avatar Jun 27 '21 15:06 samuelgoddard

As you get the scroll instance when you use useLocomotiveScroll you should be able to do whatever you like. I found this : https://greensock.com/forums/topic/24859-locomotive-scroll-direction-with-scrolltrigger/ it may possibly help you !

antoinelin avatar Jun 27 '21 16:06 antoinelin

Has anybody actually managed to get this working with Next JS? I can get the smooth scrolling working, I can get GSAP Scroll Trigger working. But not together. I have tried with a custom hook and also with HoC but no luck as yet.

Suggestion above gives some guidance but its not exactly clear how they actually fully implemented it.

willslater avatar Oct 12 '21 14:10 willslater

Erf, as I said here I think this library needs too much DIY to find how to properly use it with React. As I did not tried yet to use GSAP myself with it I can not give valuable advises, but if someone can help 🙏🏻

antoinelin avatar Oct 15 '21 12:10 antoinelin

I managed to get it working, and mostly working well. For anyone coming in the future, i used https://www.npmjs.com/package/react-locomotive-scroll so that it gives provider and then you can get the event using hooks. One thing I needed though was a scroller proxy.

https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.scrollerProxy()

Example here with component worked. I found this on GSAP forums so cannot link to it, but the code i found is below.

import { useRef, useEffect } from "react";
import {
  LocomotiveScrollProvider,
  useLocomotiveScroll,
} from "react-locomotive-scroll";
import { gsap } from "gsap/dist/gsap";
import ScrollTrigger from "gsap/dist/ScrollTrigger";

import { Header, Footer } from "components";

gsap.registerPlugin(ScrollTrigger);

const ScrollTriggerProxy = () => {
  const { scroll } = useLocomotiveScroll();

  useEffect(() => {
    if (scroll) {
      const element = scroll?.el;

      scroll.on("scroll", ScrollTrigger.update);
      ScrollTrigger.scrollerProxy(element, {
        scrollTop(value) {
          return arguments.length
            ? scroll.scrollTo(value, 0, 0)
            : scroll.scroll.instance.scroll.y;
        },
        getBoundingClientRect() {
          return {
            top: 0,
            left: 0,
            width: window.innerWidth,
            height: window.innerHeight,
          };
        },
        pinType: element.style.transform ? "transform" : "fixed",
      });
    }

    return () => {
      ScrollTrigger.addEventListener("refresh", () => scroll?.update());
      ScrollTrigger.refresh();
    };
  }, [scroll]);

  return null;
};

const MainLayout = ({ children }) => {
    const containerRef = useRef(null);
  return (
    <>
      <LocomotiveScrollProvider
        options={{
          smooth: true,
          multiplier: 1,
          class: "is-reveal",
        }}
        watch={
          [
            //..all the dependencies you want to watch to update the scroll.
            //  Basicaly, you would want to watch page/location changes
            //  For exemple, on Next.js you would want to watch properties like `router.asPath` (you may want to add more criterias if the instance should be update on locations with query parameters)
          ]
        }
        containerRef={containerRef}
      >
        <ScrollTriggerProxy />
        <Header />
        <main data-scroll-container ref={containerRef}>
          {children}
          <Footer />
        </main>
      </LocomotiveScrollProvider>
    </>
  );
};

export default MainLayout;

Note, I could not use data-sections with it as it just ignored.

willslater avatar Oct 15 '21 12:10 willslater

instead of this line, scroll.on("scroll", ScrollTrigger.update); I've used this,

scroll.on('scroll', () => {
        ScrollTrigger.update()
        ScrollTrigger.refresh()
      })

it worked perfectly in my case. even with data-scroll-section s

malinda666 avatar Aug 19 '22 13:08 malinda666

@willslater How does this work with ScrollTrigger pin function? My content always disappears :(

opr-inzn avatar Jan 14 '23 16:01 opr-inzn