2015-04-30 10 views
8

arasındaki saat farkı nasıl alınır javascript'te "window.requestAnimationFrame" geri bildirimi arasındaki zaman farkını almanın en iyi yolu nedir?Javascript: window.requestAnimationFrame

denedim:

// create the best .requestAnimationFrame callback for each browser 
window.FPS = (function() { 
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || 
    function(callback) {window.setTimeout(callback, 1000/60);}; 
})(); 

// start animation loop 
var dt, stamp = (new Date()).getTime(); 
function loop() { 
    window.FPS(loop); 
    var now = (new Date()).getTime(); 
    var dt = now - stamp; 
    stamp = now; 
} 
// has "dt" the best accuracy? 
+1

potansiyel yinelenen: http://stackoverflow.com/questions/8279729/calculate-fps-in-canvas- use-requestanimationframe –

+0

Geri dönüşün tek bir parametre, bir zaman damgası (tam yerel requestAnimationFrame uygulamalarında) geçtiğinden kesinlikle emin olun, eğer polifil için destek arıyorsanız, orada zaman damgası parametresine sahip olduğunuzdan daha iyi zaman damgası parametresi taklit edenler var window.FPS polyfill. [Bu] (https://gist.github.com/timhall/4078614) belki de gördüğüm daha iyi olanlardan biridir. [This] ile ilgili (http://stackoverflow.com/questions/13241314/up-to-date-polyfill-for-requestanimationframe) SO soru – OJay

+1

Btw, tamamen IEFE ve "geri dönüşü" nü atabilir, sadece atayabilirsiniz window.raf =… || … || işlev (cb) {…}; ' – Bergi

cevap

2

modern tarayıcıların çoğu otomatik olarak her requestAnimation geri arama döngüye bir argüman olarak bir yüksek hassasiyetli zaman damgası göndermek: http://caniuse.com/#search=performance

Yani basitçe geçerli zaman damgası son zaman damgası çıkarma Döngünün son çalıştırılmasından bu yana geçen süreyi elde etmek için.

İşte örnek kod ve Demo var:

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 
var startingTime; 
 
var lastTime; 
 
var totalElapsedTime; 
 
var elapsedSinceLastLoop; 
 

 
var $total=$('#total'); 
 
var $loop=$('#loop'); 
 

 
requestAnimationFrame(loop); 
 

 
function loop(currentTime){ 
 
    if(!startingTime){startingTime=currentTime;} 
 
    if(!lastTime){lastTime=currentTime;} 
 
    totalElapsedTime=(currentTime-startingTime); 
 
    elapsedSinceLastLoop=(currentTime-lastTime); 
 
    lastTime=currentTime; 
 
    $total.text('Since start: '+totalElapsedTime+' ms'); 
 
    $loop.text('Since last loop: '+elapsedSinceLastLoop+' ms'); 
 
    requestAnimationFrame(loop); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<p id=total>T1</p> 
 
<p id=loop>T2</p> 
 
<canvas id="canvas" width=300 height=300></canvas>

Performance desteklemeyen tarayıcılar çift için, hiçbir beri döngünün içine currentTime yerine Date.now() kullanmak zorunda olacak zaman damgası bu tarayıcılar tarafından otomatik olarak döngüye gönderilir.

+0

Oradaki parite nedir? Bir js altın rozet sahibi olarak daha iyi bilmelisiniz! – Bergi

+0

@Bergi. Chuckle, kabul etti! – markE

4

"dt" en iyi doğruluğa sahip? requestAnimationFrame tarafından sıraya geri aramalar

yangın başladığında geçerli zamanı gösterir geri arama yöntemi tek bir bağımsız değişken geçirilir

the docs göre

No. bir DOMHighResTimeStamp,

, böylece yüksek hassasiyet almak için bunu kullanmayı tercih etmelisiniz.

function loop(now) { 
    var last = now || Date.now(); // fallback if no precise time is given 
    window.FPS(function(now) { 
     now = now || Date.now(); 
     var dt = now - last; 
     if (dt != 0) // something might be wrong with our frames 
      console.log(dt); 
     loop(now); 
    }); 
} 
window.FPS(loop); 

(jsfiddle demo)

+0

Ayrıca, dikkat edilmesi gereken diğer bir nokta da, rAF zaman damgasının, her durumda 16.67ms, 16.67x2 vb. ile monitör yenileme hızıyla senkronize edildiği şekilde bir miktar nicelleştirileceğidir. – K3N

+0

var last = now || Date.now() yanlış olduğunu düşünüyorum. "now", animFrame'ın başlamasından bu yana geçen zaman damgasıdır. Date.now(), Unix zaman damgası – marirena

+0

@marirena'dır: Hayır, '' '* * geçerli süreyi * gösterir *" doc'lara göre, rAF’ın çağrılmasından beri zaman çizelgesi değil. Sadece Tarih olarak mutlak milisaniye zaman damgası.Şimdi, ama daha büyük bir doğrulukla (ve muhtemelen farklı bir köken). Tamamen ihmal edebilirsiniz '|| … 'Kısmı da, uyumsuz rAF şimleri için bir geri dönüş. – Bergi

2

Bu desenini kullanmak isteyen herkes için net bir sonuca, yazacak

// CREATING AN FPS ENGINE 

window.FPS = (function() { 
    return window.requestAnimationFrame || 
    window.webkitRequestAnimationFrame || 
    window.mozRequestAnimationFrame || 
    window.oRequestAnimationFrame || 
    window.msRequestAnimationFrame || 
    function(callback) {window.setTimeout(callback, 1000/60);}; 
})(); 

var FPS = { 
    loop: function(canvas_object) { // OPTIONAL canvas_object, I think it increases performance | canvas_object = document.getElementById("canvas_id") 
     var ticks = window.FPS(function(now){ 
      var dt = now - FPS.stamp || 0; 
      FPS.stamp = now; 
      FPS.update(dt, FPS.stamp, ticks); 
      FPS.loop(canvas_object); 
     }, canvas_object); 

    }, 
    update: undefined, 
    stamp: undefined 
}; 

// USING THE FPS ENGINE 

FPS.loop(the_canvas_object); // starts the engine 
FPS.update = function(dt, stamp, ticks) { 
    // The game/video loop, using accurate dt. Stamp is the time since engine started. Ticks is the number of the loop cycles 
    console.log("dt: " + dt + ", Stamp: " + stamp + ", Ticks: " + ticks); // check output 
    // HAPPY GAME CREATING 
    var fps= (1/(dt/1000)).toFixed(1); 
}; 
+1

'(1/(dt/1000))' buna basitleştirilebilir: '(1000/dt)'. Neden böyle yaptığını anlamıyorum. –