Code coverage report for src/map/handler/Map.TouchZoom.js

Statements: 6.67% (3 / 45)      Branches: 4.17% (1 / 24)      Functions: 0% (0 / 7)      Lines: 7.32% (3 / 41)     

All files » src/map/handler/ » Map.TouchZoom.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118        1       1                                                                                                                                                                                                                       1  
/*
 * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers.
 */
 
L.Map.mergeOptions({
	touchZoom: L.Browser.touch && !L.Browser.android23
});
 
L.Map.TouchZoom = L.Handler.extend({
	addHooks: function () {
		L.DomEvent.on(this._map._container, 'touchstart', this._onTouchStart, this);
	},
 
	removeHooks: function () {
		L.DomEvent.off(this._map._container, 'touchstart', this._onTouchStart, this);
	},
 
	_onTouchStart: function (e) {
		var map = this._map;
 
		if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; }
 
		var p1 = map.mouseEventToLayerPoint(e.touches[0]),
		    p2 = map.mouseEventToLayerPoint(e.touches[1]),
		    viewCenter = map._getCenterLayerPoint();
 
		this._startCenter = p1.add(p2)._divideBy(2);
		this._startDist = p1.distanceTo(p2);
 
		this._moved = false;
		this._zooming = true;
 
		this._centerOffset = viewCenter.subtract(this._startCenter);
 
		if (map._panAnim) {
			map._panAnim.stop();
		}
 
		L.DomEvent
		    .on(document, 'touchmove', this._onTouchMove, this)
		    .on(document, 'touchend', this._onTouchEnd, this);
 
		L.DomEvent.preventDefault(e);
	},
 
	_onTouchMove: function (e) {
		if (!e.touches || e.touches.length !== 2) { return; }
 
		var map = this._map;
 
		var p1 = map.mouseEventToLayerPoint(e.touches[0]),
		    p2 = map.mouseEventToLayerPoint(e.touches[1]);
 
		this._scale = p1.distanceTo(p2) / this._startDist;
		this._delta = p1._add(p2)._divideBy(2)._subtract(this._startCenter);
 
		if (this._scale === 1) { return; }
 
		if (!this._moved) {
			L.DomUtil.addClass(map._mapPane, 'leaflet-touching');
 
			map
			    .fire('movestart')
			    .fire('zoomstart');
 
			this._moved = true;
		}
 
		L.Util.cancelAnimFrame(this._animRequest);
		this._animRequest = L.Util.requestAnimFrame(
		        this._updateOnMove, this, true, this._map._container);
 
		L.DomEvent.preventDefault(e);
	},
 
	_updateOnMove: function () {
		var map = this._map,
		    origin = this._getScaleOrigin(),
		    center = map.layerPointToLatLng(origin),
		    zoom = map.getScaleZoom(this._scale);
 
		map._animateZoom(center, zoom, this._startCenter, this._scale, this._delta, true);
	},
 
	_onTouchEnd: function () {
		if (!this._moved || !this._zooming) { return; }
 
		var map = this._map;
 
		this._zooming = false;
		L.DomUtil.removeClass(map._mapPane, 'leaflet-touching');
 
		L.DomEvent
		    .off(document, 'touchmove', this._onTouchMove)
		    .off(document, 'touchend', this._onTouchEnd);
 
		var origin = this._getScaleOrigin(),
		    center = map.layerPointToLatLng(origin),
 
		    oldZoom = map.getZoom(),
		    floatZoomDelta = map.getScaleZoom(this._scale) - oldZoom,
		    roundZoomDelta = (floatZoomDelta > 0 ?
		            Math.ceil(floatZoomDelta) : Math.floor(floatZoomDelta)),
 
		    zoom = map._limitZoom(oldZoom + roundZoomDelta),
		    scale = map.getZoomScale(zoom) / this._scale;
 
		map._animateZoom(center, zoom, origin, scale, null, true);
	},
 
	_getScaleOrigin: function () {
		var centerOffset = this._centerOffset.subtract(this._delta).divideBy(this._scale);
		return this._startCenter.add(centerOffset);
	}
});
 
L.Map.addInitHook('addHandler', 'touchZoom', L.Map.TouchZoom);