From ebc5d7c021a4ef03b1f16f4b965aa9f4e9ec0e14 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Mon, 16 Nov 2009 10:38:26 +0000 Subject: [PATCH] added option to the MouseWheel handler to trigger up/down events only when wheel is released. r=elemoine (closes #2345) git-svn-id: http://svn.openlayers.org/trunk/openlayers@9799 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/mousewheel-interval.html | 43 +++++++++++++++++++++ lib/OpenLayers/Control/Navigation.js | 27 +++++++++---- lib/OpenLayers/Handler/MouseWheel.js | 57 +++++++++++++++++++++------- tests/Handler/MouseWheel.html | 20 +++++++++- 4 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 examples/mousewheel-interval.html diff --git a/examples/mousewheel-interval.html b/examples/mousewheel-interval.html new file mode 100644 index 0000000000..c5b11570be --- /dev/null +++ b/examples/mousewheel-interval.html @@ -0,0 +1,43 @@ + + + OpenLayers Mousewheel Interval Example + + + + + + +

OpenLayers Mousewheel Interval Example

+ +
+ +
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"); + }); + }