diff --git a/src/objectliterals.exports b/src/objectliterals.exports index 3f0a1e984d..36493574b1 100644 --- a/src/objectliterals.exports +++ b/src/objectliterals.exports @@ -7,7 +7,6 @@ @exportObjectLiteralProperty ol.MapOptions.keyboardPanOffset number|undefined @exportObjectLiteralProperty ol.MapOptions.layers ol.Collection|undefined @exportObjectLiteralProperty ol.MapOptions.mouseWheelZoom boolean|undefined -@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoomDelta number|undefined @exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined @exportObjectLiteralProperty ol.MapOptions.renderers Array.|undefined @exportObjectLiteralProperty ol.MapOptions.scaleLineControl boolean|undefined diff --git a/src/ol/interaction/mousewheelzoominteraction.js b/src/ol/interaction/mousewheelzoominteraction.js index 9b49e01024..b274dd7e35 100644 --- a/src/ol/interaction/mousewheelzoominteraction.js +++ b/src/ol/interaction/mousewheelzoominteraction.js @@ -4,30 +4,63 @@ goog.provide('ol.interaction.MouseWheelZoom'); goog.require('goog.events.MouseWheelEvent'); goog.require('goog.events.MouseWheelHandler.EventType'); +goog.require('goog.math'); +goog.require('ol.Coordinate'); goog.require('ol.View2D'); goog.require('ol.interaction.Interaction'); /** - * @define {number} Zoom duration. + * @define {number} Animation duration. */ -ol.interaction.ZOOM_DURATION = 200; +ol.interaction.MOUSEWHEELZOOM_ANIMATION_DURATION = 250; + + +/** + * @define {number} Maximum delta. + */ +ol.interaction.MOUSEWHEELZOOM_MAXDELTA = 1; + + +/** + * @define {number} Timeout duration. + */ +ol.interaction.MOUSEWHEELZOOM_TIMEOUT_DURATION = 80; /** * @constructor * @extends {ol.interaction.Interaction} - * @param {number} delta The zoom delta applied on each mousewheel. */ -ol.interaction.MouseWheelZoom = function(delta) { +ol.interaction.MouseWheelZoom = function() { + + goog.base(this); + /** * @private * @type {number} */ - this.delta_ = delta; + this.delta_ = 0; + + /** + * @private + * @type {?ol.Coordinate} + */ + this.lastAnchor_ = null; + + /** + * @private + * @type {number|undefined} + */ + this.startTime_ = undefined; + + /** + * @private + * @type {number|undefined} + */ + this.timeoutId_ = undefined; - goog.base(this); }; goog.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction); @@ -37,20 +70,52 @@ goog.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction); */ ol.interaction.MouseWheelZoom.prototype.handleMapBrowserEvent = function(mapBrowserEvent) { + if (mapBrowserEvent.type == goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) { var map = mapBrowserEvent.map; var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */ (mapBrowserEvent.browserEvent); goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent); - var anchor = mapBrowserEvent.getCoordinate(); - var delta = mouseWheelEvent.deltaY < 0 ? this.delta_ : -this.delta_; - // FIXME works for View2D only - var view = map.getView(); - goog.asserts.assert(view instanceof ol.View2D); - map.requestRenderFrame(); - view.zoom(map, delta, anchor, ol.interaction.ZOOM_DURATION); + + this.lastAnchor_ = mapBrowserEvent.getCoordinate(); + this.delta_ += mouseWheelEvent.deltaY / 3; + + if (!goog.isDef(this.startTime_)) { + this.startTime_ = goog.now(); + } + + var duration = ol.interaction.MOUSEWHEELZOOM_TIMEOUT_DURATION; + var timeLeft = Math.max(duration - (goog.now() - this.startTime_), 0); + + goog.global.clearTimeout(this.timeoutId_); + this.timeoutId_ = goog.global.setTimeout( + goog.bind(this.doZoom_, this, map), timeLeft); + mapBrowserEvent.preventDefault(); mouseWheelEvent.preventDefault(); } }; + + +/** + * @private + * @param {ol.Map} map Map. + */ +ol.interaction.MouseWheelZoom.prototype.doZoom_ = function(map) { + var maxDelta = ol.interaction.MOUSEWHEELZOOM_MAXDELTA; + var delta = goog.math.clamp(this.delta_, -maxDelta, maxDelta); + + // FIXME works for View2D only + var view = map.getView(); + goog.asserts.assert(view instanceof ol.View2D); + + map.requestRenderFrame(); + view.zoom(map, -delta, this.lastAnchor_, + ol.interaction.MOUSEWHEELZOOM_ANIMATION_DURATION); + + this.delta_ = 0; + this.lastAnchor_ = null; + this.startTime_ = undefined; + this.timeoutId_ = undefined; +}; diff --git a/src/ol/map.js b/src/ol/map.js index 771122e531..0650f66a76 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -1014,10 +1014,7 @@ ol.Map.createInteractions_ = function(mapOptions) { var mouseWheelZoom = goog.isDef(mapOptions.mouseWheelZoom) ? mapOptions.mouseWheelZoom : true; if (mouseWheelZoom) { - var mouseWheelZoomDelta = - goog.isDef(mapOptions.mouseWheelZoomDelta) ? - mapOptions.mouseWheelZoomDelta : 1; - interactions.push(new ol.interaction.MouseWheelZoom(mouseWheelZoomDelta)); + interactions.push(new ol.interaction.MouseWheelZoom()); } var shiftDragZoom = goog.isDef(mapOptions.shiftDragZoom) ? diff --git a/test/spec/ol/map.test.js b/test/spec/ol/map.test.js index c5e0ff2b30..38e5758437 100644 --- a/test/spec/ol/map.test.js +++ b/test/spec/ol/map.test.js @@ -85,28 +85,11 @@ describe('ol.Map', function() { }); describe('create mousewheel interaction', function() { - - beforeEach(function() { + it('creates mousewheel interaction', function() { options.mouseWheelZoom = true; - }); - - describe('default mouseWheelZoomDelta', function() { - it('create mousewheel interaction with default delta', function() { - var interactions = ol.Map.createInteractions_(options); - expect(interactions.getLength()).toEqual(1); - expect(interactions.getAt(0)).toBeA(ol.interaction.MouseWheelZoom); - expect(interactions.getAt(0).delta_).toEqual(1); - }); - }); - - describe('set mouseWheelZoomDelta', function() { - it('create mousewheel interaction with set delta', function() { - options.mouseWheelZoomDelta = 7; - var interactions = ol.Map.createInteractions_(options); - expect(interactions.getLength()).toEqual(1); - expect(interactions.getAt(0)).toBeA(ol.interaction.MouseWheelZoom); - expect(interactions.getAt(0).delta_).toEqual(7); - }); + var interactions = ol.Map.createInteractions_(options); + expect(interactions.getLength()).toEqual(1); + expect(interactions.getAt(0)).toBeA(ol.interaction.MouseWheelZoom); }); }); @@ -125,7 +108,7 @@ describe('ol.Map', function() { }); }); - describe('set mouseWheelZoomDelta', function() { + describe('set zoomDelta', function() { it('create double click interaction with set delta', function() { options.zoomDelta = 7; var interactions = ol.Map.createInteractions_(options);