0

I am trying to implement locomotive-scroll with my react project but I run into 2 issues. One of them is that react strict mode (I think) created 2 instances of the locomotive-scroll which resulted in multiple problems.

enter image description here

The second problem is that the gsap scrollTriggers that I use are created before the locomotive scroll resulting in some glitches because the scrollProxy does not update the actual scroll position properly because the locomotive scroll is created afterward.

Here is how I implemented the locomotive-scroll and made it work with scrollTrigger.

import React, { useEffect } from 'react';
import LocomotiveScroll from 'locomotive-scroll';
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';

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

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

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

    let locoScroll = new LocomotiveScroll({
      el: scrollEl,
      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 lsUpdate = () => {
      if (locoScroll) {
        locoScroll.update();
      }
    };

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

    // return () => {
    //   if (locoScroll) {
    //     ScrollTrigger.removeEventListener('refresh', lsUpdate);
    //     locoScroll.destroy();
    //     locoScroll = null;
    //   }
    // };

    console.log('LocoScroll created');
  }, [start]);
};

export default useLocoScroll;

I've tried removing loco-scroll if it already exists (commented code in the example above), but if I do so, the scrollTrigger won't work at all. Also, I am not a big fan of using setTimeout for scrollTrigger to allow the locoScroll to be created before them.

Oliver
  • 177
  • 1
  • 10

0 Answers0