Normalize scrolling speed across browsers/devices
darsain opened this issue · 12 comments
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.
this plugin is no problem on mac.
demos: http://manos.malihu.gr/tuts/jquery_custom_scrollbar.html
home: http://manos.malihu.gr/jquery-custom-content-scroller
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.
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.
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 :)
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
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.
another thing, don't forget refresh your tag of version 1.1.0.
bower only have 1.0.2 right now.
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.
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 as450+
.
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.
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.
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!
v1.2.0 landed including the aforementioned fix. Gonna close this one. If more issues come up, feel free to post them here.