Управление жизненным циклом

Жизненный цикл анимаций в mo.js определяется последовательностью состояний объекта, начиная от инициализации и заканчивая завершением воспроизведения или его повторными циклами. Библиотека строит управление анимациями вокруг сущностей Tween, Timeline, Shape, Burst, каждая из которых имеет единый механизм перехода между состояниями и набор управляющих методов.

Создание анимации в mo.js начинается с конфигурации параметров объекта. На этом этапе задаются:

  • начальные и конечные значения свойств
  • длительность (duration)
  • задержка (delay)
  • тип easing-функции
  • параметры повторения и направления

Инициализация не запускает анимацию автоматически. Объект находится в состоянии готовности, где внутренние структуры уже рассчитаны, но временная шкала ещё не активирована.

const tween = new mojs.Tween({
  duration: 2000,
  delay: 300,
  onStart: () => console.log('start'),
  onUpdate: (progress) => console.log(progress),
  onComplete: () => console.log('complete')
});

На этом этапе создаётся внутренняя модель анимации, включающая вычисленные кривые интерполяции и временные сегменты.

Состояние ожидания и задержка

Перед стартом анимации учитывается параметр delay. В течение этого периода объект остаётся в состоянии ожидания, не изменяя целевые значения и не вызывая событий обновления.

Задержка входит в общий временной континуум анимации, но не влияет на прогресс напрямую. Внутренне она увеличивает начальную точку отсчёта времени.

Запуск анимации

Анимация переходит в активное состояние при вызове метода play(). В этот момент фиксируется стартовое время и начинается отсчёт прогресса.

tween.play();

При запуске выполняется:

  • фиксация начального timestamp
  • активация update-цикла
  • вызов onStart
  • переход в состояние воспроизведения

Внутренний механизм использует requestAnimationFrame для синхронизации с частотой обновления экрана.

Обновление состояния

Ключевой фазой жизненного цикла является обновление (update). На каждом кадре вычисляется текущий прогресс анимации в диапазоне от 0 до 1 с учётом задержки, длительности и easing-функции.

Формула вычисления прогресса:

progress = (currentTime - startTime) / duration

После нормализации применяется easing-функция, преобразующая линейный прогресс в нелинейную кривую.

В этот момент вызывается callback onUpdate, позволяющий синхронизировать внешние эффекты с состоянием анимации.

Завершение анимации

При достижении прогресса значения 1 анимация переходит в состояние завершения. Выполняются следующие операции:

  • фиксация финального состояния свойств
  • вызов onComplete
  • остановка update-цикла (если нет repeat)

Завершение может быть как конечным, так и промежуточным в случае повторов.

Повтор и цикличность

mo.js поддерживает управление повторением через параметр repeat. При установленном значении больше 0 жизненный цикл расширяется, добавляя дополнительные итерации.

При каждом цикле:

  • прогресс сбрасывается в 0
  • состояние пересчитывается
  • снова вызывается onStart

Дополнительно может применяться параметр yoyo, изменяющий направление анимации при каждом повторе.

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

В этом режиме жизненный цикл становится петлевым, а обновления чередуют прямое и обратное движение.

Управление воспроизведением

Состояние анимации может изменяться в любой момент через набор управляющих методов:

  • play() — запуск или продолжение
  • pause() — приостановка
  • replay() — перезапуск с начала
  • reset() — возврат к исходному состоянию
  • stop() — остановка с фиксацией текущего состояния

При паузе сохраняется текущий timestamp, позволяя корректно продолжить вычисление прогресса без сдвига временной оси.

Внутреннее состояние объекта

Каждый анимационный объект содержит набор флагов состояния:

  • isPlaying
  • isPaused
  • isCompleted

Эти флаги определяют поведение update-цикла и реакцию на вызовы методов управления. Например, при isPaused обновление прогресса прекращается, но вычисленные значения сохраняются.

Timeline и композиция жизненных циклов

Timeline объединяет несколько анимаций в единый синхронизированный жизненный цикл. В этом случае управление временем становится централизованным.

const timeline = new mojs.Timeline();

timeline.add(tween1, tween2, tween3);
timeline.play();

В timeline жизненные циклы дочерних анимаций подчиняются общей временной шкале:

  • старт всех элементов синхронизирован
  • задержки суммируются относительно общего времени
  • завершение определяется последним активным tween

Событийная модель

Жизненный цикл расширяется через систему событий, привязанную к ключевым точкам:

  • start
  • update
  • complete
  • refresh

Каждое событие вызывается строго в момент перехода состояния.

new mojs.Tween({
  onStart: () => {},
  onUpdate: () => {},
  onComplete: () => {}
});

События не блокируют выполнение цикла и не влияют на расчёт прогресса, выполняясь асинхронно в рамках текущего кадра.

Промежуточные состояния и пересчёт

При изменении параметров анимации во время выполнения жизненный цикл может быть пересчитан. Это включает:

  • перерасчёт duration
  • изменение easing-кривой
  • смещение временной точки старта

Такая динамическая модификация приводит к частичному перезапуску внутреннего состояния без полного сброса объекта.

Управление памятью и уничтожение

После завершения или остановки анимации объект может быть удалён из памяти через разрыв ссылок и очистку внутренних подписок на requestAnimationFrame.

mo.js не выполняет автоматическую финализацию, поэтому жизненный цикл объекта фактически завершается на уровне внешнего управления, когда отсутствуют активные ссылки на экземпляр анимации или timeline.