使用Google Maps API v3中的请求动画框架为地图标记设置动画 [英] animating a map marker using request animation frame in google maps api v3

查看:98
本文介绍了使用Google Maps API v3中的请求动画框架为地图标记设置动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设法使用setTimeout在google maps api v3中的路线周围设置google地图标记的动画,但是我想找到一种使用请求动画框架进行动画处理的方法。但是,当我尝试执行此操作时,标记似乎只是从路径的开头跳到结尾,没有动画。有什么想法让我误入歧途吗?这是使用setTimeout编写的代码的相关部分,但是您也可以在 github

I've managed to animate a google map marker around a route in google maps api v3 using setTimeout, but I'd like to find a way to do it using request animation frame. However, when I try to do this - the marker just seems to jump from beginning of the path to the end, with no animation. Any ideas where I'm going astray? Here's the relevant parts of my code using setTimeout, but you can also download / view the files in 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 中:

And what I tried to do with request animation frame was to place this code from 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行。

commenting out the setTimeout and uncommenting the requestanimationframe line. But this didn't work.

我想知道也许您不能传递参数,所以我将函数animateRun更改为不接受任何参数,而是引用了一个全局变量,curDist,但这仍然行不通。我不确定还有什么尝试或可能出什么问题。我可以在requestanimationframe中找到该调用,并且可以正常工作-我什至输入了一种模数作为计时器来尝试降低它的速度(var frameCount = 0,每次调用animateRun时frameCount都会增加。如果framecount%100 = 0 ,请执行animateRun中的所有操作),但这也不起作用。该函数看起来像这样:

I wondered if maybe you couldn't pass parameters, so I changed the function animateRun to accept no parameters, and instead reference a global variable, curDist, but this still didn't work. I'm not sure what else to try or what might be going wrong. I can trace out the call in requestanimationframe and it works - i've even input a sort of modulus as a timer to try and slow it down (var frameCount = 0, frameCount increases once each call to animateRun. If framecount%100 = 0, do all the stuff in animateRun) but that didn't work either. That function looked something like this:

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);


          }

如果有任何想法,谢谢

推荐答案

当您这样做:


requestAnimationFrame(self.animateRun);

requestAnimationFrame(self.animateRun);

您仅传递self.animateRun函数定义的值到requestAnimationFrame时,当您真正需要做的是传递对MapClass的animateRun方法的特定实例的引用时,应保持对当前此对象(自身)的引用。

You are only passing the value of the self.animateRun function definition to requestAnimationFrame, when what you really need to do is pass a reference to the particular instance of MapClass's animateRun method in a manner which maintains a reference to the current 'this' object (self).

然后,在您的startRunnerAnimation函数中,这将是一种清洁的解决方案,用于监视地图对象的tileloaded事件,而不是setTimeout

Then, in your startRunnerAnimation function, it would be a cleaner solution to watch for the map objects tilesloaded event rather than the setTimeout


该函数看起来像这样:

That function looked something like this:

将其以及startRunnerAnimation()函数更改为以下内容:

Change that, as well as your startRunnerAnimation() function to the following:

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();});
    });
}

这篇关于使用Google Maps API v3中的请求动画框架为地图标记设置动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆