javascript - requestAnimationFrame is passing unexpected parameters in IE10 - Stack Overflow

So I've been a good net citizen, using feature detection to see whether the browser supports reque

So I've been a good net citizen, using feature detection to see whether the browser supports requestAnimationFrame and only fall back to a setTimeout-based solution otherwise (something around the lines of Paul Irish's famous post).

var NOW = Date.now || function () { return new Date.getTime(); };
var reqAnimFrame =
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        /*                        ... ||                     */
        function (callback) {
            setTimeout(function () { callback(NOW()); }, 1000 / 60);
        };

var previousTime = NOW();
function animStep(time) {
    var timePassed = time - previousTime;
    myCharacter.move(myCharacter.speed * timePassed);
    previousTime = time;
    reqAnimationFrame(animStep);
} 

// start the animation
reqAnimationFrame(animStep); 

This worked great everywhere until Internet Explorer 10 came along. In IE10, the time parameter passed doesn't seem to have anything to do with the current time, screwing up the calculation of timePassed.

What's going on?

So I've been a good net citizen, using feature detection to see whether the browser supports requestAnimationFrame and only fall back to a setTimeout-based solution otherwise (something around the lines of Paul Irish's famous post).

var NOW = Date.now || function () { return new Date.getTime(); };
var reqAnimFrame =
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        /*                        ... ||                     */
        function (callback) {
            setTimeout(function () { callback(NOW()); }, 1000 / 60);
        };

var previousTime = NOW();
function animStep(time) {
    var timePassed = time - previousTime;
    myCharacter.move(myCharacter.speed * timePassed);
    previousTime = time;
    reqAnimationFrame(animStep);
} 

// start the animation
reqAnimationFrame(animStep); 

This worked great everywhere until Internet Explorer 10 came along. In IE10, the time parameter passed doesn't seem to have anything to do with the current time, screwing up the calculation of timePassed.

What's going on?

Share asked Dec 18, 2012 at 15:25 balphabalpha 51k18 gold badges113 silver badges132 bronze badges 3
  • quite surprisingly... that would have been the first time that Internet Explorer deviates from the spec. I'm shocked! – jAndy Commented Dec 18, 2012 at 15:27
  • @jAndy Well in this case, you could say they're ahead of the other browsers in following it. – balpha Commented Dec 18, 2012 at 15:29
  • And that is exactly the point: IE messed up for years and now they're trying to be good guy following the standards tightly. Hopefully it will balance out in the future. – Sander Commented Apr 15, 2013 at 14:20
Add a ment  | 

1 Answer 1

Reset to default 9

All (as far as I know) other browsers that implement requestAnimationFrame go by the specification in the (at the time of writing) current Working Draft:

Let time be [the redraw time] expressed as the number of milliseconds since 1970-01-01T00:00:00Z.

That's representing time precisely like your NOW() does.

IE10 however goes by the spec in the current Editor's Draft:

Let time be the result of invoking the now method of the Performance interface within this context.

Which essentially means the number of milliseconds since the browser loaded this page (it also means the the measurement is more precise, since performance.now returns fractional milliseconds).

And thus when you calculate timePassed for the first time in IE10, you are getting something like negative 43 years.

Fortunately, because the value passed to the requestAnimationFrame callback has the same unit in either case, just a different point of reference, you can easily adjust to this.

There are three possibilities:

  1. You could just throw away the very first animation step, using it only to set previousTime, but not doing anything else.
  2. You could ignore the passed parameter and use your NOW() (or performance.now) every time, thus always having the same same point of reference.
  3. Or you could change the start of the animation to this:

    // start the animation
    reqAnimationFrame(function (t) {
        previousTime = t - (NOW() - previousTime);
        animStep(t);
    );
    

    This will make the calculation (including the first one) of timePassed correct no matter which spec the browser follows. And since it changes only the very first invocation, you don't have any additional overhead in the long run either.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744932913a4601845.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信