Jump to content
GreenSock

Visual-Q

Smooth transition from mousewheel scroll to scrollTo?

Recommended Posts

This is a followup to my previous post. I've created a scroll helper it's fired by a scrollMajic trigger and callback to a scroll function I made with GSAP. The main tween is:

 

TweenMax.to(window, duration, {scrollTo:{y:item, offsetY:calculateOffset + offset,autoKill:false},delay:delay,ease:ease});

 

At the transition point between user scroll and scrollTo taking over there is noticeable jitter before scrollTo wins control and runs, autoKill:false is working but it's not instantaneous. I'm guessing perhaps this is due to scrollTo trying to take over scroll at the same time as there are pending mousewheel scroll events attempting to fire?

 

In my case I'm using an apple Majic Mouse which presumably broadcasts a lot of scroll events having what is essentially a touchpad not a wheel so maybe it wouldn't happen on a normal wheel mouse, though I expect a hyperscrolling mouse would probably do the same thing.

 

Before I try and make a pen for testing I thought i'd  put this out to the big guns around here for advice to see if maybe the issue has been encountered before and solved already?

 

 

 

Link to comment
Share on other sites

To update I have solved the problem apparently by applying a mousewheel cancelling function before I call the scrollTo and then re-enabling mouswheel scroll after the scrollTo is complete instead of relying on autoKill:false.

 

So here is my first feature request, if it is possible I would suggest trying to make autoKill:false more robust so it cancels scroll events completely even if the user is actively scrolling before scrollTo starts to scroll the window.

 

 

Link to comment
Share on other sites

Just to chime in @Visual-Q, some scroll events, depending on how they were trigered, cannot be cancelled. It might be outside GSAP's reach. @GreenSock himself will be able to confirm that.

 

In the meantime, this article has some useful information about how browsers handle scroll.

 

https://blogs.windows.com/msedgedev/2017/03/08/scrolling-on-the-web/#lvzozB8m1fZOWgTt.97

  • Like 6
  • Thanks 1
Link to comment
Share on other sites

Thanks Dipscom. Looks like a very useful article.

 

I don't know how scroll cancelling is handled by gsap. In fact I don't much about scroll cancelling at all. To fix the problem for my instance I just used some found code that I modified into enable and disable functions.

 

I run the disable function just before GSAP scrollTo and enable onComplete or in a timeout the length of the scrollTo tween. Seems to work I still have to do complete browser testing to check reliability.

 

function disableMouseWheel(){
//Blocking the Mouse Wheel
document.onmousewheel = function(){ stopWheel(); } /* IE7, IE8 */
if(document.addEventListener){ /* Chrome, Safari, Firefox */
    document.addEventListener('DOMMouseScroll', stopWheel, false);
}
}

//Re-enabling the Wheel
function enableMouseWheel(){  
document.onmousewheel = null;  /* IE7, IE8 */
if(document.addEventListener){ /* Chrome, Safari, Firefox */
    document.removeEventListener('DOMMouseScroll', stopWheel, false);
}
}


function stopWheel(e){
    if(!e){ e = window.event; } /* IE7, IE8, Chrome, Safari */
    if(e.preventDefault) { e.preventDefault(); } /* Chrome, Safari, Firefox */
    e.returnValue = false; /* IE7, IE8 */
}

 

 

  • Like 1
Link to comment
Share on other sites

Quote

...if it is possible I would suggest trying to make autoKill:false more robust so it cancels scroll events completely even if the user is actively scrolling before scrollTo starts to scroll the window.

1

 

Quote

...some scroll events, depending on how they were trigered, cannot be cancelled

 

I should have probably been more precise is my request, I was principally referring to wheel/touch scrolling not necessarily all scrolling. 

 

Attempting to disable scrollbars is probably not necessary unless something about user scroll might screw up presentation. I interpret direct scroll bar interaction as an emphatic "I want control" by the user, so it's probably a good idea to let them have it.

 

 

Link to comment
Share on other sites

On 2/26/2018 at 10:36 AM, Visual-Q said:

I don't know how scroll cancelling is handled by gsap.

 

Just to clarify, I'm pretty sure GSAP doesn't **ever** cancel scrolling that's initiated outside of GSAP. ScrollToPlugin just checks to see if something **outside of itself** changes the scroll position while tweening, and if so, it'll kill that part of the tween. That's it. We really try not to over-reach. And my personal opinion was that if a user tries to scroll during an animation, it'd be super annoying if it was disallowed (from the user's perspective). I'd wonder if something was broken. That's why I made autoKill the default behavior. But feel free to disable that if you prefer. :)

  • Like 1
Link to comment
Share on other sites

Thanks for the response Jack. Actually I wasn't highlighting a problem with the concept of autoKill:true or if it should be the default. 

 

It's more about autoKill:false. In this case I think you are definitely defining that you want to suspend normal scroll interaction at least mousewheel scroll. And that is what it does, so we're fine here.

 

In a specific usage case like the one I encountered, autoKill:false appeared not to immediately intercept scrolling prior to scrollTo running if the user is actively scrolling. This caused some jitter as the two appeared to fight for control. The fix was fairly easy, I used my own function and stopped scrolling before calling scrollTo. This suggests that a similar approach might be taken with autoKill:false. 

 

I'm guessing maybe the scrollTo is recording the starting value and returning to it, before autoKill:false is cancelling scroll interaction and if there is a momentary overscroll by the user before autoKill:false kicks in this causes the jitter.

Link to comment
Share on other sites

On 2/28/2018 at 4:33 PM, Visual-Q said:

I'm guessing maybe the scrollTo is recording the starting value and returning to it, before autoKill:false is cancelling scroll interaction and if there is a momentary overscroll by the user before autoKill:false kicks in this causes the jitter.

 

Actually it just gets the current value and if it senses that it's not what it had just set it to on the previous render (within the threshold), it'll just set it to the current value. It doesn't set it to the tween's scrolling value at all in that case. Not quite sure what might be causing that jitter, but I'm glad you figured out a workaround. I'm quite reluctant to wire in something that'd literally block the mouse wheel (or other scrolling) since it seems so invasive and possibly headache-causing for users (?) but I'll definitely keep my ears open and if enough people are saying that's what they want, it'll give me the confidence to just force it anyway :)

 

Thanks for the feedback/discussion. Sorry for the late reply. 

Link to comment
Share on other sites

The jitter is probably caused by your touchpad. They are usually very sensitive, so simply removing your finger from it could be triggering a scroll.

 

And "DOMMouseScroll" is not a standard event.

https://developer.mozilla.org/en-US/docs/Web/Events/DOMMouseScroll

 

Consider using "wheel" instead. See the example towards the bottom of this page if you want to include behavior for old browsers.

https://developer.mozilla.org/en-US/docs/Web/Events/wheel

 

  • Like 5
Link to comment
Share on other sites

Thanks @OSUblake I'll look at updating my functions to the suggested event handler.

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