# 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);