如何重新启动此动画地图路线



我正在使用'Gmaps动画路线(https://github.com/henriquea/gmaps-animated-route 在这里找到),现在我一切正常 - 但是我希望当用户再次单击"动画路线"时重置动画。我不知道从哪里开始或在文件中编辑什么,以便地图重置。任何帮助将不胜感激。

如果您需要我提供更多信息或代码,请告诉我。

路线.js

define([
  'gmaps',
  '../underscore',
  './points',
  './filters',
  './styles',
  './animation'],
function(gmaps, _, points, filters, styles, animateRoute){
  function Route(options) {
    this.options = this.extend(this._options, options);
    this.init();
  }
  Route.prototype = {
    // default options
    _options: {
      initializeFilters: true,
      animate: true
    },
    map: {},
    mapTileListener: null,
coordinates: [],
line: {},
enabledFilters: {},
init: function(){
  this.enabledFilters = (this.options.initializeFilters ? filters : {});
  this.parseJSON(points);
},
parseJSON: function(data){
  this.coordinates = data.map(function(item){
    return {
      lat: item.latitude,
      lng: item.longitude,
      timestamp: item.timestamp,
      googLatLng: new gmaps.LatLng(item.latitude, item.longitude)
    }
  });
  this.drawMap();
},
drawMap: function() {
  var self = this,
      forEach = Array.prototype.forEach;
  self.map = new gmaps.Map(document.querySelector(".map"), {
    center: new gmaps.LatLng(41.712167, -90.689098),
    zoom: 14,
    mapTypeId: gmaps.MapTypeId.ROADMAP,
    styles: styles,
    panControl: false,
    zoomControl: false,
    mapTypeControl: false,
    streetViewControl : false,
    scrollwheel: false,
    zoomControlOptions : {
      position: gmaps.ControlPosition.LEFT_BOTTOM,
      style: gmaps.ZoomControlStyle.LARGE
    }
  });
  // Wait map to be fully loaded before set the markers
  self.mapTileListener = gmaps.event.addListener(self.map, 'tilesloaded', function(){
    self.setMarkers();
    gmaps.event.removeListener(self.tileListener);
  });
},
setMarkers: function() {
  var self = this,
      startMarker, endMarker, pin;
  pin = new gmaps.MarkerImage('images/pin.png', null, null, null, new gmaps.Size(38,45));
  startMarker = new gmaps.Marker({
    position: self.coordinates[0].googLatLng,
    icon: pin,
    map: self.map,
    //animation: google.maps.Animation.DROP
  });
  endMarker = new google.maps.Marker({
    position: self.coordinates[self.coordinates.length-1].googLatLng,
    icon: pin,
    map: self.map,
    //animation: google.maps.Animation.DROP
  });
  //self.updateRoutes();
},
updateRoutes: function() {
  var pathCoordinates = _.pluck(this.normalizeCoordinates(), "googLatLng");
  if(this.options.animate) {
    this.enabledFilters = filters;
    pathCoordinates = _.pluck(this.normalizeCoordinates(), "googLatLng");
    animateRoute(pathCoordinates, this.map);
    return;
  }
  this.line = new gmaps.Polyline({
    path: pathCoordinates,
    geodesic: false,
    strokeColor: '#fff000',
    strokeOpacity: 1,
    strokeWeight: 2
  });
  this.line.setMap(this.map);
},
// Remove potentially erroneous points
normalizeCoordinates: function() {
  var self = this;
  var filtersList = _.keys(self.enabledFilters);
  return _.reduce(filtersList, function(memo, filter) {
    return self.enabledFilters[filter](memo);
  }, self.coordinates);
},
playAnimation: function() {
  if (this.line.setMap) {
    this.line.setMap(null);
  }
  this.options.animate = true;
  this.updateRoutes();
},
extend: function(a, b) {
  for (var key in b) {
    if (b.hasOwnProperty(key)) {
      a[key] = b[key];
    }
  }
  return a;
}
}
return Route;
});

动画.js

define(['gmaps'],function(gmaps){
  var animationIndex = 0;
function animateRoute(coords, map) {
var self = this,
    step = 0,
    numSteps = 100,
    animationSpeed = 0.10,
    offset = animationIndex,
    nextOffset = animationIndex + 1,
    departure, destination, nextStop, line, interval;
if (nextOffset >= coords.length) {
  clearInterval(interval);
  return false;
}
departure = coords[offset];
destination = coords[nextOffset];
line = new gmaps.Polyline({
  path: [departure, departure],
  geodesic: false,
  strokeColor: '#fff000',
  strokeOpacity: 0.5,
  strokeWeight: 4,
  map: map
});
interval = setInterval(function() {
  step++;
  if (step > numSteps) {
    animationIndex++;
    animateRoute(coords, map);
    clearInterval(interval);
  } else {
    nextStop = gmaps.geometry.spherical.interpolate(departure,destination,step/numSteps);
    line.setPath([departure, nextStop]);
  }
}, animationSpeed);
}
return animateRoute;
});

点.js

// array of points (latitude, longitude and timestamp)
define([], function() {
  return [
{
  "latitude": "41.71312",
  "longitude": " -90.68956",
  "timestamp": "100"
},
{
  "latitude": "41.70579",
  "longitude": "-90.68943",
  "timestamp": "200"
},
{
  "latitude": "41.70566",
  "longitude": "-90.69617",
  "timestamp": "300"
},
{
  "latitude": "41.70265",
  "longitude": "-90.69411",
  "timestamp": "400"
},
{
  "latitude": "41.69951",
  "longitude": "-90.70046",
  "timestamp": "500"
},
{
  "latitude": "41.70252",
  "longitude": "-90.70638",
  "timestamp": "600"
},
{
  "latitude": "41.70598",
  "longitude": "-90.70775",
  "timestamp": "700"
},
{
  "latitude": "41.70566",
  "longitude": "-90.69248",
  "timestamp": "800"
},
{
  "latitude": "41.7136",
  "longitude": "-90.69213",
  "timestamp": "900"
},
{
  "latitude": "41.71376",
  "longitude": "-90.69574",
  "timestamp": "1000"
},
{
  "latitude": "41.71947",
  "longitude": "-90.696",
  "timestamp": "1100"
},
{
  "latitude": "41.7169",
  "longitude": "-90.69016",
  "timestamp": "1200"
    }
  ]
})

过滤器.js

define(['gmaps', '../GDouglasPeuker'], function(gmaps, GDouglasPeuker) {
return {
  /*
   * Douglas Peucker line simplification routine
   * http://www.bdcc.co.uk/Gmaps/GDouglasPeuker.js
   */
  GDPeuker: function(data) {
    var gdp = GDouglasPeuker(_.pluck(data, "googLatLng"), 23),
        result = _.filter(data, function(c) {
        return _.contains(gdp, c.googLatLng);
      });
    return result;
  },
  /*
   * Calculate a maxium possible distance between the coordinates
   * http://thinkmetric.org.uk/speed.html
   */
  maxDistanceTravelled: function(data) {
    var maxMetersPerSec = 13, // 50km/h
        i, curr, last, result = [];
    for(i=0;i<data.length;i++) {
      curr = data[i];
      if (last) {
        // seconds between current and last coord
        var diff = curr.timestamp - last.timestamp;
        var maxDistance = diff * maxMetersPerSec;
        var traveledDistance = gmaps.geometry.spherical.computeDistanceBetween(last.googLatLng, curr.googLatLng);
        if (traveledDistance > maxDistance) {
          continue;
        } else {
          result.push(curr);
        }
      } else {
        result.push(curr);
      }
      last = curr;
    }
    return result;
  }
 }
});
抱歉,

我不知道如何制作演示。我拼凑的东西太多了。

我在本地尝试了以下更改。通过更改,路径会在单击按钮时重新绘制,但仅在当前动画完成后。

很难正确清除间隔,因此在当前动画完成之前,我无形地阻止了按钮的操作。

我依靠"全局状态",因为我只希望任何时候都出现一个动画。我知道这并不理想,但我尝试了替代方案。简单的方法赢了。

我所做的更改是route.jsanimation.js.我假设您没有更改任何文件。我包括整个文件以便于复制。我进行更改的部分用// ADD注释。

route.js

define([
  'gmaps',
  '../underscore',
  './points',
  './filters',
  './styles',
  './animation'],
function(gmaps, _, points, filters, styles, animateRoute){
  function Route(options) {
    this.options = this.extend(this._options, options);
    this.init();
  }
  Route.prototype = {
    // default options
    _options: {
      initializeFilters: true,
      animate: false
    },
    map: {},
    mapTileListener: null,
    coordinates: [],
    // ADD references to later delete the line
    line: { segments: [] },
    // ADD, because cannot figure out how to manipulate interval
    globalState: { idle: true },

    enabledFilters: {},
    init: function(){
      this.enabledFilters = (this.options.initializeFilters ? filters : {});
      this.parseJSON(points);
    },
    parseJSON: function(data){
      this.coordinates = data.map(function(item){
        return {
          lat: item.latitude,
          lng: item.longitude,
          timestamp: item.timestamp,
          googLatLng: new gmaps.LatLng(item.latitude, item.longitude)
        }
      });
      this.drawMap();
    },
    drawMap: function() {
      var self = this,
          forEach = Array.prototype.forEach;
      self.map = new gmaps.Map(document.querySelector(".map"), {
        center: new gmaps.LatLng(51.512361, -0.1404834),
        zoom: 13,
        mapTypeId: gmaps.MapTypeId.ROADMAP,
        styles: styles,
        panControl: false,
        zoomControl: false,
        mapTypeControl: false,
        streetViewControl : false,
        scrollwheel: false,
        zoomControlOptions : {
          position: gmaps.ControlPosition.LEFT_BOTTOM,
          style: gmaps.ZoomControlStyle.LARGE
        }
      });
      // Wait map to be fully loaded before set the markers
      self.mapTileListener = gmaps.event.addListener(self.map, 'tilesloaded', function(){
        self.setMarkers();
        gmaps.event.removeListener(self.tileListener);
      });
    },
    setMarkers: function() {
      var self = this,
          startMarker, endMarker, pin;
      pin = new gmaps.MarkerImage('images/pin.png', null, null, null, new gmaps.Size(26,31));
      startMarker = new gmaps.Marker({
        position: self.coordinates[0].googLatLng,
        icon: pin,
        map: self.map,
        //animation: google.maps.Animation.DROP
      });
      endMarker = new google.maps.Marker({
        position: self.coordinates[self.coordinates.length-1].googLatLng,
        icon: pin,
        map: self.map,
        //animation: google.maps.Animation.DROP
      });
      //self.updateRoutes();
    },
    updateRoutes: function() {
      var pathCoordinates = _.pluck(this.normalizeCoordinates(), "googLatLng");
      if(this.options.animate) {
        this.enabledFilters = filters;
        pathCoordinates = _.pluck(this.normalizeCoordinates(), "googLatLng");
        // ADD globals
        animateRoute(pathCoordinates, this.map, this.line, 0, this.globalState);
        return;
      }
      this.line = new gmaps.Polyline({
        path: pathCoordinates,
        geodesic: false,
        strokeColor: '#f1d32e',
        strokeOpacity: 1,
        strokeWeight: 2
      });
      this.line.setMap(this.map);
    },
    // Remove potentially erroneous points
    normalizeCoordinates: function() {
      var self = this;
      var filtersList = _.keys(self.enabledFilters);
      return _.reduce(filtersList, function(memo, filter) {
        return self.enabledFilters[filter](memo);
      }, self.coordinates);
    },
    clearRoute: function() {
      this.line.segments.forEach(function(segment) {
        segment.setMap(null);
      }, null);
    },
    playAnimation: function() {
      // ADD
      if (this.globalState.idle) {
        // ADD
        console.log("Clear route and prepare to animate");
        this.clearRoute();
        if (this.line.setMap) {
          this.line.setMap(null);
        }
        this.options.animate = true;
        this.updateRoutes();
      }
    },
    extend: function(a, b) {
      for (var key in b) {
        if (b.hasOwnProperty(key)) {
          a[key] = b[key];
        }
      }
      return a;
    }
  }
  return Route;
});

animation.js

define(['gmaps'],function(gmaps){
  var animationIndex = 0;
  // ADD global parameters
  function animateRoute(coords, map, line, animationIndex, globalState) {
    // ADD, to make redraw possible
    animationIndex = animationIndex || 0;
    var self = this,
    step = 0,
    numSteps = 20,
    animationSpeed = 0.50,
    offset = animationIndex,
    nextOffset = animationIndex + 1,
    departure, destination, nextStop, line, interval;
    // ADD
    globalState.idle = false;
    console.log("animation offset " + nextOffset);
    if (nextOffset >= coords.length) {
      clearInterval(interval);
      globalState.idle = true;
      return false;
    }
    departure = coords[offset];
    destination = coords[nextOffset];
    // ADD
    line.segments.push(new gmaps.Polyline({
      path: [departure, departure],
      geodesic: false,
      strokeColor: '#f1d32e',
      strokeOpacity: 1,
      strokeWeight: 2,
      map: map
      // ADD RIGHT PARENTHESES
    }));
    interval = setInterval(function() {
      step++;
      if (step > numSteps) {
        animationIndex++;
        // ADD references to globals
        animateRoute(coords, map, line, animationIndex, globalState);
        clearInterval(interval);
      } else {
        nextStop = gmaps.geometry.spherical.interpolate(departure,destination,step/numSteps);
        // ADD segment reference
        line.segments[line.segments.length-1].setPath([departure, nextStop]);
      }
    }, animationSpeed);
  }
  return animateRoute;
});