RequestAnimationFrame: примеры (JAVASCRIPT)
requestAnimationFrame(callback: function): number (id for cancellation)Основные сведения о requestAnimationFrame
Функция requestAnimationFrame является частью JavaScript API и предназначена для создания плавной анимации в браузере. Она сообщает браузеру о необходимости выполнить анимацию и запрашивает вызов указанной функции перед следующей перерисовкой страницы.
Основное применение функции — создание анимации, которая синхронизирована с частотой обновления экрана устройства. Это позволяет добиться оптимальной производительности и избежать лишних вычислений, когда страница неактивна или скрыта.
Аргументы функции:
- callback — единственный обязательный параметр. Это функция, которая будет вызвана перед следующей перерисовкой. Она получает один аргумент —
DOMHighResTimeStamp, указывающий время, когда запланирован вызов callback.
Возвращаемое значение — числовой идентификатор запроса, который можно передать в cancelAnimationFrame для отмены вызова.
Примеры базового использования
Простейший пример анимации движения элемента.
let start;
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
element.style.transform = `translateX(${Math.min(progress / 10, 200)}px)`;
if (progress < 2000) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);Пример использования с отменой анимации.
let animationId;
function animate() {
// Логика анимации
animationId = requestAnimationFrame(animate);
}
animationId = requestAnimationFrame(animate);
// Для остановки:
// cancelAnimationFrame(animationId);Похожие функции в JavaScript
setInterval и setTimeout — традиционные методы для периодического выполнения кода. Они не привязаны к циклу отрисовки браузера, что может вызвать пропуск кадров или излишние вычисления. Предпочтительнее использовать requestAnimationFrame для визуальных анимаций.
Intersection Observer API — позволяет асинхронно отслеживать видимость элементов. Используется для ленивой загрузки или запуска анимации при появлении элемента в viewport. Для анимации движения лучше подходит requestAnimationFrame.
Типичные ошибки
Рекурсивный вызов без условия остановки приводит к бесконечной анимации и нагрузке на процессор.
function animate() {
// Изменение состояния
requestAnimationFrame(animate); // Вызывается всегда
}
animate(); // Нельзя остановитьИгнорирование временной метки вызывает анимацию, зависящую от скорости выполнения, а не от реального времени.
let position = 0;
function animate() {
position += 5; // Скорость зависит от частоты кадров
element.style.left = position + 'px';
requestAnimationFrame(animate);
}Изменения в последних версиях
Функция requestAnimationFrame была стандартизирована в спецификации HTML5. Современные браузеры поддерживают высокоточную временную метку DOMHighResTimeStamp. В более старых реализациях метка времени могла быть с меньшей точностью.
В последних версиях браузеров функция оптимизирована для работы в фоновых вкладках — частота вызовов снижается для экономии ресурсов. Это поведение определено в спецификации Page Visibility API.
Расширенные примеры использования
Анимация с линейной интерполяцией по времени.
const duration = 2000; // 2 секунды
const startPosition = 0;
const endPosition = 300;
let startTime;
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1);
const currentPosition = startPosition + (endPosition - startPosition) * progress;
element.style.transform = `translateX(${currentPosition}px)`;
if (progress < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);Использование для контроля частоты кадров в игровом цикле.
let lastTime = 0;
const fps = 30;
const frameInterval = 1000 / fps;
function gameLoop(timestamp) {
if (timestamp - lastTime >= frameInterval) {
// Логика игры
lastTime = timestamp;
}
requestAnimationFrame(gameLoop);
}
gameLoop();Создание плавного скролла с использованием requestAnimationFrame.
function smoothScrollTo(targetY, duration = 1000) {
const startY = window.scrollY;
const distance = targetY - startY;
let startTime;
function scrollStep(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1);
const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
window.scrollTo(0, startY + distance * ease);
if (progress < 1) {
requestAnimationFrame(scrollStep);
}
}
requestAnimationFrame(scrollStep);
}Аналоги в других языках программирования
В Python для создания анимаций в библиотеке PyGame используется основной игровой цикл с контролем FPS.
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Логика анимации
pygame.display.flip()
clock.tick(60) # Ограничение до 60 кадров в секундуВ C/C++ для графических приложений используются специализированные API (OpenGL, DirectX) и циклы сообщений. Концепция запроса следующего кадра отсутствует, так как управление происходит через системные события.
JS requestAnimationFrame function comments
- Js requestAnimationFrame - аргументы и возвращаемое значение
- Функция javascript requestAnimationFrame - описание
- requestAnimationFrame - примеры
- requestAnimationFrame - похожие методы на javascript
- requestAnimationFrame на php, python, mysql
- requestAnimationFrame изменения javascript
- Примеры requestAnimationFrame на js