Jump to content
Search Community

ScrollTrigger : Pinning causes jitter when using touch (& on Safari)

noahr test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi there,

I keep running into a small problem:

In Chrome pinning with ScrollTrigger runs wonderfully, however, on Safari (both, iOS & macOS) an on Chrome/Android it keeps vertically jittering while its pinned. 

 

Excuse the weird layout in my codepen demo - I tried sticking to the original as well as I could and for me the preproduction worked like this.

I suspect it might be some CSS issue since I reduced the JS to a bare minimum?

 

Thanks a lot for your help!

See the Pen ZEjWwNd by fltng (@fltng) on CodePen

Link to comment
Share on other sites

Hi @noahr. Welcome to the forums!

 

I couldn't reproduce any jitter at all on MacOS (Chrome or Safari). iOS actually handles scrolling in a completely non-synchronized way which is super annoying - scrolling happens on a separate thread, so the browser renders things graphically as if the page scrolled, but then the JS thread executes and ScrollTrigger positions the "pinned" element correctly. That's normally not an issue because pinned elements have position: fixed but in your case you're using a custom scroller (instead of the <body>), thus ScrollTrigger is forced to use transforms to do the pinning and that requires an update for every single scroll. Do you need to use a custom scroller element? 

 

ScrollTrigger.normalizeScroll({ allowNestedScroll: true }) may help, especially on iOS devices. The normalizeScroll feature represents many hundreds of hours of effort we put into solving this whole iOS jitter issue that's caused by Apple's buggy scroll behavior. It's not a silver bullet, but sometimes it drastically improves things in certain scenarios. 

 

Try adding this to your demo and let us know if it resolves things for you: 

document.querySelector(".scroller").addEventListener("scroll", ScrollTrigger.update);

Any better? 

Link to comment
Share on other sites

 I discovered something else that's very interesting - Firefox (and maybe some other browsers) appears to repaint scrolls less consistently if you don't have anything queued in requestAnimationFrame(). SUPER weird. For example, the intermittent glitchy scroll repaints vanished as soon as I did something like this: 

function rafFix() {
  requestAnimationFrame(rafFix);
};
rafFix();

🤷‍♂️ 

Link to comment
Share on other sites

Happy new year! And thanks so much for the detailed replies.

I tried ScrollTrigger.normalizeScroll({ allowNestedScroll: true }) as well as ScrollTrigger.update, however unfortunately both tests came out without any changes for the better. I could only test them using an Android (13) device with Chrome (108), but I get the same jittery behavior there, too. (To specify again: it basically jiggles up and down while I pull my finger up/down on the screen, instead of just staying pinned down still). 

One noteworthy thing I totally forgot to mention:
Something that completely fixes this issue is when I use 'smooth-scrollbar'. Makes the pinning super smooth on all devices I used for testing, also mac/iOS. I don't really know why though and I would like to refrain from using any form of scroll jacking. 

Link to comment
Share on other sites

Just to confirm, are you saying that you added this exact line and it did nothing to help?: 

document.querySelector(".scroller").addEventListener("scroll", ScrollTrigger.update);

You could also try this (touchmove): 

document.querySelector(".scroller").addEventListener("touchmove", ScrollTrigger.update);

And did you try the rafFix() that I mentioned above as well? 

 

1 hour ago, noahr said:

Something that completely fixes this issue is when I use 'smooth-scrollbar'. Makes the pinning super smooth on all devices I used for testing, also mac/iOS. I don't really know why though and I would like to refrain from using any form of scroll jacking. 

Yeah, I assume it would also resolve things if you used our ScrollSmoother because the scrolling would be handled on the main thread. Any scroll-jacking solution does that. And the crux of the issue has to do with the fact that many browsers handle scrolling on a totally separate (and not synchronized) thread.

 

1 hour ago, noahr said:

Happy new year!

🥳

Link to comment
Share on other sites

  • Solution

Aha, I believe I figured it out. Two things: 

  1. I forgot to tell you to set the "target" of the normalizeScroll() config because you're doing the non-standard thing of using an element as the scroller that's not the <body> (default). Like: 
    ScrollTrigger.normalizeScroll({ target: ".scroller", allowNestedScroll: true })

     

  2. When the scroll value gets updated, it needs to force an update of all the ScrollTriggers immediately. That has been added to the next release of ScrollTrigger which you can preview at https://assets.codepen.io/16327/ScrollTrigger.min.js

    But in the meantime, you can add this workaround: 
    ScrollTrigger.addEventListener("scrollStart", () => gsap.ticker.add(ScrollTrigger.update));
    ScrollTrigger.addEventListener("scrollEnd", () => gsap.ticker.remove(ScrollTrigger.update));

Sorry about any confusion there. I hope this clears things up. 

  • Like 2
Link to comment
Share on other sites

Oh yes, that solved it, it's running infinitely smoother now. This was the very crucial line:

ScrollTrigger.normalizeScroll({ target: ".scroller", allowNestedScroll: true })

I'll have to try it on the other devices soon, too, but it's looking super promising on Android. Thanks so much for your great help!

  • Like 1
Link to comment
Share on other sites

...one more thing that I just realized is that the solution unfortunately breaks the native smooth-scrolling behavior (only an issue for mouse wheel scrolling). Basically I get frame-jumps instead of seeing the vertical movement of the page. 

Here the demo again, if you comment out ScrollTrigger.normalizeScroll({ target: ".scroller", allowNestedScroll: true }), mousewheel scrolling will be smoother again.

Do you maybe have an idea how to bring that back while allowing nested scroll, too?
Here's a topic I just found that seems to be super close to mine: 

Thanks a lot, I appreciate your effort!

Link to comment
Share on other sites

2 hours ago, noahr said:

...one more thing that I just realized is that the solution unfortunately breaks the native smooth-scrolling behavior (only an issue for mouse wheel scrolling). Basically I get frame-jumps instead of seeing the vertical movement of the page. 

Here the demo again, if you comment out ScrollTrigger.normalizeScroll({ target: ".scroller", allowNestedScroll: true }), mousewheel scrolling will be smoother again.

Sorry, I'm a little lost - are you saying you don't see any momentum scrolling when normalizeScroll() is enabled? I am seeing momentum scroll just fine on all my devices, all browsers so far. What am I missing? Is there a secret to getting it to break? What browser and device? 

 

And what do you mean by "frame jumps"? 

Link to comment
Share on other sites

Oh, you must be on windows. That's an OS-level setting I believe. ScrollTrigger.normalizeScroll() can't possibly know the system settings or perfectly mimic every setting - it simply takes whatever the wheel event tells it (event.deltaY) and applies that to the scroll movement. But you could try setting wheelSpeed to something smaller, like wheelSpeed: 0.2 for example (in the normalizeScroll() config). But you'd want to only do that on Windows systems I'd guess. 

 

And of course you could use ScrollSmoother to smooth out scrolling. It's totally integrated with GSAP. It's a membership benefit of Club GreenSock

  • Like 1
Link to comment
Share on other sites

Just to update, here's what fixed everything for me:

ScrollTrigger.normalizeScroll({ target: scroller, allowNestedScroll: true, type: "touch,scroll,pointer" });

I additionally excluded the normalizeScroll for wheel scroll actions with "type".

Thanks for all the help again!

  • Like 3
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...