Let OpenLayers send less tile requests to the server when wheel-zooming.
+
+
+
+
+
This example shows how to configure the Navigation control to use
+ the mousewheel in a less server resource consuming way: as long as you
+ spin the mousewheel, no request will be sent to the server. Instead,
+ the zoomlevel delta will be recorded. After a delay (in this example
+ 100ms), a zoom action with the cumulated delta will be performed.
+
+
+
\ No newline at end of file
diff --git a/lib/OpenLayers/Control/Navigation.js b/lib/OpenLayers/Control/Navigation.js
index b3c2209d0b..4ed7eab56d 100644
--- a/lib/OpenLayers/Control/Navigation.js
+++ b/lib/OpenLayers/Control/Navigation.js
@@ -46,7 +46,14 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
* APIProperty: zoomWheelEnabled
* {Boolean} Whether the mousewheel should zoom the map
*/
- zoomWheelEnabled: true,
+ zoomWheelEnabled: true,
+
+ /**
+ * Property: mouseWheelOptions
+ * {Object} Options passed to the MouseWheel control (only useful if
+ * is set to true)
+ */
+ mouseWheelOptions: null,
/**
* APIProperty: handleRightClicks
@@ -159,7 +166,8 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
this.zoomBox.draw();
this.handlers.wheel = new OpenLayers.Handler.MouseWheel(
this, {"up" : this.wheelUp,
- "down": this.wheelDown} );
+ "down": this.wheelDown},
+ this.mouseWheelOptions );
},
/**
@@ -192,8 +200,11 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
* deltaZ - {Integer}
*/
wheelChange: function(evt, deltaZ) {
+ var currentZoom = this.map.getZoom();
var newZoom = this.map.getZoom() + deltaZ;
- if (!this.map.isValidZoomLevel(newZoom)) {
+ newZoom = Math.max(newZoom, 0);
+ newZoom = Math.min(newZoom, this.map.getNumZoomLevels());
+ if (newZoom === currentZoom) {
return;
}
var size = this.map.getSize();
@@ -213,9 +224,10 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
*
* Parameters:
* evt - {Event}
+ * delta - {Integer}
*/
- wheelUp: function(evt) {
- this.wheelChange(evt, 1);
+ wheelUp: function(evt, delta) {
+ this.wheelChange(evt, delta || 1);
},
/**
@@ -224,9 +236,10 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
*
* Parameters:
* evt - {Event}
+ * delta - {Integer}
*/
- wheelDown: function(evt) {
- this.wheelChange(evt, -1);
+ wheelDown: function(evt, delta) {
+ this.wheelChange(evt, delta || -1);
},
/**
diff --git a/lib/OpenLayers/Handler/MouseWheel.js b/lib/OpenLayers/Handler/MouseWheel.js
index 2be61e385b..13c3b7e11b 100644
--- a/lib/OpenLayers/Handler/MouseWheel.js
+++ b/lib/OpenLayers/Handler/MouseWheel.js
@@ -28,6 +28,23 @@ OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
*/
mousePosition: null,
+ /**
+ * Property: interval
+ * {Integer} In order to increase server performance, an interval (in
+ * milliseconds) can be set to reduce the number of up/down events
+ * called. If set, a new up/down event will not be set until the
+ * interval has passed.
+ * Defaults to 0, meaning no interval.
+ */
+ interval: 0,
+
+ /**
+ * Property: delta
+ * {Integer} When interval is set, delta collects the mousewheel z-deltas
+ * of the events that occur within the interval.
+ */
+ delta: 0,
+
/**
* Constructor: OpenLayers.Handler.MouseWheel
*
@@ -138,7 +155,31 @@ OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
//
if (!overScrollableDiv && overMapDiv) {
if (overLayerDiv) {
- this.wheelZoom(e);
+ var delta = 0;
+ if (!e) {
+ e = window.event;
+ }
+ 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);
}
@@ -153,19 +194,9 @@ OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
* e - {Event}
*/
wheelZoom: function(e) {
+ var delta = this.delta;
+ this.delta = 0;
- var delta = 0;
- if (!e) {
- e = window.event;
- }
- 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;
- }
if (delta) {
// add the mouse position to the event because mozilla has
// a bug with clientX and clientY (see
diff --git a/tests/Handler/MouseWheel.html b/tests/Handler/MouseWheel.html
index f5b4933f3a..a371962bca 100644
--- a/tests/Handler/MouseWheel.html
+++ b/tests/Handler/MouseWheel.html
@@ -62,12 +62,19 @@
}
function test_Handler_MouseWheel_events(t) {
- t.plan(5);
+ t.plan(6);
var map = new OpenLayers.Map('map');
+ map.addLayer(new OpenLayers.Layer.WMS("","",{}));
+ map.zoomToMaxExtent();
var control = new OpenLayers.Control();
map.addControl(control);
- var handler = new OpenLayers.Handler.MouseWheel(control);
+ var deltaZ;
+ var handler = new OpenLayers.Handler.MouseWheel(control, {
+ 'up': function(evt, delta){
+ deltaZ = delta;
+ }
+ }, {interval: 200});
// list below events that should be handled (events) and those
// that should not be handled (nonevents) by the handler
@@ -99,6 +106,15 @@
}
var activated = handler.activate();
+
+ var delta = 120;
+ if (window.opera && window.opera.version() < 9.2) delta = -delta;
+ handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});
+ handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});
+ t.delay_call(1, function() {
+ t.eq(deltaZ, 2, "Multiple scroll actions triggered one event when interval is set");
+ });
+
}