Reworked mapbrowser* things
This commit is contained in:
@@ -1,15 +1,8 @@
|
|||||||
goog.provide('ol.MapBrowserEvent');
|
goog.provide('ol.MapBrowserEvent');
|
||||||
goog.provide('ol.MapBrowserEvent.EventType');
|
|
||||||
goog.provide('ol.MapBrowserEventHandler');
|
|
||||||
goog.provide('ol.MapBrowserPointerEvent');
|
|
||||||
|
|
||||||
goog.require('ol');
|
goog.require('ol');
|
||||||
goog.require('ol.MapEvent');
|
goog.require('ol.MapEvent');
|
||||||
goog.require('ol.events');
|
|
||||||
goog.require('ol.events.EventTarget');
|
|
||||||
goog.require('ol.events.EventType');
|
goog.require('ol.events.EventType');
|
||||||
goog.require('ol.pointer.EventType');
|
|
||||||
goog.require('ol.pointer.PointerEventHandler');
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,339 +83,6 @@ ol.MapBrowserEvent.prototype.stopPropagation = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @extends {ol.MapBrowserEvent}
|
|
||||||
* @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_dragging,
|
|
||||||
opt_frameState) {
|
|
||||||
|
|
||||||
ol.MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
|
|
||||||
opt_frameState);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {ol.pointer.PointerEvent}
|
|
||||||
*/
|
|
||||||
this.pointerEvent = pointerEvent;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.MapBrowserPointerEvent, ol.MapBrowserEvent);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.Map} map The map with the viewport to listen to events on.
|
|
||||||
* @constructor
|
|
||||||
* @extends {ol.events.EventTarget}
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler = function(map) {
|
|
||||||
|
|
||||||
ol.events.EventTarget.call(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the element that we will listen to the real events on.
|
|
||||||
* @type {ol.Map}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.map_ = map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.clickTimeoutId_ = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.dragging_ = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {!Array.<ol.EventsKey>}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.dragListenerKeys_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The most recent "down" type event (or null if none have occurred).
|
|
||||||
* Set on pointerdown.
|
|
||||||
* @type {ol.pointer.PointerEvent}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.down_ = null;
|
|
||||||
|
|
||||||
var element = this.map_.getViewport();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.activePointers_ = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {!Object.<number, boolean>}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.trackedTouches_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event handler which generates pointer events for
|
|
||||||
* the viewport element.
|
|
||||||
*
|
|
||||||
* @type {ol.pointer.PointerEventHandler}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.pointerEventHandler_ = new ol.pointer.PointerEventHandler(element);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event handler which generates pointer events for
|
|
||||||
* the document (used when dragging).
|
|
||||||
*
|
|
||||||
* @type {ol.pointer.PointerEventHandler}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.documentPointerEventHandler_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {?ol.EventsKey}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_,
|
|
||||||
ol.pointer.EventType.POINTERDOWN,
|
|
||||||
this.handlePointerDown_, this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {?ol.EventsKey}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_,
|
|
||||||
ol.pointer.EventType.POINTERMOVE,
|
|
||||||
this.relayEvent_, this);
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.MapBrowserEventHandler, ol.events.EventTarget);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
|
|
||||||
var newEvent = new ol.MapBrowserPointerEvent(
|
|
||||||
ol.MapBrowserEvent.EventType.CLICK, this.map_, pointerEvent);
|
|
||||||
this.dispatchEvent(newEvent);
|
|
||||||
if (this.clickTimeoutId_ !== 0) {
|
|
||||||
// double-click
|
|
||||||
clearTimeout(this.clickTimeoutId_);
|
|
||||||
this.clickTimeoutId_ = 0;
|
|
||||||
newEvent = new ol.MapBrowserPointerEvent(
|
|
||||||
ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, pointerEvent);
|
|
||||||
this.dispatchEvent(newEvent);
|
|
||||||
} else {
|
|
||||||
// click
|
|
||||||
this.clickTimeoutId_ = setTimeout(function() {
|
|
||||||
this.clickTimeoutId_ = 0;
|
|
||||||
var newEvent = new ol.MapBrowserPointerEvent(
|
|
||||||
ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, pointerEvent);
|
|
||||||
this.dispatchEvent(newEvent);
|
|
||||||
}.bind(this), 250);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Keeps track on how many pointers are currently active.
|
|
||||||
*
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) {
|
|
||||||
var event = pointerEvent;
|
|
||||||
|
|
||||||
if (event.type == ol.MapBrowserEvent.EventType.POINTERUP ||
|
|
||||||
event.type == ol.MapBrowserEvent.EventType.POINTERCANCEL) {
|
|
||||||
delete this.trackedTouches_[event.pointerId];
|
|
||||||
} else if (event.type == ol.MapBrowserEvent.EventType.POINTERDOWN) {
|
|
||||||
this.trackedTouches_[event.pointerId] = true;
|
|
||||||
}
|
|
||||||
this.activePointers_ = Object.keys(this.trackedTouches_).length;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
|
|
||||||
this.updateActivePointers_(pointerEvent);
|
|
||||||
var newEvent = new ol.MapBrowserPointerEvent(
|
|
||||||
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)) {
|
|
||||||
ol.DEBUG && console.assert(this.down_, 'this.down_ must be truthy');
|
|
||||||
this.emulateClick_(this.down_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ol.DEBUG && console.assert(this.activePointers_ >= 0,
|
|
||||||
'this.activePointers_ should be equal to or larger than 0');
|
|
||||||
if (this.activePointers_ === 0) {
|
|
||||||
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
|
|
||||||
this.dragListenerKeys_.length = 0;
|
|
||||||
this.dragging_ = false;
|
|
||||||
this.down_ = null;
|
|
||||||
this.documentPointerEventHandler_.dispose();
|
|
||||||
this.documentPointerEventHandler_ = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @return {boolean} If the left mouse button was pressed.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) {
|
|
||||||
return pointerEvent.button === 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) {
|
|
||||||
this.updateActivePointers_(pointerEvent);
|
|
||||||
var newEvent = new ol.MapBrowserPointerEvent(
|
|
||||||
ol.MapBrowserEvent.EventType.POINTERDOWN, this.map_, pointerEvent);
|
|
||||||
this.dispatchEvent(newEvent);
|
|
||||||
|
|
||||||
this.down_ = pointerEvent;
|
|
||||||
|
|
||||||
if (this.dragListenerKeys_.length === 0) {
|
|
||||||
/* Set up a pointer event handler on the `document`,
|
|
||||||
* which is required when the pointer is moved outside
|
|
||||||
* the viewport when dragging.
|
|
||||||
*/
|
|
||||||
this.documentPointerEventHandler_ =
|
|
||||||
new ol.pointer.PointerEventHandler(document);
|
|
||||||
|
|
||||||
this.dragListenerKeys_.push(
|
|
||||||
ol.events.listen(this.documentPointerEventHandler_,
|
|
||||||
ol.MapBrowserEvent.EventType.POINTERMOVE,
|
|
||||||
this.handlePointerMove_, this),
|
|
||||||
ol.events.listen(this.documentPointerEventHandler_,
|
|
||||||
ol.MapBrowserEvent.EventType.POINTERUP,
|
|
||||||
this.handlePointerUp_, this),
|
|
||||||
/* Note that the listener for `pointercancel is set up on
|
|
||||||
* `pointerEventHandler_` and not `documentPointerEventHandler_` like
|
|
||||||
* the `pointerup` and `pointermove` listeners.
|
|
||||||
*
|
|
||||||
* The reason for this is the following: `TouchSource.vacuumTouches_()`
|
|
||||||
* issues `pointercancel` events, when there was no `touchend` for a
|
|
||||||
* `touchstart`. Now, let's say a first `touchstart` is registered on
|
|
||||||
* `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
|
|
||||||
* But `documentPointerEventHandler_` doesn't know about the first
|
|
||||||
* `touchstart`. If there is no `touchend` for the `touchstart`, we can
|
|
||||||
* only receive a `touchcancel` from `pointerEventHandler_`, because it is
|
|
||||||
* only registered there.
|
|
||||||
*/
|
|
||||||
ol.events.listen(this.pointerEventHandler_,
|
|
||||||
ol.MapBrowserEvent.EventType.POINTERCANCEL,
|
|
||||||
this.handlePointerUp_, this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
|
|
||||||
// Fix IE10 on windows Surface : When you tap the tablet, it triggers
|
|
||||||
// multiple pointermove events between pointerdown and pointerup with
|
|
||||||
// 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 (this.isMoving_(pointerEvent)) {
|
|
||||||
this.dragging_ = true;
|
|
||||||
var newEvent = new ol.MapBrowserPointerEvent(
|
|
||||||
ol.MapBrowserEvent.EventType.POINTERDRAG, this.map_, pointerEvent,
|
|
||||||
this.dragging_);
|
|
||||||
this.dispatchEvent(newEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some native android browser triggers mousemove events during small period
|
|
||||||
// of time. See: https://code.google.com/p/android/issues/detail?id=5491 or
|
|
||||||
// https://code.google.com/p/android/issues/detail?id=19827
|
|
||||||
// ex: Galaxy Tab P3110 + Android 4.1.1
|
|
||||||
pointerEvent.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap and relay a pointer event. Note that this requires that the type
|
|
||||||
* string for the MapBrowserPointerEvent matches the PointerEvent type.
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
|
|
||||||
var dragging = !!(this.down_ && this.isMoving_(pointerEvent));
|
|
||||||
this.dispatchEvent(new ol.MapBrowserPointerEvent(
|
|
||||||
pointerEvent.type, this.map_, pointerEvent, dragging));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
|
||||||
* @return {boolean} Is moving.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) {
|
|
||||||
return pointerEvent.clientX != this.down_.clientX ||
|
|
||||||
pointerEvent.clientY != this.down_.clientY;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
|
|
||||||
if (this.relayedListenerKey_) {
|
|
||||||
ol.events.unlistenByKey(this.relayedListenerKey_);
|
|
||||||
this.relayedListenerKey_ = null;
|
|
||||||
}
|
|
||||||
if (this.pointerdownListenerKey_) {
|
|
||||||
ol.events.unlistenByKey(this.pointerdownListenerKey_);
|
|
||||||
this.pointerdownListenerKey_ = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
|
|
||||||
this.dragListenerKeys_.length = 0;
|
|
||||||
|
|
||||||
if (this.documentPointerEventHandler_) {
|
|
||||||
this.documentPointerEventHandler_.dispose();
|
|
||||||
this.documentPointerEventHandler_ = null;
|
|
||||||
}
|
|
||||||
if (this.pointerEventHandler_) {
|
|
||||||
this.pointerEventHandler_.dispose();
|
|
||||||
this.pointerEventHandler_ = null;
|
|
||||||
}
|
|
||||||
ol.events.EventTarget.prototype.disposeInternal.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants for event names.
|
* Constants for event names.
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
|
|||||||
317
src/ol/mapbrowsereventhandler.js
Normal file
317
src/ol/mapbrowsereventhandler.js
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
goog.provide('ol.MapBrowserEventHandler');
|
||||||
|
|
||||||
|
goog.require('ol');
|
||||||
|
goog.require('ol.MapBrowserEvent');
|
||||||
|
goog.require('ol.MapBrowserPointerEvent');
|
||||||
|
goog.require('ol.events');
|
||||||
|
goog.require('ol.events.EventTarget');
|
||||||
|
goog.require('ol.pointer.EventType');
|
||||||
|
goog.require('ol.pointer.PointerEventHandler');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Map} map The map with the viewport to listen to events on.
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.events.EventTarget}
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler = function(map) {
|
||||||
|
|
||||||
|
ol.events.EventTarget.call(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the element that we will listen to the real events on.
|
||||||
|
* @type {ol.Map}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.map_ = map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.clickTimeoutId_ = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.dragging_ = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {!Array.<ol.EventsKey>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.dragListenerKeys_ = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The most recent "down" type event (or null if none have occurred).
|
||||||
|
* Set on pointerdown.
|
||||||
|
* @type {ol.pointer.PointerEvent}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.down_ = null;
|
||||||
|
|
||||||
|
var element = this.map_.getViewport();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.activePointers_ = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {!Object.<number, boolean>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.trackedTouches_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler which generates pointer events for
|
||||||
|
* the viewport element.
|
||||||
|
*
|
||||||
|
* @type {ol.pointer.PointerEventHandler}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.pointerEventHandler_ = new ol.pointer.PointerEventHandler(element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler which generates pointer events for
|
||||||
|
* the document (used when dragging).
|
||||||
|
*
|
||||||
|
* @type {ol.pointer.PointerEventHandler}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.documentPointerEventHandler_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {?ol.EventsKey}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_,
|
||||||
|
ol.pointer.EventType.POINTERDOWN,
|
||||||
|
this.handlePointerDown_, this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {?ol.EventsKey}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_,
|
||||||
|
ol.pointer.EventType.POINTERMOVE,
|
||||||
|
this.relayEvent_, this);
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.MapBrowserEventHandler, ol.events.EventTarget);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
|
||||||
|
var newEvent = new ol.MapBrowserPointerEvent(
|
||||||
|
ol.MapBrowserEvent.EventType.CLICK, this.map_, pointerEvent);
|
||||||
|
this.dispatchEvent(newEvent);
|
||||||
|
if (this.clickTimeoutId_ !== 0) {
|
||||||
|
// double-click
|
||||||
|
clearTimeout(this.clickTimeoutId_);
|
||||||
|
this.clickTimeoutId_ = 0;
|
||||||
|
newEvent = new ol.MapBrowserPointerEvent(
|
||||||
|
ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, pointerEvent);
|
||||||
|
this.dispatchEvent(newEvent);
|
||||||
|
} else {
|
||||||
|
// click
|
||||||
|
this.clickTimeoutId_ = setTimeout(function() {
|
||||||
|
this.clickTimeoutId_ = 0;
|
||||||
|
var newEvent = new ol.MapBrowserPointerEvent(
|
||||||
|
ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, pointerEvent);
|
||||||
|
this.dispatchEvent(newEvent);
|
||||||
|
}.bind(this), 250);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track on how many pointers are currently active.
|
||||||
|
*
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) {
|
||||||
|
var event = pointerEvent;
|
||||||
|
|
||||||
|
if (event.type == ol.MapBrowserEvent.EventType.POINTERUP ||
|
||||||
|
event.type == ol.MapBrowserEvent.EventType.POINTERCANCEL) {
|
||||||
|
delete this.trackedTouches_[event.pointerId];
|
||||||
|
} else if (event.type == ol.MapBrowserEvent.EventType.POINTERDOWN) {
|
||||||
|
this.trackedTouches_[event.pointerId] = true;
|
||||||
|
}
|
||||||
|
this.activePointers_ = Object.keys(this.trackedTouches_).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
|
||||||
|
this.updateActivePointers_(pointerEvent);
|
||||||
|
var newEvent = new ol.MapBrowserPointerEvent(
|
||||||
|
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)) {
|
||||||
|
ol.DEBUG && console.assert(this.down_, 'this.down_ must be truthy');
|
||||||
|
this.emulateClick_(this.down_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ol.DEBUG && console.assert(this.activePointers_ >= 0,
|
||||||
|
'this.activePointers_ should be equal to or larger than 0');
|
||||||
|
if (this.activePointers_ === 0) {
|
||||||
|
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
|
||||||
|
this.dragListenerKeys_.length = 0;
|
||||||
|
this.dragging_ = false;
|
||||||
|
this.down_ = null;
|
||||||
|
this.documentPointerEventHandler_.dispose();
|
||||||
|
this.documentPointerEventHandler_ = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @return {boolean} If the left mouse button was pressed.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) {
|
||||||
|
return pointerEvent.button === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) {
|
||||||
|
this.updateActivePointers_(pointerEvent);
|
||||||
|
var newEvent = new ol.MapBrowserPointerEvent(
|
||||||
|
ol.MapBrowserEvent.EventType.POINTERDOWN, this.map_, pointerEvent);
|
||||||
|
this.dispatchEvent(newEvent);
|
||||||
|
|
||||||
|
this.down_ = pointerEvent;
|
||||||
|
|
||||||
|
if (this.dragListenerKeys_.length === 0) {
|
||||||
|
/* Set up a pointer event handler on the `document`,
|
||||||
|
* which is required when the pointer is moved outside
|
||||||
|
* the viewport when dragging.
|
||||||
|
*/
|
||||||
|
this.documentPointerEventHandler_ =
|
||||||
|
new ol.pointer.PointerEventHandler(document);
|
||||||
|
|
||||||
|
this.dragListenerKeys_.push(
|
||||||
|
ol.events.listen(this.documentPointerEventHandler_,
|
||||||
|
ol.MapBrowserEvent.EventType.POINTERMOVE,
|
||||||
|
this.handlePointerMove_, this),
|
||||||
|
ol.events.listen(this.documentPointerEventHandler_,
|
||||||
|
ol.MapBrowserEvent.EventType.POINTERUP,
|
||||||
|
this.handlePointerUp_, this),
|
||||||
|
/* Note that the listener for `pointercancel is set up on
|
||||||
|
* `pointerEventHandler_` and not `documentPointerEventHandler_` like
|
||||||
|
* the `pointerup` and `pointermove` listeners.
|
||||||
|
*
|
||||||
|
* The reason for this is the following: `TouchSource.vacuumTouches_()`
|
||||||
|
* issues `pointercancel` events, when there was no `touchend` for a
|
||||||
|
* `touchstart`. Now, let's say a first `touchstart` is registered on
|
||||||
|
* `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
|
||||||
|
* But `documentPointerEventHandler_` doesn't know about the first
|
||||||
|
* `touchstart`. If there is no `touchend` for the `touchstart`, we can
|
||||||
|
* only receive a `touchcancel` from `pointerEventHandler_`, because it is
|
||||||
|
* only registered there.
|
||||||
|
*/
|
||||||
|
ol.events.listen(this.pointerEventHandler_,
|
||||||
|
ol.MapBrowserEvent.EventType.POINTERCANCEL,
|
||||||
|
this.handlePointerUp_, this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
|
||||||
|
// Fix IE10 on windows Surface : When you tap the tablet, it triggers
|
||||||
|
// multiple pointermove events between pointerdown and pointerup with
|
||||||
|
// 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 (this.isMoving_(pointerEvent)) {
|
||||||
|
this.dragging_ = true;
|
||||||
|
var newEvent = new ol.MapBrowserPointerEvent(
|
||||||
|
ol.MapBrowserEvent.EventType.POINTERDRAG, this.map_, pointerEvent,
|
||||||
|
this.dragging_);
|
||||||
|
this.dispatchEvent(newEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some native android browser triggers mousemove events during small period
|
||||||
|
// of time. See: https://code.google.com/p/android/issues/detail?id=5491 or
|
||||||
|
// https://code.google.com/p/android/issues/detail?id=19827
|
||||||
|
// ex: Galaxy Tab P3110 + Android 4.1.1
|
||||||
|
pointerEvent.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap and relay a pointer event. Note that this requires that the type
|
||||||
|
* string for the MapBrowserPointerEvent matches the PointerEvent type.
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
|
||||||
|
var dragging = !!(this.down_ && this.isMoving_(pointerEvent));
|
||||||
|
this.dispatchEvent(new ol.MapBrowserPointerEvent(
|
||||||
|
pointerEvent.type, this.map_, pointerEvent, dragging));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
|
||||||
|
* @return {boolean} Is moving.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) {
|
||||||
|
return pointerEvent.clientX != this.down_.clientX ||
|
||||||
|
pointerEvent.clientY != this.down_.clientY;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
|
||||||
|
if (this.relayedListenerKey_) {
|
||||||
|
ol.events.unlistenByKey(this.relayedListenerKey_);
|
||||||
|
this.relayedListenerKey_ = null;
|
||||||
|
}
|
||||||
|
if (this.pointerdownListenerKey_) {
|
||||||
|
ol.events.unlistenByKey(this.pointerdownListenerKey_);
|
||||||
|
this.pointerdownListenerKey_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
|
||||||
|
this.dragListenerKeys_.length = 0;
|
||||||
|
|
||||||
|
if (this.documentPointerEventHandler_) {
|
||||||
|
this.documentPointerEventHandler_.dispose();
|
||||||
|
this.documentPointerEventHandler_ = null;
|
||||||
|
}
|
||||||
|
if (this.pointerEventHandler_) {
|
||||||
|
this.pointerEventHandler_.dispose();
|
||||||
|
this.pointerEventHandler_ = null;
|
||||||
|
}
|
||||||
|
ol.events.EventTarget.prototype.disposeInternal.call(this);
|
||||||
|
};
|
||||||
29
src/ol/mapbrowserpointerevent.js
Normal file
29
src/ol/mapbrowserpointerevent.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
goog.provide('ol.MapBrowserPointerEvent');
|
||||||
|
|
||||||
|
goog.require('ol');
|
||||||
|
goog.require('ol.MapBrowserEvent');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.MapBrowserEvent}
|
||||||
|
* @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_dragging,
|
||||||
|
opt_frameState) {
|
||||||
|
|
||||||
|
ol.MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
|
||||||
|
opt_frameState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {ol.pointer.PointerEvent}
|
||||||
|
*/
|
||||||
|
this.pointerEvent = pointerEvent;
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.MapBrowserPointerEvent, ol.MapBrowserEvent);
|
||||||
Reference in New Issue
Block a user