Skip to content

Commit

Permalink
move zoom animation code into Map.js
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Sep 30, 2016
1 parent ff73971 commit 863cf74
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 150 deletions.
14 changes: 0 additions & 14 deletions build/deps.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,20 +232,6 @@ var deps = {
src: ['control/Control.js',
'control/Control.Layers.js'],
desc: 'Layer Switcher control.'
},

AnimationPan: {
src: [
],
heading: 'Animation',
desc: 'Core panning animation support.'
},

AnimationZoom: {
src: [
'map/anim/Map.ZoomAnimation.js'
],
desc: 'Smooth zooming animation. Works only on browsers that support CSS3 Transitions.'
}
};

Expand Down
118 changes: 118 additions & 0 deletions src/map/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ L.Map = L.Evented.extend({


// @section Animation Options
// @option zoomAnimation: Boolean = true
// Whether the map zoom animation is enabled. By default it's enabled
// in all browsers that support CSS3 Transitions except Android.
zoomAnimation: true,

// @option zoomAnimationThreshold: Number = 4
// Won't animate zoom if the zoom difference exceeds this value.
zoomAnimationThreshold: 4,

// @option fadeAnimation: Boolean = true
// Whether the tile fade animation is enabled. By default it's enabled
// in all browsers that support CSS3 Transitions except Android.
Expand Down Expand Up @@ -128,6 +137,17 @@ L.Map = L.Evented.extend({

this.callInitHooks();

// don't animate on browsers without hardware-accelerated transitions or old Android/Opera
this._zoomAnimated = L.DomUtil.TRANSITION && L.Browser.any3d && !L.Browser.mobileOpera &&
this.options.zoomAnimation;

// zoom transitions run with the same duration for all layers, so if one of transitionend events
// happens after starting zoom animation (propagating to the map pane), we know that it ended globally
if (this._zoomAnimated) {
this._createAnimProxy();
L.DomEvent.on(this._proxy, L.DomUtil.TRANSITION_END, this._catchTransitionEnd, this);
}

this._addLayers(this.options.layers);
},

Expand Down Expand Up @@ -1448,6 +1468,104 @@ L.Map = L.Evented.extend({
this.panBy(offset, options);

return true;
},

_createAnimProxy: function () {

var proxy = this._proxy = L.DomUtil.create('div', 'leaflet-proxy leaflet-zoom-animated');
this._panes.mapPane.appendChild(proxy);

this.on('zoomanim', function (e) {
var prop = L.DomUtil.TRANSFORM,
transform = proxy.style[prop];

L.DomUtil.setTransform(proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));

// workaround for case when transform is the same and so transitionend event is not fired
if (transform === proxy.style[prop] && this._animatingZoom) {
this._onZoomTransitionEnd();
}
}, this);

this.on('load moveend', function () {
var c = this.getCenter(),
z = this.getZoom();
L.DomUtil.setTransform(proxy, this.project(c, z), this.getZoomScale(z, 1));
}, this);
},

_catchTransitionEnd: function (e) {
if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
this._onZoomTransitionEnd();
}
},

_nothingToAnimate: function () {
return !this._container.getElementsByClassName('leaflet-zoom-animated').length;
},

_tryAnimatedZoom: function (center, zoom, options) {

if (this._animatingZoom) { return true; }

options = options || {};

// don't animate if disabled, not supported or zoom difference is too large
if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() ||
Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; }

// offset is the pixel coords of the zoom origin relative to the current center
var scale = this.getZoomScale(zoom),
offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);

// don't animate if the zoom origin isn't within one screen from the current center, unless forced
if (options.animate !== true && !this.getSize().contains(offset)) { return false; }

L.Util.requestAnimFrame(function () {
this
._moveStart(true)
._animateZoom(center, zoom, true);
}, this);

return true;
},

_animateZoom: function (center, zoom, startAnim, noUpdate) {
if (startAnim) {
this._animatingZoom = true;

// remember what center/zoom to set after animation
this._animateToCenter = center;
this._animateToZoom = zoom;

L.DomUtil.addClass(this._mapPane, 'leaflet-zoom-anim');
}

// @event zoomanim: ZoomAnimEvent
// Fired on every frame of a zoom animation
this.fire('zoomanim', {
center: center,
zoom: zoom,
noUpdate: noUpdate
});

// Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693
setTimeout(L.bind(this._onZoomTransitionEnd, this), 250);
},

_onZoomTransitionEnd: function () {
if (!this._animatingZoom) { return; }

L.DomUtil.removeClass(this._mapPane, 'leaflet-zoom-anim');

this._animatingZoom = false;

this._move(this._animateToCenter, this._animateToZoom);

// This anim frame should prevent an obscure iOS webkit tile loading race condition.
L.Util.requestAnimFrame(function () {
this._moveEnd(true);
}, this);
}
});

Expand Down
136 changes: 0 additions & 136 deletions src/map/anim/Map.ZoomAnimation.js

This file was deleted.

0 comments on commit 863cf74

Please sign in to comment.