На этом уроке рассмотрим один из вариантов создания анимации на JavaScript , через функцию requestAnimationFrame . По большому счету существует два способа, как сделать анимацию на JS :

Функция requestAnimationFrame

На этом уроке рассмотрим один из вариантов создания анимации на JavaScript, через функцию requestAnimationFrame. По большому счету существует два способа, как сделать анимацию на JS:

  1. через методы setTimeout, setInterval
  2. через функцию requestAnimationFrame

Недостатки setTimeout, setInterval

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

Функция requestAnimationFrame

Функция requestAnimationFrame была создана для решения всех вышеперечисленных проблем. У нее достаточно высокая поддержка среди браузеров. Функция requestAnimationFrame позволяет нам запускать какие-то другие функции в качестве анимаций. Она берет вашу анимацию и подстраивает ее под частоту обновления вашего браузера. Делая так, что ваша анимация будет происходить в тот момент, когда обновляется страничка. Добиваясь плавности анимации и при этом не нагружая компьютер. А если на страничке прописано несколько анимаций, то запускаться они будут одновременно. Звучит хорошо, не правда ли?

Пример анимации с requestAnimationFrame

Нужно плавно переместить по диагонали сверху вниз маленький квадрат внутри большого. Запустит анимацию желтая кнопка.


Функция requestAnimationFrame.

// HTML разметка
<button class="btn">Запуск анимации</button>
<div class="wrapper">
    <div class="box"></div>
</div>

Найдем оба элемента по селектору и поместим их в переменные для наших манипуляций.

const btn = document.querySelector('.btn'),
    elem = document.querySelector('.box');
// Изначальная позиция квадрата
let pos = 0;

requestAnimationFrame запускает функцию myAnimation() в виде коллбэка. Когда позиция элемента станет меньше 300, то нужно запустить анимацию, а если больше, то остановить анимацию. За запуск анимации отвечает requestAnimationFrame, таким образом происходит зацикливание анимации. И когда анимация выполнится 300 раз, то перестанет запускаться.

function myAnimation() {
    pos++; // Увеличиваем позицию квадрата на единицу
    elem.style.top = pos + "px"; // Устанавливаем значение top для инлайн стилей у квадрата
    elem.style.left = pos + 'px'; // // Устанавливаем значение left для инлайн стилей у квадрата

    if (pos < 300) {
        requestAnimationFrame(myAnimation); // Запуск анимации
    }
}

Для запуска анимации в первый раз, отслеживаем клик по кнопке btn и вызываем requestAnimationFrame. Для отмены анимации, нужно вызвать метод cancelAnimationFrame с уникальным идентификатором.

btn.addEventListener('click', () => requestAnimationFrame(myAnimation));

let id = requestAnimationFrame(myAnimation);
cancelAnimationFrame(id);

Посмотрите демо на CodePen