2014-09-16 26 views
6

Ich würde gerne setInterval für tatsächliche Schritte in einem Programm und requestAnimationFrame zum Rendern verwenden. Ich hatte den Eindruck, dass dies der perfekte Mix wäre: Die Rendering-Geschwindigkeit würde die tatsächliche Progression nicht verlangsamen, also würde die Dips-in-Frame-Rate nur die Bildrate beeinflussen und trotzdem synchronisieren. Was ich jedoch bekam, waren Tropfen in der setInterval Funktion.Verwenden von setInterval mit requestAnimationFrame

Ein Beispiel dafür, was ich meine, stecken absichtlich mit Schatten unten: http://jsfiddle.net/Ltdz168m/

die Anzahl der Minen verringern oder erhöhen und Sie werden den Unterschied

Es scheint, dass tatsächlich request nicht ist zu sehen eine Lösung für das Rendern von Verzögerungen, die JavaScript verlangsamen. Wie würde ich dann die logische Seite der Dinge aktualisieren, die mit 60 fps ohne Behinderung durch das Rendern gemacht werden kann? Sind WebWorker absolut notwendig?

Antwort

17

Das Problem ist, dass der Browser immer noch nur eine Sache zu einer Zeit machen kann. Wenn es also gerendert wird, kann es die Position nicht aktualisieren.

Wenn Sie Dinge tun, um variable Frameraten zu unterstützen, sollten Sie immer Delta Timing verwenden. Es funktioniert ungefähr so:

requestAnimationFrame(function(e) { 
 
    document.getElementById('status').innerHTML = "Delta time: "+e; 
 
    
 
    // lag randomly 
 
    while(Math.random() > 0.0000001) {} 
 
    
 
    requestAnimationFrame(arguments.callee); 
 
});
<div id="status"></div>

Wie Sie (hoffentlich), unabhängig von der Framerate, die Delta-Zeit gezeigt nach oben geht konsequent sehen. Dies bedeutet, dass Sie zum Beispiel angleFromStart = e/1000*Math.PI*2; tun können und Ihr Punkt wird mit genau 60 RPM umlaufen.

var angle=0, 
 
    radian=Math.PI/180; 
 
var canvas=document.getElementById("canvas"), 
 
    context=canvas.getContext("2d"); 
 
context.shadowColor="black"; 
 
context.shadowBlur=100; 
 
requestAnimationFrame(function draw(e) { 
 
    angle = e/1000*Math.PI*2; 
 
    var x=canvas.width/2+Math.cos(angle)*canvas.width/4, 
 
     y=canvas.height/2+Math.sin(angle)*canvas.height/4; 
 
    context.clearRect(0, 0, canvas.width, canvas.height); 
 
    context.beginPath(); 
 
    context.arc(x, y, 5, 0, Math.PI*2); 
 
    context.closePath(); 
 
    for(var i=0; i<255; i++) { 
 
     context.fill(); 
 
    } 
 
    requestAnimationFrame(draw); 
 
});
#canvas { 
 
    border: 1px solid black; 
 
}
<canvas id="canvas"></canvas>

PS: Ich liebe die neue Stack-Snippet-Funktion!

+0

Ich dachte daran, aber Junge wäre es eine Menge Arbeit. Ich nehme an, es ist jedoch notwendige Arbeit. Und ich muss zustimmen, das ist ein nettes Feature; beats jfiddle links. –

+0

Es ist eigentlich weniger Code, um Delta Timing zu verwenden als 'setInterval';) –

+0

Nun, ich hatte gerade eine Schleife mit einem .update() auf alles eingerichtet, also muss ich damit beginnen und das anwenden zu ziemlich viel Mathearbeit (weit mehr als dieses Beispiel). Trotzdem sollte es sich auszahlen, die Dinge zu synchronisieren. –

Verwandte Themen