-
Notifications
You must be signed in to change notification settings - Fork 0
/
MouseWheelMonkeyPatches.js
165 lines (150 loc) · 5.55 KB
/
MouseWheelMonkeyPatches.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/* Fix for vertical-only mouse delta in capable browsers
* by Nathan Vander Wilt, 2010 April 13. */
OpenLayers.Util.getWebKitVersion = function () {
// see also code at http://trac.webkit.org/wiki/DetectingWebKit
var extract = navigator.userAgent.match(/AppleWebKit\/([0-9.]+)/);
if (extract) {
var versionString = extract[1];
var versionComponents = versionString.split(".");
var versionNumber = 0;
var component;
for (var i = 0; i < 3; ++i) {
versionNumber *= 100;
versionNumber += parseInt(versionComponents[i]) || 0;
}
return versionNumber;
}
};
// patch to support vertical-only scrolling (applies to 2.9.1)
OpenLayers.Handler.MouseWheel.prototype.onWheelEvent = function(e) {
// make sure we have a map and check keyboard modifiers
if (!this.map || !this.checkModifiers(e)) {
return;
}
// Ride up the element's DOM hierarchy to determine if it or any of
// its ancestors was:
// * specifically marked as scrollable
// * one of our layer divs
// * the map div
//
var overScrollableDiv = false;
var overLayerDiv = false;
var overMapDiv = false;
var elem = OpenLayers.Event.element(e);
while((elem != null) && !overMapDiv && !overScrollableDiv) {
if (!overScrollableDiv) {
try {
if (elem.currentStyle) {
overflow = elem.currentStyle["overflow"];
} else {
var style =
document.defaultView.getComputedStyle(elem, null);
var overflow = style.getPropertyValue("overflow");
}
overScrollableDiv = ( overflow &&
(overflow == "auto") || (overflow == "scroll") );
} catch(err) {
//sometimes when scrolling in a popup, this causes
// obscure browser error
}
}
if (!overLayerDiv) {
for(var i=0, len=this.map.layers.length; i<len; i++) {
// Are we in the layer div? Note that we have two cases
// here: one is to catch EventPane layers, which have a
// pane above the layer (layer.pane)
if (elem == this.map.layers[i].div
|| elem == this.map.layers[i].pane) {
overLayerDiv = true;
break;
}
}
}
overMapDiv = (elem == this.map.div);
elem = elem.parentNode;
}
// Logic below is the following:
//
// If we are over a scrollable div or not over the map div:
// * do nothing (let the browser handle scrolling)
//
// otherwise
//
// If we are over the layer div:
// * zoom/in out
// then
// * kill event (so as not to also scroll the page after zooming)
//
// otherwise
//
// Kill the event (dont scroll the page if we wheel over the
// layerswitcher or the pan/zoom control)
//
if (!overScrollableDiv && overMapDiv) {
if (overLayerDiv) {
var delta = 0;
if (!e) {
e = window.event;
}
if (e.wheelDeltaY !== undefined) {
// WebKit provides full 2-axis wheel info
delta = e.wheelDeltaY / 120;
var webkitVersion = OpenLayers.Util.getWebKitVersion();
if (webkitVersion && webkitVersion > 5330000 && webkitVersion < 5340000) {
// workaround bug in Webkit 533 - https://bugs.webkit.org/show_bug.cgi?id=40441
// caused by "fixing" https://bugs.webkit.org/show_bug.cgi?id=29601
// reverted in http://trac.webkit.org/changeset/60974
delta /= 40;
}
} else if (e.axis !== undefined) {
// Gecko provides info per axis, since FF3.5
if (e.axis == e.VERTICAL_AXIS) {
delta = -e.detail / 3;
}
} else if (e.wheelDelta) {
delta = e.wheelDelta/120;
if (window.opera && window.opera.version() < 9.2) {
delta = -delta;
}
} else if (e.detail) {
delta = -e.detail / 3;
}
this.delta = this.delta + delta;
if(this.interval) {
window.clearTimeout(this._timeoutId);
this._timeoutId = window.setTimeout(
OpenLayers.Function.bind(function(){
this.wheelZoom(e);
}, this),
this.interval
);
} else {
this.wheelZoom(e);
}
}
OpenLayers.Event.stop(e);
}
};
// also need to fix wheelChange for fractional zoom support (applies to 2.9.1)
OpenLayers.Control.Navigation.prototype.wheelChange = function(evt, deltaZ) {
var currentZoom = this.map.getZoom();
var zoomAdjust = (this.map.fractionalZoom) ? deltaZ : Math.round(deltaZ);
var newZoom = this.map.getZoom() + zoomAdjust;
newZoom = Math.max(newZoom, 0);
newZoom = Math.min(newZoom, this.map.getNumZoomLevels());
if (newZoom === currentZoom || !this.map.isValidZoomLevel(newZoom)) {
return;
}
var size = this.map.getSize();
var deltaX = size.w/2 - evt.xy.x;
var deltaY = evt.xy.y - size.h/2;
var newRes = this.map.baseLayer.getResolutionForZoom(newZoom);
var zoomPoint = this.map.getLonLatFromPixel(evt.xy);
var newCenter = new OpenLayers.LonLat(
zoomPoint.lon + deltaX * newRes,
zoomPoint.lat + deltaY * newRes );
this.map.setCenter( newCenter, newZoom );
}