87 lines
3.1 KiB
JavaScript
87 lines
3.1 KiB
JavaScript
/*
|
|
* L.Handler.TouchZoom is used internally by L.Map to add touch-zooming on Webkit-powered mobile browsers.
|
|
*/
|
|
|
|
L.Handler.TouchZoom = L.Handler.extend({
|
|
enable: function() {
|
|
if (!L.Browser.mobileWebkit || this._enabled) { return; }
|
|
L.DomEvent.addListener(this._map._container, 'touchstart', this._onTouchStart, this);
|
|
this._enabled = true;
|
|
},
|
|
|
|
disable: function() {
|
|
if (!this._enabled) { return; }
|
|
L.DomEvent.removeListener(this._map._container, 'touchstart', this._onTouchStart, this);
|
|
this._enabled = false;
|
|
},
|
|
|
|
_onTouchStart: function(e) {
|
|
if (!e.touches || e.touches.length != 2 || this._map._animatingZoom) { return; }
|
|
|
|
var p1 = this._map.mouseEventToLayerPoint(e.touches[0]),
|
|
p2 = this._map.mouseEventToLayerPoint(e.touches[1]),
|
|
viewCenter = this._map.containerPointToLayerPoint(this._map.getSize().divideBy(2));
|
|
|
|
this._startCenter = p1.add(p2).divideBy(2, true);
|
|
this._startDist = p1.distanceTo(p2);
|
|
//this._startTransform = this._map._mapPane.style.webkitTransform;
|
|
|
|
this._moved = false;
|
|
this._zooming = true;
|
|
|
|
this._centerOffset = viewCenter.subtract(this._startCenter);
|
|
|
|
L.DomEvent.addListener(document, 'touchmove', this._onTouchMove, this);
|
|
L.DomEvent.addListener(document, 'touchend', this._onTouchEnd, this);
|
|
|
|
L.DomEvent.preventDefault(e);
|
|
},
|
|
|
|
_onTouchMove: function(e) {
|
|
if (!e.touches || e.touches.length != 2) { return; }
|
|
|
|
if (!this._moved) {
|
|
this._map._mapPane.className += ' leaflet-zoom-anim';
|
|
this._map._prepareTileBg();
|
|
this._moved = true;
|
|
}
|
|
|
|
var p1 = this._map.mouseEventToLayerPoint(e.touches[0]),
|
|
p2 = this._map.mouseEventToLayerPoint(e.touches[1]);
|
|
|
|
this._scale = p1.distanceTo(p2) / this._startDist;
|
|
this._delta = p1.add(p2).divideBy(2, true).subtract(this._startCenter);
|
|
|
|
/*
|
|
* Used 2 translates instead of transform-origin because of a very strange bug -
|
|
* it didn't count the origin on the first touch-zoom but worked correctly afterwards
|
|
*/
|
|
this._map._tileBg.style.webkitTransform = [
|
|
L.DomUtil.getTranslateString(this._delta),
|
|
L.DomUtil.getScaleString(this._scale, this._startCenter)
|
|
].join(" ");
|
|
|
|
L.DomEvent.preventDefault(e);
|
|
},
|
|
|
|
_onTouchEnd: function(e) {
|
|
if (!this._moved || !this._zooming) { return; }
|
|
this._zooming = false;
|
|
|
|
var oldZoom = this._map.getZoom(),
|
|
floatZoomDelta = Math.log(this._scale)/Math.LN2,
|
|
roundZoomDelta = (floatZoomDelta > 0 ? Math.ceil(floatZoomDelta) : Math.floor(floatZoomDelta)),
|
|
zoom = this._map._limitZoom(oldZoom + roundZoomDelta),
|
|
zoomDelta = zoom - oldZoom,
|
|
centerOffset = this._centerOffset.subtract(this._delta).divideBy(this._scale),
|
|
centerPoint = this._map.getPixelOrigin().add(this._startCenter).add(centerOffset),
|
|
center = this._map.unproject(centerPoint);
|
|
|
|
L.DomEvent.removeListener(document, 'touchmove', this._onTouchMove);
|
|
L.DomEvent.removeListener(document, 'touchend', this._onTouchEnd);
|
|
|
|
var finalScale = Math.pow(2, zoomDelta);
|
|
|
|
this._map._runAnimation(center, zoom, finalScale / this._scale, this._startCenter.add(centerOffset));
|
|
}
|
|
}); |