Jump to content
Search Community

GSAP Scroll Trigger isn't working with Smooth Scrollbar (React/Gatsby)

andsavu test
Moderator Tag

Recommended Posts

Hey guys, 

 

so I started playing with GSAP & Scroll Trigger and I really liked it and the animations are super smooth, but I've been also using this plugin Smooth Scrollbar ( https://idiotwu.github.io/smooth-scrollbar/ ) for a while and I wanted to add it to this new project as well, but it doesn't work.

I was hoping maybe you guys can help a bit here?

 

I don't have a codepen sadly but I've got some bits of code:

 

I've got my page wrapped in these 2 divs, .scrollable is used to initialize Smooth Scroller

<div className="scrollable" data-scrollbar>
  <div className="wrap-overflow">
.scrollable {
  width:100vw;
  height:100vh;
  overflow: auto;
}
.wrap-overflow {
  position: relative;
  overflow: hidden;
  height:100%;
}
    gsap.registerPlugin(ScrollTrigger);
    gsap.to('.image_float', {
      scrollTrigger: {
        trigger: '.h_trigger',
        start: '-100px top',
        scroller: '.wrap-overflow',
        end:'bottom top',
        scrub: 1,
        markers: true,
        id: 'image-float'
      },
      y: -200,
      ease: 'none',
      duration: 10
    });
useEffect(() => {
  const isSSR = typeof window === "undefined"
  if(!isSSR) {
    Scrollbar.initAll();
  }
}, []);

while .wrap-overflow is the scroller I tried using. I don't think it can work without a custom scroller, because:

659299033_ScreenShot2020-08-01at2_10_16AM.png.353d554c1e683dc571d148b1a5d893bf.png

.scrollable has only 100vh height (750px on my screen) and .scroll-content has the actual height of the page (around 3300px) - this is how Smooth Scroller works/needs to work.

 

My guess here is that somehow GSAP is listening to the browsers default scrollbar, that isn't scrolling at all, because it is 'overlapped' by the Smooth Scroller scrollbar? Hope I'm not crazy, it's pretty late where I live, lol.

 

Anyways, hopefully I explained this well enough, not sure if this is/should be your expertise anyhow (using third-party plugins with Scroll Trigger). 

 

I can take the answer that these two can't simply work together, but I'd really appreciate any ideas that can make it happen tho.

 

Oh, btw, this is what I got (the Smooth Scroller works but the animation isn't 😞

1098526319_ScreenShot2020-08-01at2_06_07AM.png.2073b78d814319d76719cbf833843385.png

Link to comment
Share on other sites

Hi, Smooth Scrollbar can work with ScrollTrigger.

 

You need to use the ScrollTrigger.scrollerProxy() to keep ScrollTrigger and Smooth Scrollbar in sync.

 

Here is a simplified code example how it should be done.

 

// init Smooth Scrollbar with options
let bodyScrollBar = Scrollbar.init(selector, options);

ScrollTrigger.scrollerProxy("body", {
  scrollTop(value) {
    if (arguments.length) {
      bodyScrollBar.scrollTop = value;
    }
    return bodyScrollBar.scrollTop;
  }
});

// update ScrollTrigger when scrollbar updates
bodyScrollBar.addListener(ScrollTrigger.update);
Quote

Hey ScrollTrigger, whenever you want to get or set the scrollTop on the body, use these methods instead.

 

Hope that helps. 

  • Like 2
Link to comment
Share on other sites

  • 1 month later...

Hello, I have the very similar setup (Gatsby, ScrollTrigger and smooth-scrollbar) but the given solution doesnt work for me - I can see scroller-start and scroller-end markers following the scrolled screen but not the markers of the animated element. I can see markers of the animated element only if I add scroller property to it but then scroller-start and scroller-end dont follow the screen.
 

Also I tried to make some console.logs inside this scrollTop function but it looks like it doesn't work too.

  useEffect(() => {
    const bodyScrollBar = Scrollbar.init(box.current)

    ScrollTrigger.scrollerProxy("body", {
      scrollTop(value) {
        if (arguments.length) {
          bodyScrollBar.scrollTop = value
        }
        console.log('test')
        return bodyScrollBar.scrollTop
      },
    })

    bodyScrollBar.addListener(ScrollTrigger.update)
  }, [])

What could be my problem?

@andsavu Would you like to share your code that is working for you? Thanks in advance

Link to comment
Share on other sites

@mimoid-prog

It's been a while since I worked on this but:

 

import React, { useEffect } from "react";
import Header from "../components/header";
import Scrollbar from 'smooth-scrollbar';
import {TweenMax, TimelineLite, Power3} from 'gsap';
import gsap from 'gsap';
import ReactDOM from 'react-dom';
import { Component } from 'react';
import { ScrollTrigger } from "gsap/ScrollTrigger"
 
export default function About() {
 
useEffect(() => {
const isSSR = typeof window === "undefined"
if(!isSSR) {
 
let scrollPositionX = 0,
scrollPositionY = 0,
bodyScrollBar = Scrollbar.init(document.querySelector('#my-scrollbar'));
 
bodyScrollBar.addListener(({ offset }) => {
scrollPositionX = offset.x;
scrollPositionY = offset.y;
});
 
bodyScrollBar.setPosition(0, 0);
bodyScrollBar.track.xAxis.element.remove();
gsap.registerPlugin(ScrollTrigger);
ScrollTrigger.scrollerProxy("body", {
scrollTop(value) {
if (arguments.length) {
bodyScrollBar.scrollTop = value;
}
return bodyScrollBar.scrollTop;
}
});
 
bodyScrollBar.addListener(ScrollTrigger.update);
 
}
}, []);
 
useEffect(() => {
 
gsap.to('body', 0, {css: {visibility: 'visible'}});
 
const tl = gsap.timeline();
 
tl.from('.line span',1.6, { y: 400,ease: Power3.easeOut,delay: .2,skewY: 7,stagger: { amount: 0.3 },})
.from('.line_small span',1.2, { y: 100,ease: Power3.easeOut,
delay: .2,skewY: 7,stagger: { amount: 0.3 }}, .1)
;
 
gsap.registerPlugin(ScrollTrigger);
gsap.to('.image_float', {
scrollTrigger: {
trigger: '.h_trigger',
start: '-100px top',
end:'bottom top',
scrub: .1,
id: 'image-float'
},
y: -50,
ease: 'none',
duration: 2
});
gsap.to('.line', {
scrollTrigger: {
trigger: '.h_trigger',
start: '-100px top',
end:'center top',
scrub: .1,
id: 'lines'
},
y: -50,
ease: 'none',
duration: 2
});
 
}, [])


 
return (

 

sorry, I've got some other things there but I guess this is it:

 

 
useEffect(() => {
const isSSR = typeof window === "undefined"
if(!isSSR) {
 
let scrollPositionX = 0,
scrollPositionY = 0,
bodyScrollBar = Scrollbar.init(document.querySelector('#my-scrollbar'));
 
bodyScrollBar.addListener(({ offset }) => {
scrollPositionX = offset.x;
scrollPositionY = offset.y;
});
 
bodyScrollBar.setPosition(0, 0);
bodyScrollBar.track.xAxis.element.remove();
gsap.registerPlugin(ScrollTrigger);
ScrollTrigger.scrollerProxy("body", {
scrollTop(value) {
if (arguments.length) {
bodyScrollBar.scrollTop = value;
}
return bodyScrollBar.scrollTop;
}
});
 
bodyScrollBar.addListener(ScrollTrigger.update);
 
}
}, []);

 

and don't forget this:

 

gsap.registerPlugin(ScrollTrigger);

 

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

I copy pasted this bit into my Gatsby project and the page won't even scroll ! I don't get what in doing wrong ughhh 

 

useEffect(() => {
const isSSR = typeof window === "undefined"
if(!isSSR) {
 
let scrollPositionX = 0,
scrollPositionY = 0,
bodyScrollBar = Scrollbar.init(document.querySelector('#my-scrollbar'));
 
bodyScrollBar.addListener(({ offset }) => {
scrollPositionX = offset.x;
scrollPositionY = offset.y;
});
 
bodyScrollBar.setPosition(0, 0);
bodyScrollBar.track.xAxis.element.remove();
gsap.registerPlugin(ScrollTrigger);
ScrollTrigger.scrollerProxy("body", {
scrollTop(value) {
if (arguments.length) {
bodyScrollBar.scrollTop = value;
}
return bodyScrollBar.scrollTop;
}
});
 
bodyScrollBar.addListener(ScrollTrigger.update);
 
}
}, []);
 
useEffect(() => {
 
gsap.to('body', 0, {css: {visibility: 'visible'}});
 
const tl = gsap.timeline();
 
tl.from('.line span',1.6, { y: 400,ease: Power3.easeOut,delay: .2,skewY: 7,stagger: { amount: 0.3 },})
.from('.line_small span',1.2, { y: 100,ease: Power3.easeOut,
delay: .2,skewY: 7,stagger: { amount: 0.3 }}, .1)
;
 
gsap.registerPlugin(ScrollTrigger);
gsap.to('.image_float', {
scrollTrigger: {
trigger: '.h_trigger',
start: '-100px top',
end:'bottom top',
scrub: .1,
id: 'image-float'
},
y: -50,
ease: 'none',
duration: 2
});
gsap.to('.line', {
scrollTrigger: {
trigger: '.h_trigger',
start: '-100px top',
end:'center top',
scrub: .1,
id: 'lines'
},
y: -50,
ease: 'none',
duration: 2
});
 
}, [])


 
return (

 

sorry, I've got some other things there but I guess this is it:

 

 
useEffect(() => {
const isSSR = typeof window === "undefined"
if(!isSSR) {
 
let scrollPositionX = 0,
scrollPositionY = 0,
bodyScrollBar = Scrollbar.init(document.querySelector('#my-scrollbar'));
 
bodyScrollBar.addListener(({ offset }) => {
scrollPositionX = offset.x;
scrollPositionY = offset.y;
});
 
bodyScrollBar.setPosition(0, 0);
bodyScrollBar.track.xAxis.element.remove();
gsap.registerPlugin(ScrollTrigger);
ScrollTrigger.scrollerProxy("body", {
scrollTop(value) {
if (arguments.length) {
bodyScrollBar.scrollTop = value;
}
return bodyScrollBar.scrollTop;
}
});
 
bodyScrollBar.addListener(ScrollTrigger.update);
 
}
}, []);
Link to comment
Share on other sites

Hey , yeah my bad I've been reading gsap forums for a while but that was my first reply - completely slipped my mind inspite of knowing the rules.

Anyway I got smooth scroll working on my project with the help of another library called asscroll. Still have no clue why it wouldn't work with bodyScroll. Oh well thanks for the reply :)) 

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