Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize scrolling speed across browsers/devices #67

Closed
darsain opened this issue Jun 11, 2013 · 12 comments
Closed

Normalize scrolling speed across browsers/devices #67

darsain opened this issue Jun 11, 2013 · 12 comments

Comments

@darsain
Copy link
Owner

darsain commented Jun 11, 2013

Continuing from PR #57

Sly is scrolling the content by the same amount of pixels/items per one mousewheel event.

The problem number one is, that this event might be a concatenation of multiple events, if scrolling is happening too fast. This is reflected in event.wheelDelta property, which is multiplied by N, where N is the number of concatenated mousewheel events. At least that's how it works in like most of the world devices/browsers.

The detection of this concatenation is highly problematic, and at the moment I don't know about any 100% reliable way how to do that. Especially considering the inconsistency of this property across devices & browsers:

evt.wheelDelta evt.detail
Safari v5/OS X 120 0
Safari v5/Win7 120 0
Chrome v11b/OS X 3 0
Chrome v11b/Win7 120 0
IE9/Win7 120 undefined
Opera v11/OS X 40 -1
Opera v11/Win7 120 -3
Firefox v4/OS X undefined -1
Firefox v4/Win7 undefined -3

Old ilustrational table of one scroll event 'up'. Copied from this stakcowerflow question.

I've tried to detect the base wheelDelta by doing modulus of wheelDelta and [120, 40, 3], but that is obviously not 100% reliable. That beign said, it worked in 99% of cases, except Macbook Trackpads (and potentially other similar devices).

Mackbook trackpad's mousewheel event reporting is something else. The base is 3, but it can go as high as 450+. That is probably because in Mackbooks, this property doesn't report a value that specifies a destination, but rather the scroll velocity that should be used to control the scrolling animation speed.

This breaks everything.

I had to revert my attempt to normalize this, because modulus base detection on Macbook would just result into a ridiculous scroll distance per one event. And there is no way around it.

So currently, Sly will move the content by set number of pixels/items per event, disregarding event concatenation altogether. This is still a problem in Mackbooks, as the mousewheel event triggered by trackpads has a very high frequency, which results into a really fast scrolling speed, inconsistent with other devices using mouse wheel.


Currently, I don't see any reasonable fix for this, and userAgent sniffing is not an option.

I guess we have to wait until browsers will decide to implement a more standardized wheel event. Currently, only FF and IE9 support it.

@kongyuan
Copy link

@darsain
Copy link
Owner Author

darsain commented Sep 11, 2013

Yes, because that plugin seems to be optimized for mac. On windows, scrolling is unbelievably slow. You have to get spasm in your middle finger to get somewhere.

@kongyuan
Copy link

I mean It's fine for every os.
and the speed is configurable if you feel too slow.
I'm using it, but I hate so much doms it add to my page, so I want change to sly.
This issue is the last obstacle for my choice.

@darsain
Copy link
Owner Author

darsain commented Sep 11, 2013

The speed is configurable even with Sly, but it isn't consistent. The general issue is the difference between events triggered by normal mouse wheel, and events triggered by stuff like trackpad on MacBooks. Normal mouse wheel triggers one low precision mousewheel event for every 100px that should be scrolled, while trackpad on MacBooks is triggering shit ton of high precision mousewheel events that are instead of pixels notifying about scroll velocity. And the both events are the same, they just have different wheelDelta and detail properties. Combine that with already high inconsistencies between mousewheel events in current browsers, and you get a situation where it is almost impossible to create a consistent wrapper around it. And now I'm just repeating the issue description above :)

I remember once browsing the code of that plugin you've linked, and not finding anything useful I'd like.

Also, I don't have a MacBook to test & compare this, so I'm relying on 2nd hand observations, documentations, and random articles on the internet. So my understanding of this might be off :)

@kongyuan
Copy link

It's middlenight in my place, I can't finish it today, but I still find something in code.
There is a little plugin named "jquery.mousewheel" write by Brandon Aaron (http://brandonaaron.net)
It wraps mousewheel event, and send second arg to callback function, stand for a normalized delta.
I hope It's helpful. I will continue tomorrow

@darsain
Copy link
Owner Author

darsain commented Sep 11, 2013

I know. I've read through jquery.mousewheel plugin. As well as some other implementations trying to handle this. None of them were really good. Most of them do a little bit more complicated version of what Sly does, but nothing that would really normalize the inconsistency between events fired by generic mouse wheel and trackpad.

jquery.mousewheel seems to be updated since I've last read through it. Gonna look into it when I'll have some time. Maybe there is something brilliant addressing the issue.

@kongyuan
Copy link

another thing, don't forget refresh your tag of version 1.1.0.
bower only have 1.0.2 right now.

@kongyuan
Copy link

malihu changed mousewheel code

    // Old school scrollwheel delta
    if ( orgEvent.wheelDelta ) {
      delta = orgEvent.wheelDelta/120;
    }
    if ( orgEvent.detail) {
      delta = -orgEvent.detail/3;
    }

It's not original edition mousewheel in malihu.
That's why malihu is scroll slow but fine in mac.

@darsain
Copy link
Owner Author

darsain commented Sep 12, 2013

That doesn't solve the trackpad issue at all. As stated in the issue description:

Mackbook trackpad's mousewheel event reporting is something else. The base is 3, but it can go as high as 450+.

So on one hand, you have a really high frequency of mousewheel events triggered by trackpad, and than you are amplifying it by dividing velocity which can be as high as 450+ by 3, effectively making it 150 times worse.

Sly is trying to level it down by normalizing delta to be only -1 or +1 per event, which is still not enough, but better than above code.

@darsain
Copy link
Owner Author

darsain commented Oct 10, 2013

So the next iteration on wheel delta normalization. I hope this one is fixing all the issues. The code is in src/sly.js.

I've set up a quick test page for it here: http://jsbin.com/InAlUh/1

Please test it in all browsers & OSs you have. Especially Macbook trackpad, and normal mouse on MacOS + Chrome.

This is only a scrolling test, dragging and touch navigation is irrelevant here.

@maximilliangeorge
Copy link

Seems to work great Darsain :) I'm gonna implement tomorrow and give it a spin.

Edit: Never mind, did it straight away. Works like a charm on my MacBook!

@darsain
Copy link
Owner Author

darsain commented Oct 31, 2013

v1.2.0 landed including the aforementioned fix. Gonna close this one. If more issues come up, feel free to post them here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants