diff --git a/externs/closure-compiler.js b/externs/closure-compiler.js index 7894661c23..d51b19d762 100644 --- a/externs/closure-compiler.js +++ b/externs/closure-compiler.js @@ -15,3 +15,13 @@ * @see http://www.w3.org/TR/pointerevents/#the-touch-action-css-property */ CSSProperties.prototype.touchAction; + +/** + * @type {number} + */ +WheelEvent.DOM_DELTA_LINE; + +/** + * @type {number} + */ +WheelEvent.DOM_DELTA_PIXEL; diff --git a/src/ol/events.js b/src/ol/events.js index 3889401b02..e42556ac69 100644 --- a/src/ol/events.js +++ b/src/ol/events.js @@ -5,6 +5,7 @@ goog.provide('ol.events.KeyCode'); /** * @enum {string} + * @const */ ol.events.EventType = { /** @@ -25,14 +26,17 @@ ol.events.EventType = { MOUSEDOWN: 'mousedown', MOUSEMOVE: 'mousemove', MOUSEOUT: 'mouseout', + MOUSEWHEEL: 'mousewheel', MSPOINTERDOWN: 'mspointerdown', RESIZE: 'resize', - TOUCHSTART: 'touchstart' + TOUCHSTART: 'touchstart', + WHEEL: 'wheel' }; /** * @enum {number} + * @const */ ol.events.KeyCode = { LEFT: 37, diff --git a/src/ol/has.js b/src/ol/has.js index 91fe1c07b0..61d4d33199 100644 --- a/src/ol/has.js +++ b/src/ol/has.js @@ -5,6 +5,22 @@ goog.require('ol.dom'); goog.require('ol.webgl'); +var ua = typeof navigator !== 'undefined' ? + navigator.userAgent.toLowerCase() : ''; + +/** + * User agent string says we are dealing with Firefox as browser. + * @type {boolean} + */ +ol.has.FIREFOX = ua.indexOf('firefox') !== -1; + +/** + * User agent string says we are dealing with Safari as browser. + * @type {boolean} + */ +ol.has.SAFARI = ua.indexOf('safari') !== -1 && ua.indexOf('chrom') === -1; + + /** * The ratio between physical pixels and device-independent pixels * (dips) on the device (`window.devicePixelRatio`). diff --git a/src/ol/interaction/mousewheelzoominteraction.js b/src/ol/interaction/mousewheelzoominteraction.js index 58584b38c0..bb3840345e 100644 --- a/src/ol/interaction/mousewheelzoominteraction.js +++ b/src/ol/interaction/mousewheelzoominteraction.js @@ -1,10 +1,9 @@ goog.provide('ol.interaction.MouseWheelZoom'); goog.require('goog.asserts'); -goog.require('goog.events.MouseWheelEvent'); -goog.require('goog.events.MouseWheelHandler.EventType'); goog.require('ol'); goog.require('ol.Coordinate'); +goog.require('ol.events.EventType'); goog.require('ol.interaction.Interaction'); goog.require('ol.math'); @@ -76,18 +75,36 @@ goog.inherits(ol.interaction.MouseWheelZoom, ol.interaction.Interaction); */ ol.interaction.MouseWheelZoom.handleEvent = function(mapBrowserEvent) { var stopEvent = false; - if (mapBrowserEvent.type == - goog.events.MouseWheelHandler.EventType.MOUSEWHEEL) { + if (mapBrowserEvent.type == ol.events.EventType.WHEEL || + mapBrowserEvent.type == ol.events.EventType.MOUSEWHEEL) { var map = mapBrowserEvent.map; - var mouseWheelEvent = mapBrowserEvent.originalEvent; - goog.asserts.assertInstanceof(mouseWheelEvent, goog.events.MouseWheelEvent, - 'mouseWheelEvent should be of type MouseWheelEvent'); + var wheelEvent = /** @type {WheelEvent} */ (mapBrowserEvent.originalEvent); if (this.useAnchor_) { this.lastAnchor_ = mapBrowserEvent.coordinate; } - this.delta_ += mouseWheelEvent.deltaY; + // Delta normalisation inspired by + // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js + //TODO There's more good stuff in there for inspiration to improve this interaction. + var delta; + if (mapBrowserEvent.type == ol.events.EventType.WHEEL) { + delta = wheelEvent.deltaY; + if (ol.has.FIREFOX && + wheelEvent.deltaMode === goog.global.WheelEvent.DOM_DELTA_PIXEL) { + delta /= ol.has.DEVICE_PIXEL_RATIO; + } + if (wheelEvent.deltaMode === goog.global.WheelEvent.DOM_DELTA_LINE) { + delta *= 40; + } + } else if (mapBrowserEvent.type == ol.events.EventType.MOUSEWHEEL) { + delta = -wheelEvent.wheelDeltaY; + if (ol.has.SAFARI) { + delta /= 3; + } + } + + this.delta_ += delta; if (this.startTime_ === undefined) { this.startTime_ = Date.now(); diff --git a/src/ol/map.js b/src/ol/map.js index 64bb863a35..f2f54cd023 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -12,8 +12,6 @@ goog.require('goog.debug.Console'); goog.require('goog.dom'); goog.require('goog.dom.ViewportSizeMonitor'); goog.require('goog.dom.classlist'); -goog.require('goog.events.MouseWheelHandler'); -goog.require('goog.events.MouseWheelHandler.EventType'); goog.require('goog.functions'); goog.require('goog.log'); goog.require('goog.log.Level'); @@ -311,11 +309,10 @@ ol.Map = function(options) { */ this.keyHandlerKey_; - var mouseWheelHandler = new goog.events.MouseWheelHandler(this.viewport_); - ol.events.listen(mouseWheelHandler, - goog.events.MouseWheelHandler.EventType.MOUSEWHEEL, + ol.events.listen(this.viewport_, ol.events.EventType.WHEEL, + this.handleBrowserEvent, false, this); + ol.events.listen(this.viewport_, ol.events.EventType.MOUSEWHEEL, this.handleBrowserEvent, false, this); - this.registerDisposable(mouseWheelHandler); /** * @type {ol.Collection.