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

时间:2016-04-27 16:41:32

标签: jquery google-maps google-maps-api-3 maps

我正在使用'Gmaps Animted Route(在这里找到https://github.com/henriquea/gmaps-animated-route),而且现在我的一切工作正常 - 但是当用户再次点击“Animate Route”时我想重置动画。我不知道从哪里开始或在文件中编辑什么,以便重置地图。非常感谢任何帮助。

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

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;

});

animation.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;
});

points.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"
    }
  ]
})

filters.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;
  }
 }

});

1 个答案:

答案 0 :(得分:0)

抱歉,我无法弄清楚如何制作演示版。我要拼凑太多东西。

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

我很难让间隔正确清除,所以我无形地阻止了按钮的动作,直到当前动画完成。

我依赖“全局状态”,因为我想在任何时候只发生一个动画。我知道这不太理想,但我尝试了替代品。简单的方式赢了。

我所做的更改位于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;
});