diff --git a/examples/drag-and-drop-image-vector.js b/examples/drag-and-drop-image-vector.js index 90a6f54b83..6e35336d4c 100644 --- a/examples/drag-and-drop-image-vector.js +++ b/examples/drag-and-drop-image-vector.js @@ -145,7 +145,10 @@ var displayFeatureInfo = function(pixel) { } }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); displayFeatureInfo(pixel); }); diff --git a/examples/drag-and-drop.js b/examples/drag-and-drop.js index c481a7f9a9..830b6bc77b 100644 --- a/examples/drag-and-drop.js +++ b/examples/drag-and-drop.js @@ -141,7 +141,10 @@ var displayFeatureInfo = function(pixel) { } }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); displayFeatureInfo(pixel); }); diff --git a/examples/gpx.js b/examples/gpx.js index 13024a6a2b..d98dceba31 100644 --- a/examples/gpx.js +++ b/examples/gpx.js @@ -85,7 +85,10 @@ var displayFeatureInfo = function(pixel) { } }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); displayFeatureInfo(pixel); }); diff --git a/examples/icon-sprite-webgl.js b/examples/icon-sprite-webgl.js index 79993c97bf..8487020b8b 100644 --- a/examples/icon-sprite-webgl.js +++ b/examples/icon-sprite-webgl.js @@ -132,7 +132,10 @@ map.on('click', function(evt) { }, 1); }); -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); var hit = map.hasFeatureAtPixel(pixel); map.getTarget().style.cursor = hit ? 'pointer' : ''; diff --git a/examples/icon.js b/examples/icon.js index 1316d68799..f435b0f0b5 100644 --- a/examples/icon.js +++ b/examples/icon.js @@ -86,7 +86,11 @@ map.on('click', function(evt) { }); // change mouse cursor when over marker -$(map.getViewport()).on('mousemove', function(e) { +map.on('pointermove', function(e) { + if (e.dragging) { + $(element).popover('destroy'); + return; + } var pixel = map.getEventPixel(e.originalEvent); var hit = map.hasFeatureAtPixel(pixel); map.getTarget().style.cursor = hit ? 'pointer' : ''; diff --git a/examples/igc.js b/examples/igc.js index afb3e004bd..95b380dc1e 100644 --- a/examples/igc.js +++ b/examples/igc.js @@ -126,7 +126,10 @@ var displaySnap = function(coordinate) { map.render(); }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var coordinate = map.getEventCoordinate(evt.originalEvent); displaySnap(coordinate); }); diff --git a/examples/image-vector-layer.js b/examples/image-vector-layer.js index 01e79fe4e8..6cf67e6450 100644 --- a/examples/image-vector-layer.js +++ b/examples/image-vector-layer.js @@ -80,7 +80,10 @@ var displayFeatureInfo = function(pixel) { }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); displayFeatureInfo(pixel); }); diff --git a/examples/kml-earthquakes.js b/examples/kml-earthquakes.js index 793ebf4688..10ae729347 100644 --- a/examples/kml-earthquakes.js +++ b/examples/kml-earthquakes.js @@ -85,7 +85,11 @@ var displayFeatureInfo = function(pixel) { } }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + info.tooltip('hide'); + return; + } displayFeatureInfo(map.getEventPixel(evt.originalEvent)); }); diff --git a/examples/kml-timezones.js b/examples/kml-timezones.js index f7b5244d9d..8b8038e167 100644 --- a/examples/kml-timezones.js +++ b/examples/kml-timezones.js @@ -92,7 +92,11 @@ var displayFeatureInfo = function(pixel) { } }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + info.tooltip('hide'); + return; + } displayFeatureInfo(map.getEventPixel(evt.originalEvent)); }); diff --git a/examples/kml.js b/examples/kml.js index ac86d71adc..33236288f3 100644 --- a/examples/kml.js +++ b/examples/kml.js @@ -52,7 +52,10 @@ var displayFeatureInfo = function(pixel) { } }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); displayFeatureInfo(pixel); }); diff --git a/examples/measure.js b/examples/measure.js index 6f6c9f27b6..5b624f9934 100644 --- a/examples/measure.js +++ b/examples/measure.js @@ -57,7 +57,10 @@ var sketchElement; * handle pointer move * @param {Event} evt */ -var mouseMoveHandler = function(evt) { +var pointerMoveHandler = function(evt) { + if (evt.dragging) { + return; + } if (sketch) { var output; var geom = (sketch.getGeometry()); @@ -81,7 +84,7 @@ var map = new ol.Map({ }) }); -$(map.getViewport()).on('mousemove', mouseMoveHandler); +map.on('pointermove', pointerMoveHandler); var typeSelect = document.getElementById('type'); diff --git a/examples/synthetic-points.js b/examples/synthetic-points.js index 4381fd355c..606eb7c1f8 100644 --- a/examples/synthetic-points.js +++ b/examples/synthetic-points.js @@ -83,7 +83,10 @@ var displaySnap = function(coordinate) { map.render(); }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var coordinate = map.getEventCoordinate(evt.originalEvent); displaySnap(coordinate); }); @@ -116,13 +119,12 @@ map.on('postcompose', function(evt) { } }); -$(map.getViewport()).on('mousemove', function(e) { - var pixel = map.getEventPixel(e.originalEvent); - - var hit = map.forEachFeatureAtPixel(pixel, function(feature, layer) { - return true; - }); - +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } + var pixel = map.getEventPixel(evt.originalEvent); + var hit = map.hasFeatureAtPixel(pixel); if (hit) { map.getTarget().style.cursor = 'pointer'; } else { diff --git a/examples/tileutfgrid.js b/examples/tileutfgrid.js index b6462e37dd..89a26759b3 100644 --- a/examples/tileutfgrid.js +++ b/examples/tileutfgrid.js @@ -58,7 +58,10 @@ var displayCountryInfo = function(coordinate) { }); }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var coordinate = map.getEventCoordinate(evt.originalEvent); displayCountryInfo(coordinate); }); diff --git a/examples/vector-layer.js b/examples/vector-layer.js index 25f70d6cde..390ffe8081 100644 --- a/examples/vector-layer.js +++ b/examples/vector-layer.js @@ -114,7 +114,10 @@ var displayFeatureInfo = function(pixel) { }; -$(map.getViewport()).on('mousemove', function(evt) { +map.on('pointermove', function(evt) { + if (evt.dragging) { + return; + } var pixel = map.getEventPixel(evt.originalEvent); displayFeatureInfo(pixel); }); diff --git a/externs/oli.js b/externs/oli.js index 903fd6e893..9ffb8877f3 100644 --- a/externs/oli.js +++ b/externs/oli.js @@ -92,6 +92,12 @@ oli.MapBrowserEvent.prototype.originalEvent; oli.MapBrowserEvent.prototype.pixel; +/** + * @type {boolean} + */ +oli.MapBrowserEvent.prototype.dragging; + + /** * @interface diff --git a/src/ol/mapbrowserevent.js b/src/ol/mapbrowserevent.js index 199b2fad66..56b508cccc 100644 --- a/src/ol/mapbrowserevent.js +++ b/src/ol/mapbrowserevent.js @@ -30,9 +30,11 @@ goog.require('ol.pointer.PointerEventHandler'); * @param {string} type Event type. * @param {ol.Map} map Map. * @param {goog.events.BrowserEvent} browserEvent Browser event. + * @param {boolean=} opt_dragging Is the map currently being dragged? * @param {?olx.FrameState=} opt_frameState Frame state. */ -ol.MapBrowserEvent = function(type, map, browserEvent, opt_frameState) { +ol.MapBrowserEvent = function(type, map, browserEvent, opt_dragging, + opt_frameState) { goog.base(this, type, map, opt_frameState); @@ -61,6 +63,15 @@ ol.MapBrowserEvent = function(type, map, browserEvent, opt_frameState) { */ this.coordinate = map.getCoordinateFromPixel(this.pixel); + /** + * Indicates if the map is currently being dragged. Only set for + * `POINTERDRAG` and `POINTERMOVE` events. Default is `false`. + * + * @type {boolean} + * @api stable + */ + this.dragging = goog.isDef(opt_dragging) ? opt_dragging : false; + }; goog.inherits(ol.MapBrowserEvent, ol.MapEvent); @@ -96,11 +107,14 @@ ol.MapBrowserEvent.prototype.stopPropagation = function() { * @param {string} type Event type. * @param {ol.Map} map Map. * @param {ol.pointer.PointerEvent} pointerEvent Pointer event. + * @param {boolean=} opt_dragging Is the map currently being dragged? * @param {?olx.FrameState=} opt_frameState Frame state. */ -ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_frameState) { +ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging, + opt_frameState) { - goog.base(this, type, map, pointerEvent.browserEvent, opt_frameState); + goog.base(this, type, map, pointerEvent.browserEvent, opt_dragging, + opt_frameState); /** * @const @@ -139,7 +153,7 @@ ol.MapBrowserEventHandler = function(map) { * @type {boolean} * @private */ - this.dragged_ = false; + this.dragging_ = false; /** * @type {Array.} @@ -162,6 +176,8 @@ ol.MapBrowserEventHandler = function(map) { } /** + * The most recent "down" type event (or null if none have occurred). + * Set on pointerdown. * @type {ol.pointer.PointerEvent} * @private */ @@ -222,16 +238,6 @@ ol.MapBrowserEventHandler = function(map) { goog.inherits(ol.MapBrowserEventHandler, goog.events.EventTarget); -/** - * Get the last "down" type event. This will be set on pointerdown. - * @return {ol.pointer.PointerEvent} The most recent "down" type event (or null - * if none have occurred). - */ -ol.MapBrowserEventHandler.prototype.getDown = function() { - return this.down_; -}; - - /** * @param {goog.events.BrowserEvent} browserEvent Pointer event. * @private @@ -304,22 +310,24 @@ ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) { ol.MapBrowserEvent.EventType.POINTERUP, this.map_, pointerEvent); this.dispatchEvent(newEvent); + // We emulate click events on left mouse button click, touch contact, and pen + // contact. isMouseActionButton returns true in these cases (evt.button is set + // to 0). + // See http://www.w3.org/TR/pointerevents/#button-states + if (!this.dragging_ && this.isMouseActionButton_(pointerEvent)) { + goog.asserts.assert(!goog.isNull(this.down_)); + this.emulateClick_(this.down_); + } + goog.asserts.assert(this.activePointers_ >= 0); if (this.activePointers_ === 0) { goog.array.forEach(this.dragListenerKeys_, goog.events.unlistenByKey); this.dragListenerKeys_ = null; + this.dragging_ = false; + this.down_ = null; goog.dispose(this.documentPointerEventHandler_); this.documentPointerEventHandler_ = null; } - - // We emulate click event on left mouse button click, touch contact, and pen - // contact. isMouseActionButton returns true in these cases (evt.button is set - // to 0). - // See http://www.w3.org/TR/pointerevents/#button-states - if (!this.dragged_ && this.isMouseActionButton_(pointerEvent)) { - goog.asserts.assert(!goog.isNull(this.down_)); - this.emulateClick_(this.down_); - } }; @@ -350,7 +358,6 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = this.dispatchEvent(newEvent); this.down_ = pointerEvent; - this.dragged_ = false; if (goog.isNull(this.dragListenerKeys_)) { /* Set up a pointer event handler on the `document`, @@ -399,11 +406,11 @@ ol.MapBrowserEventHandler.prototype.handlePointerMove_ = // the exact same coordinates of the pointerdown event. To avoid a // 'false' touchmove event to be dispatched , we test if the pointer // effectively moved. - if (pointerEvent.clientX != this.down_.clientX || - pointerEvent.clientY != this.down_.clientY) { - this.dragged_ = true; + if (this.isMoving_(pointerEvent)) { + this.dragging_ = true; var newEvent = new ol.MapBrowserPointerEvent( - ol.MapBrowserEvent.EventType.POINTERDRAG, this.map_, pointerEvent); + ol.MapBrowserEvent.EventType.POINTERDRAG, this.map_, pointerEvent, + this.dragging_); this.dispatchEvent(newEvent); } @@ -422,8 +429,20 @@ ol.MapBrowserEventHandler.prototype.handlePointerMove_ = * @private */ ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) { + var dragging = !goog.isNull(this.down_) && this.isMoving_(pointerEvent); this.dispatchEvent(new ol.MapBrowserPointerEvent( - pointerEvent.type, this.map_, pointerEvent)); + pointerEvent.type, this.map_, pointerEvent, dragging)); +}; + + +/** + * @param {ol.pointer.PointerEvent} pointerEvent Pointer event. + * @return {boolean} + * @private + */ +ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) { + return pointerEvent.clientX != this.down_.clientX || + pointerEvent.clientY != this.down_.clientY; }; diff --git a/test/spec/ol/mapbrowserevent.test.js b/test/spec/ol/mapbrowserevent.test.js index c046545524..a72b45d4a7 100644 --- a/test/spec/ol/mapbrowserevent.test.js +++ b/test/spec/ol/mapbrowserevent.test.js @@ -96,22 +96,22 @@ describe('ol.MapBrowserEventHandler', function() { }); - describe('#getDown()', function() { + describe('#down_', function() { var handler; beforeEach(function() { handler = new ol.MapBrowserEventHandler(new ol.Map({})); }); - it('returns null if no "down" type event has been handled', function() { - expect(handler.getDown()).to.be(null); + it('is null if no "down" type event has been handled', function() { + expect(handler.down_).to.be(null); }); - it('returns an event after handlePointerDown_ has been called', function() { + it('is an event after handlePointerDown_ has been called', function() { var event = new ol.pointer.PointerEvent('pointerdown', new goog.events.BrowserEvent({})); handler.handlePointerDown_(event); - expect(handler.getDown()).to.be(event); + expect(handler.down_).to.be(event); }); });