Debounce mousewheel zoom events

This commit is contained in:
Éric Lemoine
2013-02-21 14:52:15 +01:00
parent 4d486601f9
commit faef495cfd
4 changed files with 84 additions and 40 deletions

View File

@@ -7,7 +7,6 @@
@exportObjectLiteralProperty ol.MapOptions.keyboardPanOffset number|undefined @exportObjectLiteralProperty ol.MapOptions.keyboardPanOffset number|undefined
@exportObjectLiteralProperty ol.MapOptions.layers ol.Collection|undefined @exportObjectLiteralProperty ol.MapOptions.layers ol.Collection|undefined
@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoom boolean|undefined @exportObjectLiteralProperty ol.MapOptions.mouseWheelZoom boolean|undefined
@exportObjectLiteralProperty ol.MapOptions.mouseWheelZoomDelta number|undefined
@exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined @exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined
@exportObjectLiteralProperty ol.MapOptions.renderers Array.<ol.RendererHint>|undefined @exportObjectLiteralProperty ol.MapOptions.renderers Array.<ol.RendererHint>|undefined
@exportObjectLiteralProperty ol.MapOptions.scaleLineControl boolean|undefined @exportObjectLiteralProperty ol.MapOptions.scaleLineControl boolean|undefined

View File

@@ -4,30 +4,63 @@ goog.provide('ol.interaction.MouseWheelZoom');
goog.require('goog.events.MouseWheelEvent'); goog.require('goog.events.MouseWheelEvent');
goog.require('goog.events.MouseWheelHandler.EventType'); goog.require('goog.events.MouseWheelHandler.EventType');
goog.require('goog.math');
goog.require('ol.Coordinate');
goog.require('ol.View2D'); goog.require('ol.View2D');
goog.require('ol.interaction.Interaction'); 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 * @constructor
* @extends {ol.interaction.Interaction} * @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 * @private
* @type {number} * @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); 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 = ol.interaction.MouseWheelZoom.prototype.handleMapBrowserEvent =
function(mapBrowserEvent) { function(mapBrowserEvent) {
if (mapBrowserEvent.type == if (mapBrowserEvent.type ==
goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) { goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) {
var map = mapBrowserEvent.map; var map = mapBrowserEvent.map;
var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */ var mouseWheelEvent = /** @type {goog.events.MouseWheelEvent} */
(mapBrowserEvent.browserEvent); (mapBrowserEvent.browserEvent);
goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent); goog.asserts.assert(mouseWheelEvent instanceof goog.events.MouseWheelEvent);
var anchor = mapBrowserEvent.getCoordinate();
var delta = mouseWheelEvent.deltaY < 0 ? this.delta_ : -this.delta_; this.lastAnchor_ = mapBrowserEvent.getCoordinate();
// FIXME works for View2D only this.delta_ += mouseWheelEvent.deltaY / 3;
var view = map.getView();
goog.asserts.assert(view instanceof ol.View2D); if (!goog.isDef(this.startTime_)) {
map.requestRenderFrame(); this.startTime_ = goog.now();
view.zoom(map, delta, anchor, ol.interaction.ZOOM_DURATION); }
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(); mapBrowserEvent.preventDefault();
mouseWheelEvent.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;
};

View File

@@ -1014,10 +1014,7 @@ ol.Map.createInteractions_ = function(mapOptions) {
var mouseWheelZoom = goog.isDef(mapOptions.mouseWheelZoom) ? var mouseWheelZoom = goog.isDef(mapOptions.mouseWheelZoom) ?
mapOptions.mouseWheelZoom : true; mapOptions.mouseWheelZoom : true;
if (mouseWheelZoom) { if (mouseWheelZoom) {
var mouseWheelZoomDelta = interactions.push(new ol.interaction.MouseWheelZoom());
goog.isDef(mapOptions.mouseWheelZoomDelta) ?
mapOptions.mouseWheelZoomDelta : 1;
interactions.push(new ol.interaction.MouseWheelZoom(mouseWheelZoomDelta));
} }
var shiftDragZoom = goog.isDef(mapOptions.shiftDragZoom) ? var shiftDragZoom = goog.isDef(mapOptions.shiftDragZoom) ?

View File

@@ -85,28 +85,11 @@ describe('ol.Map', function() {
}); });
describe('create mousewheel interaction', function() { describe('create mousewheel interaction', function() {
it('creates mousewheel interaction', function() {
beforeEach(function() {
options.mouseWheelZoom = true; options.mouseWheelZoom = true;
}); var interactions = ol.Map.createInteractions_(options);
expect(interactions.getLength()).toEqual(1);
describe('default mouseWheelZoomDelta', function() { expect(interactions.getAt(0)).toBeA(ol.interaction.MouseWheelZoom);
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);
});
}); });
}); });
@@ -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() { it('create double click interaction with set delta', function() {
options.zoomDelta = 7; options.zoomDelta = 7;
var interactions = ol.Map.createInteractions_(options); var interactions = ol.Map.createInteractions_(options);