diff --git a/build/deps.js b/build/deps.js index b027fe63..fb8c7866 100644 --- a/build/deps.js +++ b/build/deps.js @@ -19,7 +19,9 @@ var deps = { 'geo/crs/CRS.EPSG3857.js', 'geo/crs/CRS.EPSG4326.js', 'map/Map.js', - 'layer/Layer.js' + 'layer/Layer.js', + 'dom/DomEvent.js', + 'dom/PosAnimation.js' ], desc: 'The core of the library, including OOP, events, DOM facilities, basic units, projections (EPSG:3857 and EPSG:4326) and the base Map class.' }, @@ -234,9 +236,6 @@ var deps = { AnimationPan: { src: [ - 'dom/DomEvent.js', - 'dom/PosAnimation.js', - 'map/anim/Map.PanAnimation.js' ], heading: 'Animation', desc: 'Core panning animation support.' @@ -246,7 +245,6 @@ var deps = { src: [ 'map/anim/Map.ZoomAnimation.js' ], - deps: ['AnimationPan'], desc: 'Smooth zooming animation. Works only on browsers that support CSS3 Transitions.' } }; diff --git a/src/map/Map.js b/src/map/Map.js index 7c8d17f1..c62d7b17 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -137,10 +137,36 @@ L.Map = L.Evented.extend({ // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this // Sets the view of the map (geographical center and zoom) with the given // animation options. - setView: function (center, zoom) { - // replaced by animation-powered implementation in Map.PanAnimation.js - zoom = zoom === undefined ? this.getZoom() : zoom; - this._resetView(L.latLng(center), zoom); + setView: function (center, zoom, options) { + + zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom); + center = this._limitCenter(L.latLng(center), zoom, this.options.maxBounds); + options = options || {}; + + this._stop(); + + if (this._loaded && !options.reset && options !== true) { + + if (options.animate !== undefined) { + options.zoom = L.extend({animate: options.animate}, options.zoom); + options.pan = L.extend({animate: options.animate, duration: options.duration}, options.pan); + } + + // try animating pan or zoom + var moved = (this._zoom !== zoom) ? + this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : + this._tryAnimatedPan(center, options.pan); + + if (moved) { + // prevent resize handler call, the view will refresh after animation anyway + clearTimeout(this._sizeTimer); + return this; + } + } + + // animation didn't start, just reset the map view + this._resetView(center, zoom); + return this; }, @@ -239,14 +265,46 @@ L.Map = L.Evented.extend({ // @method panBy(offset: Point): this // Pans the map by a given number of pixels (animated). - panBy: function (offset) { // (Point) - // replaced with animated panBy in Map.PanAnimation.js - this.fire('movestart'); + panBy: function (offset, options) { + offset = L.point(offset).round(); + options = options || {}; - this._rawPanBy(L.point(offset)); + if (!offset.x && !offset.y) { + return this.fire('moveend'); + } + // If we pan too far, Chrome gets issues with tiles + // and makes them disappear or appear in the wrong place (slightly offset) #2602 + if (options.animate !== true && !this.getSize().contains(offset)) { + this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom()); + return this; + } - this.fire('move'); - return this.fire('moveend'); + if (!this._panAnim) { + this._panAnim = new L.PosAnimation(); + + this._panAnim.on({ + 'step': this._onPanTransitionStep, + 'end': this._onPanTransitionEnd + }, this); + } + + // don't fire movestart if animating inertia + if (!options.noMoveStart) { + this.fire('movestart'); + } + + // animate pan unless animate: false specified + if (options.animate !== false) { + L.DomUtil.addClass(this._mapPane, 'leaflet-pan-anim'); + + var newPos = this._getMapPanePos().subtract(offset).round(); + this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); + } else { + this._rawPanBy(offset); + this.fire('move').fire('moveend'); + } + + return this; }, // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this @@ -1369,6 +1427,27 @@ L.Map = L.Evented.extend({ zoom = Math.round(zoom / snap) * snap; } return Math.max(min, Math.min(max, zoom)); + }, + + _onPanTransitionStep: function () { + this.fire('move'); + }, + + _onPanTransitionEnd: function () { + L.DomUtil.removeClass(this._mapPane, 'leaflet-pan-anim'); + this.fire('moveend'); + }, + + _tryAnimatedPan: function (center, options) { + // difference between the new and current centers in pixels + var offset = this._getCenterOffset(center)._floor(); + + // don't animate too far unless animate: true specified in options + if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; } + + this.panBy(offset, options); + + return true; } }); diff --git a/src/map/anim/Map.PanAnimation.js b/src/map/anim/Map.PanAnimation.js deleted file mode 100644 index 552f7c57..00000000 --- a/src/map/anim/Map.PanAnimation.js +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Extends L.Map to handle panning animations. - */ - -L.Map.include({ - - setView: function (center, zoom, options) { - - zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom); - center = this._limitCenter(L.latLng(center), zoom, this.options.maxBounds); - options = options || {}; - - this._stop(); - - if (this._loaded && !options.reset && options !== true) { - - if (options.animate !== undefined) { - options.zoom = L.extend({animate: options.animate}, options.zoom); - options.pan = L.extend({animate: options.animate, duration: options.duration}, options.pan); - } - - // try animating pan or zoom - var moved = (this._zoom !== zoom) ? - this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : - this._tryAnimatedPan(center, options.pan); - - if (moved) { - // prevent resize handler call, the view will refresh after animation anyway - clearTimeout(this._sizeTimer); - return this; - } - } - - // animation didn't start, just reset the map view - this._resetView(center, zoom); - - return this; - }, - - panBy: function (offset, options) { - offset = L.point(offset).round(); - options = options || {}; - - if (!offset.x && !offset.y) { - return this.fire('moveend'); - } - // If we pan too far, Chrome gets issues with tiles - // and makes them disappear or appear in the wrong place (slightly offset) #2602 - if (options.animate !== true && !this.getSize().contains(offset)) { - this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom()); - return this; - } - - if (!this._panAnim) { - this._panAnim = new L.PosAnimation(); - - this._panAnim.on({ - 'step': this._onPanTransitionStep, - 'end': this._onPanTransitionEnd - }, this); - } - - // don't fire movestart if animating inertia - if (!options.noMoveStart) { - this.fire('movestart'); - } - - // animate pan unless animate: false specified - if (options.animate !== false) { - L.DomUtil.addClass(this._mapPane, 'leaflet-pan-anim'); - - var newPos = this._getMapPanePos().subtract(offset).round(); - this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); - } else { - this._rawPanBy(offset); - this.fire('move').fire('moveend'); - } - - return this; - }, - - _onPanTransitionStep: function () { - this.fire('move'); - }, - - _onPanTransitionEnd: function () { - L.DomUtil.removeClass(this._mapPane, 'leaflet-pan-anim'); - this.fire('moveend'); - }, - - _tryAnimatedPan: function (center, options) { - // difference between the new and current centers in pixels - var offset = this._getCenterOffset(center)._floor(); - - // don't animate too far unless animate: true specified in options - if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; } - - this.panBy(offset, options); - - return true; - } -});