"Helicopter" panning in Leaflet

(a sort of poor man's flyTo)

by nathansnider

HTML

<script src="http://cdn.leafletjs.com/leaflet/v1.0.0-beta.2/leaflet.js"></script>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v1.0.0-beta.2/leaflet.css">
<div class="btn-group">
  <button class="btn" onclick="helicopterTo([34.42, -119.7], 12, 2)">Santa Barbara</button>
  <button class="btn" onclick="helicopterTo([34.05, -118.25], 12, 2)">Los Angeles</button>
</div>
<div id="map" style="height: 500px"></div>

JavaScript

var map = new L.Map('map').setView([34.2, -119.2], 12);

L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

//INPUTS:
//latLng: (see http://leafletjs.com/reference.html#latlng)
//zoomLevel (integer)
//panDuration (numeric, in seconds)
helicopterTo = function(latLng, zoomLevel, panDuration) {
  map.off('moveend');
  map.off('zoomend');
  map.on('zoomend', function() {
    map.panTo(latLng, {
      animate: true,
      duration: panDuration
    });
  });
  map.setView(map.getCenter(), Math.min(zoomLevel - 1, map.getZoom() - 1), {
    animate: true
  });
  setTimeout(function() {
    map.off('zoomend');
  }, 300);
  setTimeout(function() {
    map.on('moveend', function() {
      map.setView(latLng, zoomLevel, {
        "animate": true
      });
    })
  }, 500);
  setTimeout(function() {
    map.off('moveend');
  }, panDuration * 1000 + 300);
}