【问题标题】:animating a map marker using request animation frame in google maps api v3在 google maps api v3 中使用请求动画帧为地图标记设置动画
【发布时间】:2020-02-12 07:40:06
【问题描述】:

我已经设法使用 setTimeout 在 google maps api v3 中的路线周围为 google map 标记设置动画,但我想找到一种使用请求动画帧的方法。但是,当我尝试这样做时 - 标记似乎只是从路径的开头跳到了结尾,没有动画。有什么想法我会误入歧途吗?这是我使用 setTimeout 的代码的相关部分,但您也可以下载/查看 github 中的文件:

self.animateRun = function(curDist){ //moves the runner
  if (curDist > runnerAnimationConfig.dist) { //if we've passed the end point, exit this loop and focus on the endpoint

    var endLatLng = getLatLng(raceMarkers.endPoint.lat,raceMarkers.endPoint.lng);

    self.map.panTo(endLatLng);
    runnerMarker.setPosition();
    return;
  }

  var curPoint = racePath.GetPointAtDistance(curDist); 
  self.map.panTo(curPoint);
  runnerMarker.setPosition(curPoint);
  var newDist = curDist + runnerAnimationConfig.step;
  //requestAnimationFrame(self.animateRun(newDist));
  timerHandle = setTimeout("MAP.animateRun("+(curDist+runnerAnimationConfig.step)+")", runnerAnimationConfig.tick);

}

我对请求动画帧所做的尝试是将此代码从creativeJS:

// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

// requestAnimationFrame polyfill by Erik Möller
// fixes from Paul Irish and Tino Zijdel

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

注释掉 setTimeout 并取消注释 requestanimationframe 行。但这不起作用。

我想知道你是不是不能传递参数,所以我将函数 animateRun 更改为不接受参数,而是引用一个全局变量 curDist,但这仍然不起作用。我不确定还有什么可以尝试或可能出了什么问题。我可以在 requestanimationframe 中追踪调用并且它有效 - 我什至输入了一种模数作为计时器来尝试减慢它(var frameCount = 0,frameCount 在每次调用 animateRun 时增加一次。如果 framecount%100 = 0 ,在 animateRun 中做所有的事情),但这也不起作用。该函数看起来像这样:

var curDist = 0;
var curFrame = 0;
runnerAnimationConfig.step = 5;

    self.animateRun = function(){ //moves the runner



            if (curDist > runnerAnimationConfig.dist) { //if we've passed the end point, exit this loop and focus on the endpoint

              var endLatLng = getLatLng(raceMarkers.endPoint.lat,raceMarkers.endPoint.lng);

              self.map.panTo(endLatLng);
              runnerMarker.setPosition();
              return;
            }

            if (curFrame%100 === 0){

            var curPoint = racePath.GetPointAtDistance(curDist); 
            self.map.panTo(curPoint);
            runnerMarker.setPosition(curPoint);

            }

            curFrame += 1;
            curDist = curDist + runnerAnimationConfig.step;

            requestAnimationFrame(self.animateRun);


          }

如果您对如何解决此问题有任何想法,谢谢。

【问题讨论】:

    标签: javascript google-maps animation google-maps-api-3 requestanimationframe


    【解决方案1】:

    当你这样做时:

    requestAnimationFrame(self.animateRun);

    您只是将 self.animateRun 函数定义的值传递给 requestAnimationFrame,而您真正需要做的是以保持对当前 'this 的引用的方式传递对 MapClass 的 animateRun 方法的特定实例的引用' 对象(自我)。

    然后,在您的 startRunnerAnimation 函数中,监视地图对象的 tilesloaded 事件而不是 setTimeout 会是一个更简洁的解决方案

    那个函数看起来像这样:

    将它以及您的 startRunnerAnimation() 函数更改为以下内容:

    self.curDist = 0;
    
    self.animateRun = function(){ //moves the runner
            if (self.curDist > runnerAnimationConfig.dist) { //if we've passed the end point, exit this loop and focus on the endpoint
              var endLatLng = getLatLng(raceMarkers.endPoint.lat,raceMarkers.endPoint.lng);
              self.map.panTo(endLatLng);
              runnerMarker.setPosition();
              return;
            }
            var curPoint = racePath.GetPointAtDistance(self.curDist); 
            self.map.panTo(curPoint);
            runnerMarker.setPosition(curPoint);
            self.curDist += runnerAnimationConfig.step;
            window.requestAnimationFrame(function () {self.animateRun();});
    };
    
    function startRunnerAnimation(){
        runnerAnimationConfig.dist = racePath.Distance();
        self.map.setCenter(racePath.getPath().getAt(0));
        var lstnr = google.maps.event.addListener(self.map, 'tilesloaded', function () {
             //only want this happening on initial load, not every time the tiles change
            google.maps.event.removeListener(lstnr);
            window.requestAnimationFrame(function () {self.animateRun();});
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-27
      • 2012-06-09
      • 2012-07-04
      • 1970-01-01
      • 2011-04-20
      相关资源
      最近更新 更多