Skip to content

Commit

Permalink
A different hack for reliable mousewheel.
Browse files Browse the repository at this point in the history
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
mbostock committed Apr 8, 2011
1 parent f4c3ff1 commit 4518c22
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 106 deletions.
59 changes: 38 additions & 21 deletions polymaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}

Expand Down Expand Up @@ -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);
}
Expand All @@ -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},
Expand Down
Loading

0 comments on commit 4518c22

Please sign in to comment.