Current File : //home/tradevaly/www/node_modules/leaflet/src/map/handler/Map.Tap.js |
import {Map} from '../Map';
import {Handler} from '../../core/Handler';
import * as DomEvent from '../../dom/DomEvent';
import {Point} from '../../geometry/Point';
import * as Util from '../../core/Util';
import * as DomUtil from '../../dom/DomUtil';
import * as Browser from '../../core/Browser';
/*
* L.Map.Tap is used to enable mobile hacks like quick taps and long hold.
*/
// @namespace Map
// @section Interaction Options
Map.mergeOptions({
// @section Touch interaction options
// @option tap: Boolean = true
// Enables mobile hacks for supporting instant taps (fixing 200ms click
// delay on iOS/Android) and touch holds (fired as `contextmenu` events).
tap: true,
// @option tapTolerance: Number = 15
// The max number of pixels a user can shift his finger during touch
// for it to be considered a valid tap.
tapTolerance: 15
});
export var Tap = Handler.extend({
addHooks: function () {
DomEvent.on(this._map._container, 'touchstart', this._onDown, this);
},
removeHooks: function () {
DomEvent.off(this._map._container, 'touchstart', this._onDown, this);
},
_onDown: function (e) {
if (!e.touches) { return; }
DomEvent.preventDefault(e);
this._fireClick = true;
// don't simulate click or track longpress if more than 1 touch
if (e.touches.length > 1) {
this._fireClick = false;
clearTimeout(this._holdTimeout);
return;
}
var first = e.touches[0],
el = first.target;
this._startPos = this._newPos = new Point(first.clientX, first.clientY);
// if touching a link, highlight it
if (el.tagName && el.tagName.toLowerCase() === 'a') {
DomUtil.addClass(el, 'leaflet-active');
}
// simulate long hold but setting a timeout
this._holdTimeout = setTimeout(Util.bind(function () {
if (this._isTapValid()) {
this._fireClick = false;
this._onUp();
this._simulateEvent('contextmenu', first);
}
}, this), 1000);
this._simulateEvent('mousedown', first);
DomEvent.on(document, {
touchmove: this._onMove,
touchend: this._onUp
}, this);
},
_onUp: function (e) {
clearTimeout(this._holdTimeout);
DomEvent.off(document, {
touchmove: this._onMove,
touchend: this._onUp
}, this);
if (this._fireClick && e && e.changedTouches) {
var first = e.changedTouches[0],
el = first.target;
if (el && el.tagName && el.tagName.toLowerCase() === 'a') {
DomUtil.removeClass(el, 'leaflet-active');
}
this._simulateEvent('mouseup', first);
// simulate click if the touch didn't move too much
if (this._isTapValid()) {
this._simulateEvent('click', first);
}
}
},
_isTapValid: function () {
return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
},
_onMove: function (e) {
var first = e.touches[0];
this._newPos = new Point(first.clientX, first.clientY);
this._simulateEvent('mousemove', first);
},
_simulateEvent: function (type, e) {
var simulatedEvent = document.createEvent('MouseEvents');
simulatedEvent._simulated = true;
e.target._simulatedClick = true;
simulatedEvent.initMouseEvent(
type, true, true, window, 1,
e.screenX, e.screenY,
e.clientX, e.clientY,
false, false, false, false, 0, null);
e.target.dispatchEvent(simulatedEvent);
}
});
// @section Handlers
// @property tap: Handler
// Mobile touch hacks (quick tap and touch hold) handler.
if (Browser.touch && (!Browser.pointer || Browser.safari)) {
Map.addInitHook('addHandler', 'tap', Tap);
}