Переключение между состояниями

В библиотеке mo.js поведение анимаций строится вокруг управления состояниями объектов: запуск, остановка, перемотка, повтор, а также переходы между визуально и логически различимыми режимами. Состояние анимации в данном контексте представляет собой комбинацию параметров времени, прогресса и активного набора свойств, определяющих текущее отображение объекта.

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


Базовая модель состояния в mo.js

Анимационные сущности mo.js опираются на временную ось, где текущее состояние определяется прогрессом:

  • 0 — начальное состояние
  • 1 — завершённое состояние
  • промежуточные значения — текущая фаза анимации

Каждый tween фактически интерполирует свойства между from и to значениями. Это создаёт непрерывный переход, который может быть переопределён в любой момент времени.

const tween = new mojs.Tween({
  duration: 1000,
  onUpdate(progress) {
    console.log(progress);
  }
});

Изменение состояния в mo.js не требует пересоздания объекта — достаточно управлять его временной шкалой.


Переключение между запуском и остановкой

Состояние активности анимации определяется методами управления исполнением:

  • play() — запуск с текущей позиции
  • pause() — остановка на текущем кадре
  • replay() — возврат к началу с последующим запуском
  • stop() — остановка и сброс состояния
const circle = new mojs.Shape({
  shape: 'circle',
  radius: 30,
  duration: 800
});

circle.play();
circle.pause();
circle.replay();

Смена состояния не уничтожает объект, а лишь изменяет его временной указатель и внутренний флаг активности.


Управление направлением состояния

Переходы между состояниями часто требуют изменения направления анимации. В mo.js поддерживается инверсия временной шкалы через reverse-подобное поведение.

const tween = new mojs.Tween({
  duration: 1000
});

tween.play();
tween.setDirection(-1);
tween.play();

Изменение направления позволяет реализовать двусторонние состояния, такие как:

  • открыто / закрыто
  • активировано / деактивировано
  • показано / скрыто

Использование yoyo как механизма возврата состояния

Режим yoyo обеспечивает автоматическое переключение состояния по завершении цикла анимации. Это создаёт циклическое движение между двумя крайними состояниями без необходимости ручного управления направлением.

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

Механизм yoyo фактически формирует замкнутую систему состояний:

  • прямое выполнение
  • обратное выполнение
  • повтор цикла

Прогрессивное управление состоянием через setProgress

Одним из ключевых инструментов точного переключения состояний является управление прогрессом вручную.

tween.setProgress(0.5);

Такой подход позволяет:

  • фиксировать анимацию в промежуточном состоянии
  • синхронизировать несколько независимых анимаций
  • строить пользовательские контроллеры состояния

В UI-паттернах это используется для привязки анимации к состоянию интерфейса, а не ко времени.


Состояния через события жизненного цикла

mo.js предоставляет события, которые позволяют отслеживать переходы между состояниями:

  • onStart
  • onUpdate
  • onComplete
  • onRefresh
const tween = new mojs.Tween({
  duration: 1000,
  onStart() {
    console.log('start state');
  },
  onComplete() {
    console.log('end state');
  }
});

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


Переключение UI-состояний через анимации

Часто анимации mo.js выступают визуальным отражением логических состояний интерфейса. Типичный пример — переключение кнопки между состояниями «включено» и «выключено».

let isActive = false;

const activeAnimation = new mojs.Shape({
  shape: 'circle',
  radius: { 0: 40 },
  opacity: { 1: 0 },
  duration: 400
});

function toggle() {
  isActive = !isActive;

  if (isActive) {
    activeAnimation.replay();
  } else {
    activeAnimation.stop();
  }
}

Здесь состояние интерфейса отделено от состояния анимации, но синхронизируется через явные вызовы управления временем.


Композиция состояний в Timeline

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

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

const timeline = new mojs.Timeline({
  children: [burst]
});

timeline.play();

Переключение состояния timeline приводит к синхронному изменению состояния всех дочерних объектов.


Динамическое переключение состояния через обновление параметров

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

const shape = new mojs.Shape({
  shape: 'rect',
  radius: 20,
  duration: 800
});

shape.play();

shape.tune({
  radius: 50
});

Механизм tune позволяет трансформировать текущее поведение объекта, фактически создавая гибридное состояние между старой и новой конфигурацией.


Синхронизация нескольких состояний

При работе с группами анимаций возникает необходимость синхронизации переходов между состояниями нескольких объектов. Для этого используются:

  • единый timeline
  • общие триггеры событий
  • согласованное управление прогрессом
const a = new mojs.Shape({ radius: { 0: 30 }, duration: 500 });
const b = new mojs.Shape({ radius: { 0: 60 }, duration: 500 });

const timeline = new mojs.Timeline({
  children: [a, b]
});

timeline.play();

Состояние timeline становится управляющим уровнем, определяющим состояние всех вложенных элементов.


Инверсия состояния и возврат к исходной точке

Состояния часто требуют возврата к начальному виду без пересоздания объекта. Для этого используются комбинации reset-подобного поведения и управления прогрессом.

tween.pause();
tween.setProgress(0);

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


Модель конечных состояний анимации

При проектировании сложных интерфейсов анимации mo.js часто рассматриваются как конечный автомат:

  • состояние A → состояние B через tween
  • состояние B → состояние A через reverse
  • промежуточные состояния через progress

Каждое состояние определяется:

  • положением на временной оси
  • направлением воспроизведения
  • набором активных свойств объекта

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


Управление конфликтами состояний

При параллельных анимациях может возникать конфликт состояний, когда несколько tween пытаются управлять одними и теми же свойствами. Решение заключается в разделении ответственности:

  • один tween — одно логическое состояние
  • timeline — координация групп состояний
  • события — синхронизация переходов

Это предотвращает неконтролируемое наложение визуальных эффектов и обеспечивает стабильность переходов.


Состояния как реакция на внешние события

Часто переключение состояний инициируется внешними триггерами: кликами, загрузкой данных, изменением DOM-состояния. В таких сценариях mo.js выступает как слой визуализации над логикой приложения.

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

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