7

そのため、私は良きネット市民であり、機能検出を使用してブラウザーがサポートしているかどうかを確認し、それ以外の場合はベースのソリューションrequestAnimationFrameにフォールバックするだけです (ポール アイリッシュの有名な投稿の行の周りの何か)。setTimeout

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

Internet Explorer 10 が登場するまで、これはどこでもうまく機能していました。IE10 では、time渡されたパラメーターは現在の時刻とは関係がないようで、 の計算が台無しになりますtimePassed

どうしたの?

4

1 に答える 1

10

(私が知る限り)実装する他のすべてのブラウザrequestAnimationFrameは、(執筆時点で)現在のワーキングドラフトの仕様に従っています:

timeを1970-01-01T00 :00:00Z からのミリ秒数で表した [再描画時間] とします。

それはあなたと同じように時間を正確に表してNOW()います。

ただし、IE10 は現在の編集者のドラフトの仕様に従います。

このコンテキスト内でPerformance インターフェースの now メソッドを呼び出した結果をtimeとします。

これは基本的に、ブラウザがこのページをロードしてからperformance.nowのミリ秒数を意味します (ミリ秒の端数を返すため、測定がより正確であることも意味します)。

timePassedしたがって、IE10 で初めて計算すると、マイナス 43 年のような値が得られます。

幸いなことに、コールバックに渡される値のrequestAnimationFrame単位はどちらの場合も同じで、基準点が異なるだけなので、簡単に調整できます。

次の 3 つの可能性があります。

  1. アニメーションの最初のステップだけを捨てて、を設定するためだけpreviousTimeに使用し、他には何もしないこともできます。
  2. 渡されたパラメーターを無視して、毎回NOW()(またはperformance.now) を使用することで、常に同じ参照ポイントを持つことができます。
  3. または、アニメーションの開始を次のように変更できます。

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

    timePassedこれにより、ブラウザーがどの仕様に従っているかに関係なく、計算 (最初のものを含む) が正しくなります。また、最初の呼び出しのみが変更されるため、長期的には追加のオーバーヘッドもありません。

于 2012-12-18T15:25:25.637 に答える