CancelAnimationFrame: примеры (JAVASCRIPT)

Руководство по cancelAnimationFrame с практическими примерами
Раздел: Анимация, Управление
cancelAnimationFrame(id: number): undefined

Основные сведения о cancelAnimationFrame

Метод cancelAnimationFrame() отменяет анимацию, запланированную с помощью requestAnimationFrame(). Он является частью JavaScript API для управления анимацией и позволяет останавливать выполнение анимационных кадров.

Использование функции целесообразно при необходимости прервать анимацию, например, когда элемент скрывается, страница становится неактивной или требуется остановить игровой цикл.

Функция принимает один обязательный аргумент:

  • requestID - числовой идентификатор, возвращенный ранее вызовом requestAnimationFrame(). Этот идентификатор указывает, какой конкретный запрос анимации должен быть отменен.

Метод не возвращает значения (undefined). Его единственная задача - остановить выполнение анимации, связанной с переданным идентификатором.

Простые примеры использования

Базовый пример запуска и отмены анимации:

let requestId;
let startTime = null;

function animate(timestamp) {
  if (!startTime) startTime = timestamp;
  const progress = timestamp - startTime;
  
  // Анимация элемента
  document.getElementById('box').style.transform = 
    `translateX(${Math.min(progress / 10, 200)}px)`;
  
  if (progress < 2000) {
    requestId = requestAnimationFrame(animate);
  }
}

// Запуск анимации
requestId = requestAnimationFrame(animate);

// Отмена через 1 секунду
setTimeout(() => {
  cancelAnimationFrame(requestId);
  console.log('Анимация отменена');
}, 1000);
// Через 1 секунду в консоли появится:
// Анимация отменена

Альтернативные методы управления анимацией в JavaScript

clearTimeout() / clearInterval() - отменяют выполнение функций, установленных через setTimeout() и setInterval(). Подходят для простых временных интервалов, но менее эффективны для анимации, связанной с отрисовкой.

CSS-анимации и transition - управление через CSS свойства. Отмена происходит через изменение классов или установку animation-play-state: paused. Более производительны для простых трансформаций.

Web Animations API - современный API с методами cancel() и pause() для объектов Animation. Предоставляет больше контроля над анимацией.

Аналоги в других языках программирования

Python (Pygame): Используется метод pygame.time.Clock() для контроля частоты кадров, явной отмены нет.

import pygame
pygame.init()
clock = pygame.time.Clock()
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False  # Остановка цикла
    clock.tick(60)  # Ограничение 60 FPS

C# (Unity): Остановка через отмену вызова метода в Update() или использование CancelInvoke().

using UnityEngine;
public class Example : MonoBehaviour {
    void Start() {
        InvokeRepeating("Animate", 0f, 0.016f);
    }
    void StopAnimation() {
        CancelInvoke("Animate");
    }
}

Распространенные ошибки

1. Отмена несуществующего или уже выполненного ID

// Ошибка: отмена неправильного ID
const wrongId = 999999;
cancelAnimationFrame(wrongId); // Ничего не происходит, ошибки нет

// Ошибка: повторная отмена того же ID
const id = requestAnimationFrame(() => {});
cancelAnimationFrame(id);
cancelAnimationFrame(id); // Второй вызов не имеет эффекта

2. Использование значения null или undefined

let requestId;
// Пропущен вызов requestAnimationFrame
cancelAnimationFrame(requestId); // Без ошибки, но бесполезно

Изменения в спецификации

Функция cancelAnimationFrame() была стандартизирована в рамках W3C Timing Control for Script-Based Animations. Современные браузеры реализуют её без существенных отличий от первоначальной спецификации.

Важное уточнение: в ранних префиксных реализациях (webkitCancelAnimationFrame, mozCancelAnimationFrame) требовалась проверка наличия методов. Сейчас поддержка унифицирована.

Расширенные примеры применения

Управление несколькими анимациями

Пример javascript
class AnimationManager {
  constructor() {
    this.animations = new Map();
  }
  
  addAnimation(key, callback) {
    const animate = (timestamp) => {
      if (!this.animations.has(key)) return;
      callback(timestamp);
      const id = requestAnimationFrame(animate);
      this.animations.set(key, id);
    };
    const id = requestAnimationFrame(animate);
    this.animations.set(key, id);
  }
  
  cancelAnimation(key) {
    if (this.animations.has(key)) {
      cancelAnimationFrame(this.animations.get(key));
      this.animations.delete(key);
    }
  }
}

// Использование
const manager = new AnimationManager();
manager.addAnimation('move', (time) => {
  console.log('Движение:', time);
});

// Отмена конкретной анимации
manager.cancelAnimation('move');

Интеграция с событиями прокрутки

Пример javascript
let scrollAnimationId = null;

window.addEventListener('scroll', () => {
  // Отмена предыдущей анимации при быстрой прокрутке
  if (scrollAnimationId !== null) {
    cancelAnimationFrame(scrollAnimationId);
  }
  
  // Запуск новой анимации
  scrollAnimationId = requestAnimationFrame(() => {
    const scrolled = window.pageYOffset;
    document.querySelector('.parallax').style.transform = 
      `translateY(${scrolled * 0.5}px)`;
    scrollAnimationId = null;
  });
});

JS cancelAnimationFrame function comments

En
CancelAnimationFrame Cancels an animation frame request previously scheduled with requestAnimationFrame.