Jump to content
Search Community

CustomScrollBar: Scrolltrigger, Draggable

mikel test
Moderator Tag

Recommended Posts




Based on the case below, I tried to build a custom scroll bar for a scrollable element with fixed sizes. It works ...

But if you change the window size, if the scroll progress is not equal to 0 or 1, then the drag function is disturbed.


See the Pen c889651f79b9848c71f4a918e94471a8?editors=0010 by mikeK (@mikeK) on CodePen


What am I doing wrong?


See the Pen 896549f0a83297debd9111fe9b205a97?editors=1010 by GreenSock (@GreenSock) on CodePen

Link to comment
Share on other sites

Hey mikel. Even with your current sizing the scroll distance and drag distance don't match up. Try scrolling to the end then dragging - it jumps because the bounds are different.


I was able to convert the original pen you linked to your format like so. You should be able to compare your code with this code to see any differences:

const handler = document.querySelector("#handler");
const scroller = document.querySelector("#scroller");
let barLength, maxScroll, trigger, draggable;

// this ScrollTrigger will use the window/<body> by default, calling onRefresh when the page resizes, and onUpdate whenever any scroll happens. 
trigger = ScrollTrigger.create({
  scroller: scroller,
  onRefresh: onResize,
  onUpdate: updateHandler

draggable = Draggable.create(handler, {
  type: "y",
  bounds: ".bar",
  onDrag: function() {
    trigger.scroll(this.y / barLength * maxScroll); // when dragging, scroll the page to the corresponding ratio

function onResize() {
  if (trigger) {
    maxScroll = ScrollTrigger.maxScroll(scroller); // record the maximum scroll value for the page
    barLength = document.querySelector(".bar").offsetHeight - handler.offsetHeight; 

function updateHandler() {
  // move the handler to the corresponding ratio according to the page's scroll position.
  gsap.set(handler, {y: barLength * trigger.scroll() / maxScroll});


  • Like 2
Link to comment
Share on other sites

48 minutes ago, mikel said:

It doesn't work for me

Weird. What OS and browser are you using?


49 minutes ago, mikel said:

Why do you need an onRefresh when the page resizes?

You can remove the onRefresh listener if this is always going to be the same size. I just included it as part of converting the old demo. If you do remove it, make sure to get the values that you need on load.

Link to comment
Share on other sites

The problem is that you don't have a start or end on the ScrollTrigger, nor do you have a trigger, so it's defaulting to using the <body> as the trigger and a start of "top top". You're translating the nested element such that it goes beyond the top of the <body>, effectively making the <body> grow upwards beyond the viewport. So when you resize and it does a refresh to recalculate where the start/end positions are, it's setting them such that the ScrollTrigger won't get triggered until further down. You'll see that the onUpdate isn't firing. 



Just add start: 0, end: "max" to your ScrollTrigger. 


I'll also update ScrollTrigger for the next release so that when there's no trigger or "start" defined at all, it'll just default to start: 0 (numeric, absolute). That change is made in the latest beta: https://assets.codepen.io/16327/ScrollTrigger.min.js

  • Like 3
Link to comment
Share on other sites

Hey Jack,

Hey Zach,


Great - runs perfectly. Thank you JACK.


See the Pen RwGLYxE?editors=1010 by mikeK (@mikeK) on CodePen


See the Pen RwGLOmm?editors=0100 by mikeK (@mikeK) on CodePen

I often get irritated by defaults. And I couldn't believe that the default for trigger is the <body> (no reference in the DOCs).

Even if it was explicitly stated in the example.
For my level, this maxim is better: What you code is what you get! And if I forget required properties, I get a warning.
Sure, I see the convenience of defaults. However, they don't always make sense for individual designs.

And there is the possibility to set general defaults yourself if you need hundreds of similar animations.


The defaults for today: Silent Night! Holy Night!


Link to comment
Share on other sites

  • 1 year later...
25 minutes ago, Diego Gnoatto said:

i tried to use this technique to add a custom scroll bar on scroll smoother project but i couldnt sincronize both, didnt find any example with scrollsmoother , any tips?

Sorry, @Diego Gnoatto - can you elaborate a bit? It's probably best to start a new thread and ask a specific question with a very clear minimal demo (like a CodePen). We'd be happy to answer any GSAP-specific questions. 👍

Link to comment
Share on other sites

i notice scrollsmoother is synchronized with the window object using scrollto plugin, so i thought... would be cool to create a custom scroll bar that is synchronized with scrollSmoother #scroll-content, at the end i thought i could use this example to gimme insights of how to accomplish this but i couldn't, thats why i asked here , maybe there is an example i couldn't find by myself of a scroll-smoother in sync with a custom scrollbar.

sorry for no demo but i don't know where to start

Link to comment
Share on other sites

We love helping with GSAP-related questions, but unfortunately we just don't have the resources to provide free general consulting, logic troubleshooting, or "how do I create this custom effect?" tutorials. Of course anyone else is welcome to post an answer if they'd like - we just want to manage expectations.  


You can post in the "Jobs & Freelance" forum for paid consulting, or contact us directly. 

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