Найти в Дзене

JavaScript. Плавная анимация

Logo by Paltus-Pangasius-Zubatka
Logo by Paltus-Pangasius-Zubatka

Для создания анимации на JavaScript, я до недавнего времени использовал метод setInterval(). Всё вроде удобно и понятно, отдаешь в качестве параметра функцию, которая рисует кадры, указываешь вторым параметром частоту обновления в миллисекундах, и всё работает.

Пример использования метода setInterval()
Пример использования метода setInterval()

Но есть конечно нюансы. Во-первых анимация получается дерганой. Во-вторых, заметно тормозит при использовании тач и активном использовании клавиатуры - это особенно явно проявляется при создании игр. Что же делать? Вот тут я и пришел к спасению в виде метода window.requestAnimationFrame(), который рисует кадры с частотой обновления экрана и делает это даже при большой нагрузке на браузер, например от обработки тач.

Пример использования метода requestAnimationFrame()
Пример использования метода requestAnimationFrame()

Однако, если частота фиксирована, а это для современных экранов как правило 60 кадров в секунду, получается, что управлять скоростью анимации уже не выйдет так же легко, как в случае с setInterval(). Как решить эту проблему? Первое, что приходит в голову для ускорения анимации, это сделать приращение координат анимируемого объекта больше, тогда визуально скорость его перемещения вырастет. Больше приращение, больше скорость. Всё бы ничего, но выходит, что замедлить анимацию невозможно. Медленнее, чем сдвигать объект на 1 пиксель в 1/60 секунды вроде как не получится. И вот тут начинается магия - JavaScript умеет дробные пиксели! Для регулирования скорости можно использовать дробные приращения координат! Это работает, и для меня стало сюрпризом. Причем и для CSS анимации эта фишка также работает!

Используя магию дробных пикселей, я в очередной раз скорректировал код своего варианта игры Breakout. Вот ссылка - Breakout_v2.0! Можно поиграть и посмотреть код через консоль (клавиша F12 в Google Chrome). Управлять можно при помощи тач на смартфонах или мышкой на PC. Клик или тап во время игры - пауза. Клик по заголовку - переход в FullScreen.

Jake Archibald на конференции JS Conf объясняет event loop. Источник YouTube
Jake Archibald на конференции JS Conf объясняет event loop. Источник YouTube

Да, есть ещё классная лекция по теме window.requestAnimationFrame() и event loop, которая помогла мне глубже понять, что происходит под капотом JavaScript в этом контексте. Вот ссылка, это переведенное на русский язык видео с конференции JS Conf. Читает Jake Archibald, судя по всему крутой мужик :)