В браузерных анимационных программах мы обычно используем таймер, который циклически запускает целевой объект каждые несколько миллисекунд, заставляя его двигаться. Теперь хорошая новость заключается в том, что разработчики браузеров решили: эй, почему бы нам не предоставить такой API в браузере, чтобы мы могли оптимизировать их анимацию для пользователей. Таким образом, эта функция requestAnimationFrame()
представляет собой API для эффектов анимации. Вы можете использовать ее для изменения стиля анимации DOM, холста или WebGL.
Браузер может оптимизировать параллельные анимационные действия, более разумно перестраивать последовательность действий и выполнять действия, которые можно объединить в один цикл рендеринга, тем самым обеспечивая более плавный эффект анимации. Например, с помощью requestAnimationFrame() анимация JS может происходить одновременно с анимацией/преобразованием CSS или анимацией SVG SMIL. Кроме того, если вы запустите анимацию во вкладке браузера, браузер приостановит ее, когда вкладка не будет видна, что снизит нагрузку на процессор и память и сэкономит заряд батареи.
Использование запросаAnimationFrame// слой оболочки с setTimeout Fallbackwindow.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); };} )();// использование:// вместо setInterval(render, 16) ....(функция animloop(){ requestAnimFrame(animloop); render();})();// поместите rAF *перед* render(), чтобы обеспечить частоту, близкую// к 60 кадрам в секунду с резервным параметром setTimeout.
Более надежная инкапсуляция requestAnimationFrame.
Специалист по браузерам Opera Эрик Мёллер инкапсулировал эту функцию, чтобы сделать ее более совместимой с различными браузерами. Вы можете прочитать эту статью, но в основном его код решает, использовать ли задержку 4 мс или 16 мс, чтобы лучше всего соответствовать 60 кадрам в секунду. Ниже приведен этот код, вы можете его использовать, но обратите внимание, что этот код использует стандартные функции, и я добавил к нему префиксы, совместимые с различными браузерными движками.
(function() { var LastTime = 0; varvendors = ['webkit', 'moz']; for(var x = 0; x <vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } if (!window.requestAnimationFrame) window.requestAnimationFrame = функция (обратный вызов, элемент) {вар currTime = new Date().getTime(); var timeToCall = Math. max(0, 16 - (currTime - LastTime)); var id = window.setTimeout(function() { callback(currTime +) timeToCall); }, timeToCall); LastTime = currTime + timeToCall; return id; if (!window.cancelAnimationFrame) window.cancelAnimationFrame = function(id) {clearTimeout(id);}());
Позвольте мне увидеть эффект от использования requestAnimationFrame.
API запросаAnimationFramewindow.requestAnimationFrame(function(/* time */ time){ // время ~= +new Date // время unix});
Параметры функции обратного вызова могут передаваться во времени.
Поддержка requestAnimationFrame различными браузерами
Google Chrome, Firefox и IE10+ реализуют эту функцию. Даже если ваш браузер очень старый, приведенная выше инкапсуляция requestAnimationFrame может сделать этот метод безошибочным в IE8/9.