replay() - перезапуск

Метод replay() в библиотеке mo.js используется для полного перезапуска анимации независимо от её текущего состояния. В отличие от play(), который продолжает воспроизведение с текущего момента или запускает анимацию только если она остановлена, replay() всегда сбрасывает прогресс к началу и запускает заново.


Общий принцип работы

При вызове replay() происходит:

  • сброс текущего времени анимации (progress = 0)
  • очистка внутренних состояний (например, текущих значений трансформаций)
  • повторная инициализация всех tween-параметров
  • запуск анимации с самого начала

Это особенно важно для интерактивных интерфейсов, где требуется гарантированно одинаковое поведение при каждом запуске.


Базовый синтаксис

animation.replay();

Где animation — любой объект mo.js, поддерживающий анимацию:

  • mojs.Tween
  • mojs.Html
  • mojs.Shape
  • mojs.ShapeSwirl
  • mojs.Burst
  • mojs.Timeline

Пример с mojs.Shape

const circle = new mojs.Shape({
  shape: 'circle',
  radius: { 0: 50 },
  duration: 1000,
  fill: 'cyan'
});

// первый запуск
circle.play();

// повторный запуск через 2 секунды
setTimeout(() => {
  circle.replay();
}, 2000);

В этом примере:

  • play() запускает анимацию один раз
  • replay() через 2 секунды полностью её перезапускает, игнорируя текущее состояние

Отличие replay() от play()

Метод Поведение
play() Запускает анимацию с текущей позиции
replay() Всегда начинает с нуля

Иллюстрация поведения:

tween.play();   // запускает
tween.play();   // ничего не меняет, если уже играет

tween.replay(); // сбрасывает и запускает заново

Применение в пользовательских взаимодействиях

Повтор анимации по клику

const burst = new mojs.Burst({
  radius: { 0: 100 },
  count: 10,
  duration: 800
});

document.addEventListener('click', () => {
  burst.replay();
});

Каждый клик вызывает полный перезапуск анимации, даже если предыдущая ещё не завершилась.


Использование с Timeline

Метод replay() особенно полезен при работе с временными шкалами (Timeline), где объединено несколько анимаций.

const timeline = new mojs.Timeline();

timeline.add(circle, burst);

// первый запуск
timeline.play();

// повторный запуск
timeline.replay();

При вызове replay():

  • сбрасываются все дочерние анимации
  • синхронизация сохраняется
  • последовательность воспроизводится заново

Поведение при незавершённой анимации

Если replay() вызывается во время выполнения:

  • текущая анимация мгновенно прерывается
  • состояние откатывается к началу
  • начинается новый цикл

Это делает replay() безопасным способом принудительного обновления визуального эффекта.


Комбинирование с другими методами

replay() + pause()

animation.pause();
animation.replay();

Даже после паузы replay() гарантированно запустит анимацию заново.

replay() + setProgress()

animation.setProgress(0.5);
animation.replay();

Установка прогресса игнорируется — replay() всегда сбрасывает его.


Особенности работы с easing и delay

  • delay применяется заново при каждом replay()
  • easing пересчитывается с начальной точки
  • все динамические значения ({ from: to }) переинициализируются

Влияние на циклические анимации

Если анимация настроена с repeat:

const tween = new mojs.Tween({
  duration: 500,
  repeat: 3
});

Вызов replay():

  • обнуляет текущий цикл
  • запускает повторения заново

Практические сценарии использования

1. Кнопки с анимацией при каждом нажатии

button.addEventListener('click', () => {
  animation.replay();
});

2. Перезапуск анимации при повторном показе элемента

modal.onOpen(() => {
  animation.replay();
});

3. Сброс состояния интерфейса

function resetUI() {
  timeline.replay();
}

Производительность и нюансы

  • replay() не создаёт новый объект — используется тот же экземпляр
  • перерасчёт параметров происходит быстро, без лишних аллокаций
  • частый вызов допустим, но при сложных сценах (например, Burst с большим количеством элементов) может влиять на FPS

Отличие от ручного сброса

Альтернатива:

animation.setProgress(0);
animation.play();

Однако:

  • setProgress(0) не всегда корректно сбрасывает внутренние состояния
  • replay() гарантирует полный и чистый перезапуск

Поведение в цепочках анимаций

При использовании chained-анимаций:

animation.then({
  duration: 500
});

replay():

  • сбрасывает всю цепочку
  • повторно проигрывает её полностью

Резюме ключевых свойств

  • принудительный перезапуск с нуля
  • игнорирование текущего состояния
  • корректная работа с Timeline и вложенными анимациями
  • безопасное использование в интерактивных сценариях
  • предпочтительный способ повторного запуска вместо play()