Изучите API, чтобы выполнять анимацию и планировать события предсказуемым образом
requestAnimationFrame()
- относительно недавний API-интерфейс браузера. Это дает более предсказуемый способ подключиться к циклу рендеринга браузера.
В настоящее время поддерживается всеми современными браузерами (и IE 10+).
Это не API, специфичный для анимации, но именно там он используется чаще всего.
В JavaScript есть цикл событий. Он постоянно запускается для выполнения JavaScript.
Раньше анимация выполнялась с использованиемsetTimeout()
или жеsetInterval()
. Вы выполняете небольшую анимацию и вызываетеsetTimeout()
чтобы снова повторить этот код через несколько миллисекунд:
const performAnimation = () => {
//...
setTimeout(performAnimation, 1000 / 60)
}
setTimeout(performAnimation, 1000 / 60)
или же
const performAnimation = () => {
//...
}
setInterval(performAnimation, 1000 / 60)
Вы можете остановить анимацию, получив ссылку на тайм-аут или интервал и очистив ее:
let timer
const performAnimation = () => {
//…
timer = setTimeout(performAnimation, 1000 / 60)
}
timer = setTimeout(performAnimation, 1000 / 60)
//…
clearTimeout(timer)
В
1000 / 60
интервал междуperformAnimation()
Количество вызовов определяется частотой обновления монитора, которая в большинстве случаев составляет 60 Гц (60 перерисовок в секунду), поскольку выполнять перерисовку бесполезно, если монитор не может отображать ее из-за своих ограничений. Это приводит к ~ 16,6 мс времени, которое в нашем распоряжении есть для отображения каждого кадра.
Проблема с этим подходом заключается в том, что даже если мы точно укажем эту точность, браузер может быть занят выполнением других операций, и наши вызовы setTimeout могут не успеть к перерисовке, и это будет отложено до следующего цикла.
Это плохо, потому что мы теряем один кадр, а в следующем анимация выполняется 2 раза, из-за чего глаз замечает неуклюжую анимацию.
Проверьте этот пример на Glitch of anанимация построена с использованием setTimeout ().
requestAnimationFrame
- это стандартный способ выполнения анимации, и он работает совершенно по-другому, событие, хотя код очень похож на код setTimeout / setInterval:
let request
const performAnimation = () => {
request = requestAnimationFrame(performAnimation)
//animate something
}
requestAnimationFrame(performAnimation)
//…
cancelAnimationFrame(request) //stop the animation
Этот пример на Glitch of anанимация построена с использованием requestAnimationFrame ()покажи покажи.
Оптимизация
requestAnimationFrame()
так как его введение было очень дружелюбным к процессору, вызывая остановку анимации, если текущее окно или вкладка не видны.
В то время, когда был представлен requestAnimationFrame (), setTimeout / setInterval выполнялся, даже если вкладка была скрыта, но теперь, поскольку этот подход оказался успешным также для экономии заряда батареи, браузеры также реализовали дросселирование для этих событий, позволяя максимум 1 выполнение в секунду. .
С помощьюrequestAnimationFrame
браузер может дополнительно оптимизировать потребление ресурсов и сделать анимацию более плавной.
Примеры временной шкалы
Это идеальная временная шкала, если вы используете setTimeout или setInterval:
у вас есть набор событий рисования (зеленый) и рендеринга (фиолетовый), и ваш код находится в желтом поле - кстати, это цвета, которые используются в Browser DevTools, а также для представления временной шкалы:
На иллюстрации показан идеальный корпус. У вас есть рисование и рендеринг каждые 60 мс, а ваша анимация происходит между ними, совершенно регулярно.
Если вы использовали более частый вызов для своей функции анимации:
Обратите внимание, как в каждом кадре мы вызываем 4 шага анимации до того, как произойдет какой-либо рендеринг, и это сделает анимацию очень прерывистой.
Что делать, если setTimeout не может работать вовремя из-за того, что другой код блокирует цикл событий? Получаем пропущенный кадр:
Что, если шаг анимации занимает немного больше времени, чем вы ожидаете?
события рендеринга и рисования также будут отложены.
Вот какrequestAnimationFrame()
работает визуально:
весь код анимации запускаетсяпередсобытия рендеринга и рисования. Это делает код более предсказуемым, и у нас есть много времени, чтобы сделать анимацию, не беспокоясь о том, что время, которое у нас есть, превышает 16 мс.
Проверятьэто отличное видео Джейка Арчибальдапо теме.
Скачать мою бесплатнуюРуководство для начинающих по JavaScript
Больше руководств по браузеру:
- Некоторые полезные приемы, доступные в HTML5
- Как я заставил веб-сайт на CMS работать в автономном режиме
- Полное руководство по прогрессивным веб-приложениям
- API-интерфейс Fetch
- Руководство по Push API
- API обмена сообщениями канала
- Учебник для сервис-воркеров
- Руководство по Cache API
- Руководство по API уведомлений
- Погрузитесь в IndexedDB
- API селекторов: querySelector и querySelectorAll
- Эффективно загружайте JavaScript с помощью defer и async
- Объектная модель документа (DOM)
- API веб-хранилища: локальное хранилище и хранилище сеансов
- Узнайте, как работают HTTP-файлы cookie
- API истории
- Формат изображения WebP
- XMLHttpRequest (XHR)
- Подробное руководство по SVG
- Что такое URL-адреса данных
- Дорожная карта для изучения веб-платформы
- CORS, совместное использование ресурсов между источниками
- Веб-воркеры
- Руководство по requestAnimationFrame ()
- Что такое Doctype
- Работа с консолью DevTools и консольным API
- API синтеза речи
- Как дождаться события готовности DOM в простом JavaScript
- Как добавить класс к элементу DOM
- Как перебрать элементы DOM из querySelectorAll
- Как удалить класс из элемента DOM
- Как проверить, есть ли у элемента DOM класс
- Как изменить значение узла DOM
- Как добавить событие щелчка в список элементов DOM, возвращаемых из querySelectorAll
- WebRTC, веб-API реального времени
- Как получить позицию прокрутки элемента в JavaScript
- Как заменить элемент DOM
- Как принимать только изображения в поле входного файла
- Зачем использовать предварительную версию браузера?
- Объект Blob
- Файловый объект
- Объект FileReader
- Объект FileList
- ArrayBuffer
- ArrayBufferView
- Объект URL
- Типизированные массивы
- Объект DataView
- API BroadcastChannel
- API Streams
- Объект FormData
- Объект навигатора
- Как использовать API геолокации
- Как использовать getUserMedia ()
- Как использовать API перетаскивания
- Как работать с прокруткой на веб-страницах
- Обработка форм в JavaScript
- События клавиатуры
- События мыши
- Сенсорные события
- Как удалить всех дочерних элементов из элемента DOM
- Как создать атрибут HTML с помощью ванильного Javascript
- Как проверить, установлен ли флажок, используя JavaScript?
- Как скопировать в буфер обмена с помощью JavaScript
- Как отключить кнопку с помощью JavaScript
- Как сделать страницу редактируемой в браузере
- Как получить значения строки запроса в JavaScript с помощью URLSearchParams
- Как сразу удалить весь CSS со страницы
- Как использовать insertAdjacentHTML
- Safari, предупредить перед выходом
- Как добавить изображение в DOM с помощью JavaScript
- Как сбросить форму
- Как использовать Google Fonts