2016-06-03 3 views
1

Я пытаюсь создать простую анимацию холста, где маленький шар вращается вокруг большого шара. Я использую requestAnimationFrame, но он работает не так, как я. Другими словами, моя анимация иногда работает очень медленно (не может идти в ногу с 60fps). Я сделал jsFiddle для более наглядного объяснения.requestAnimationFrame делает canvas анимацию buggy

Кроме того, здесь есть Javascript я использую:

var layer1 = document.getElementById('layer1').getContext('2d'); 
var layer2 = document.getElementById('layer2').getContext('2d'); 

var x; 
var y; 
var angle = 0; 

var last_frame = 0; 

function render(timestamp) { 

    requestAnimationFrame(render); 

    fps = timestamp - last_frame; 
    last_frame = timestamp; 

    // optimal framerate would be 60 (~16ms/"loop") -> count ratio according to that 
    // for example if fps is 32 -> 32/16 = 2 -> we move ball twice the normal distance 
    var delta = fps/16; 

    angle += 0.02 * delta; 

    x = 200 + 100 * Math.cos(angle); 
    y = 200 + 100 * Math.sin(angle); 

    layer1.clearRect(0, 0, 400, 400); 

    layer1.beginPath(); 
    layer1.arc(x, y, 20, 0, Math.PI * 2); 
    layer1.fill(); 

} 
render(16); 

layer2.beginPath(); 
layer2.arc(200, 200, 80, 0, Math.PI * 2); 
layer2.fill(); 

Есть ли что-то случилось с моим кодом или что? Я пытаюсь создать гибридную мобильную игру, используя холст Cordova (PhoneGap) &, но если производительность Javascript окажется такой плохой, я могу сразу забыть об этом.

Кстати: Анимация работает довольно хорошо (большую часть времени) с ноутбуком, но с Samsung Galaxy Вкладка requestAnimationFrame дает мне, как это (60fps, 60fps, 60fps, 29fps, 29fps, 60fps, 60fps, 60fps, 29fps .....)

+0

То, что я имею в виду под «не работает хорошо» является своего рода отставание каждый здесь и там. – Jonathan

+0

Я думаю, что поместить эту строку в конец функции 'requestAnimationFrame (render);' будет действовать иначе, поскольку вы вызовете рекурсию функции после выполнения ее первых строк. попробуйте это решение и сообщите мне результат –

+0

К сожалению, это не имело значения. Мяч все еще отстает. – Jonathan

ответ

0

Недостаточно заметить отставание, но оно есть. Я скорректировал ваш код, чтобы сделать лаг более заметным.

var layer1 = document.getElementById('layer1').getContext('2d'); 
 
var layer2 = document.getElementById('layer2').getContext('2d'); 
 

 
var x; 
 
var y; 
 
var angle = 0; 
 
var last_frame = 0; 
 
layer1.globalAlpha = .5; 
 

 
function render(timestamp) { 
 

 
    fps = timestamp - last_frame; 
 
    last_frame = timestamp; 
 

 
    // optimal framerate would be 60 (~16ms/"loop") -> count ratio according to that 
 
    // for example if fps is 32 -> 32/16 = 2 -> we move ball twice the normal distance 
 
    var delta = fps/16; 
 

 
    if (angle > Math.PI * 2) { 
 
    layer1.clearRect(0, 0, 400, 400); 
 
    angle %= Math.PI * 2; 
 
    } 
 

 
    angle += 0.02 * delta; 
 
    x = 200 + 100 * Math.cos(angle); 
 
    y = 200 + 100 * Math.sin(angle); 
 

 
    layer1.beginPath(); 
 
    layer1.arc(x, y, 20, 0, Math.PI * 2); 
 
    layer1.stroke(); 
 
    requestAnimationFrame(render); 
 
} 
 
render(16); 
 
layer2.beginPath(); 
 
layer2.arc(200, 200, 80, 0, Math.PI * 2); 
 
layer2.fill();
canvas, 
 
#frames_label { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
}
<canvas id="layer1" width="400" height="400"> 
 
</canvas> 
 
<canvas id="layer2" width="400" height="400"> 
 
</canvas> 
 
<div id="frames_label"></div>

Смежные вопросы