2014-11-01 2 views
0

Я следую по this книги, чтобы узнать о html5 холст анимации, и мне было интересно, в этом коде:Почему запросAnimFrame называется 2 раза?

// shim layer with setTimeout fallback 
window.requestAnimFrame = (function(){ 
    return window.requestAnimationFrame  || 
      window.webkitRequestAnimationFrame || 
      window.mozRequestAnimationFrame || 
      window.oRequestAnimationFrame  || 
      window.msRequestAnimationFrame  || 
      function(callback){ 
      window.setTimeout(callback, 1000/60); 
      }; 
})(); 

var x = 0; 
function drawIt() { 
    window.requestAnimFrame(drawIt); 
    var canvas = document.getElementById('canvas'); 
    var c = canvas.getContext('2d'); 
    c.fillStyle = "red"; 
    c.fillRect(x,100,200,100); 
    x+=5; 
} 
window.requestAnimFrame(drawIt); 

Почему window.requestAnimFrame(drawIt) называют как снаружи, так и внутри DRAWIT функции?

+1

Нижний вызов запускает цикл drawIt для запуска. Вызов внутри цикла drawIt заставляет цикл продолжать. – markE

+1

Тот, что находится вне функции 'drawIt', похож на зажигание. Без него цикл анимации не начнется. – soktinpk

+1

BTW, [нет такой вещи, как 'oRequestAnimationFrame' или' msRequestAnimationFrame'] (http://caniuse.com/#feat=requestanimationframe). Вы можете удалить их. –

ответ

0

Чтобы уточнить, что большинство из них уже говорилось в комментариях (с некоторыми дополнительными подсказками) -

requestAnimationFrame делает один асинхронный вызов функции передается в качестве аргумента. Это означает, что метод необходимо вызывать непрерывно, чтобы создать цикл анимации.

Логическое место для вызова вызова для обновления следующего кадра происходит из самого цикла. Однако цикл является просто функцией и должен также вызываться, поэтому для «запуска» цикла требуется начальный вызов. (По этой причине также разумно рассмотреть механизм разрыва цикла).

Другой метод может заключаться в использовании самозапускаемого вызова. Код будет в этом случае выглядеть следующим образом вместо того, чтобы, без первоначального вызова:

(function drawIt() { 
    window.requestAnimFrame(drawIt); 
    var canvas = document.getElementById('canvas'); 
    var c = canvas.getContext('2d'); 
    c.fillStyle = "red"; 
    c.fillRect(x,100,200,100); 
    x+=5; 
})(); 

функции внутри первой пару скобок вычисляются в то время как вторая пара будет вызывать вызов для любого вычисляются, то есть. функция. Если вы выбрали это или оригинал, это более или менее вопрос личного вкуса (первый кадр не обновляется до тех пор, пока первый доступный обновленный монитор не будет обновлен, так что вы не будете иметь никаких сбоев, делающих обновление вручную в первый раз).

Еще одна вещь, которую стоит отметить на этом: получение ссылок на холст и контекст обычно не делается внутри цикл, поскольку они являются относительно дорогостоящими операциями. Постарайтесь, чтобы всегда получать те вне цикла, и только один раз:

var canvas = document.getElementById('canvas'); 
var c = canvas.getContext('2d'); 

(function drawIt() { 
    window.requestAnimFrame(drawIt); 
    c.fillStyle = "red";  // also a potential candidate for optimizing 
    c.fillRect(x,100,200,100); 
    x+=5; 
})(); 

Если вы установите цвет только один раз, это тоже может быть перемещен за пределы цикла (т.е. fillStyle, strokeStyle и др.). Они также являются дорогостоящими с точки зрения анимации.

+0

Благодарим вас за полный ответ. Я принимаю как правильный. – tibuurcio

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