Permalink
Browse files

A different hack for reliable mousewheel.

Wheel events are utterly broken. Even though WebKit's mousewheel precision bug
has been fixed, Chrome and Safari still differ in terms of mousewheel
acceleration. Safari and Firefox report the correct value (the number of pixels
that would be scrolled), but Chrome does not. I've not tested Opera or IE9.

Fortunately, we can determine exactly the number of pixels that would be
scrolled by dispatching the mousewheel event to a scrollable area, and then
observing the change in scrollTop. However, dispatching the received event is
not strictly allowed, so ignore this error and hope for the best.
  • Loading branch information...
1 parent f4c3ff1 commit 4518c22864c1c30540e45fbeeabf1940d900b4a3 @mbostock mbostock committed Apr 8, 2011
Showing with 140 additions and 106 deletions.
  1. +38 −21 polymaps.js
  2. +64 −64 polymaps.min.js
  3. +38 −21 src/Wheel.js
View
@@ -1575,26 +1575,46 @@ po.wheel = function() {
location = null;
}
+ // mousewheel events are totally broken!
+ // https://bugs.webkit.org/show_bug.cgi?id=40441
+ // not only that, but Chrome and Safari differ in re. to acceleration!
+ var inner = document.createElement("div"),
+ outer = document.createElement("div");
+ outer.style.visibility = "hidden";
+ outer.style.top = "0px";
+ outer.style.height = "0px";
+ outer.style.width = "0px";
+ outer.style.overflowY = "scroll";
+ inner.style.height = "2000px";
+ outer.appendChild(inner);
+ document.body.appendChild(outer);
+
function mousewheel(e) {
- var delta = (e.wheelDelta / 120 || -e.detail) * .1,
+ var delta = e.wheelDelta || -e.detail,
point;
- /* Detect fast & large wheel events on WebKit. */
- if (bug40441 < 0) {
- var now = Date.now(), since = now - last;
- if ((since > 9) && (Math.abs(e.wheelDelta) / since >= 50)) bug40441 = 1;
- last = now;
- }
- if (bug40441 == 1) delta *= .03;
+ /* Detect the pixels that would be scrolled by this wheel event. */
+ if (delta) {
+ if (smooth) {
+ try {
+ outer.scrollTop = 1000;
+ outer.dispatchEvent(e);
+ delta = 1000 - outer.scrollTop;
+ } catch (error) {
+ // Derp! Hope for the best?
+ }
+ delta *= .005;
+ }
- /* If smooth zooming is disabled, batch events into unit steps. */
- if (!smooth && delta) {
- var timeNow = Date.now();
- if (timeNow - timePrev > 200) {
- delta = delta > 0 ? +1 : -1;
- timePrev = timeNow;
- } else {
- delta = 0;
+ /* If smooth zooming is disabled, batch events into unit steps. */
+ else {
+ var timeNow = Date.now();
+ if (timeNow - timePrev > 200) {
+ delta = delta > 0 ? +1 : -1;
+ timePrev = timeNow;
+ } else {
+ delta = 0;
+ }
}
}
@@ -1643,7 +1663,7 @@ po.wheel = function() {
if (map) {
container.removeEventListener("mousemove", move, false);
container.removeEventListener("mousewheel", mousewheel, false);
- container.removeEventListener("DOMMouseScroll", mousewheel, false);
+ container.removeEventListener("MozMousePixelScroll", mousewheel, false);
container = null;
map.off("move", move);
}
@@ -1652,16 +1672,13 @@ po.wheel = function() {
container = map.container();
container.addEventListener("mousemove", move, false);
container.addEventListener("mousewheel", mousewheel, false);
- container.addEventListener("DOMMouseScroll", mousewheel, false);
+ container.addEventListener("MozMousePixelScroll", mousewheel, false);
}
return wheel;
};
return wheel;
};
-
-// https://bugs.webkit.org/show_bug.cgi?id=40441
-var bug40441 = /WebKit\/533/.test(navigator.userAgent) ? -1 : 0;
po.arrow = function() {
var arrow = {},
key = {left: 0, right: 0, up: 0, down: 0},
Oops, something went wrong.

0 comments on commit 4518c22

Please sign in to comment.