Stagger - каскадные значения

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

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

В простейшем виде каскад формируется через числовой шаг:

x: 'stagger(10)'

Каждый следующий элемент получает значение, увеличенное на фиксированный шаг. Если первый объект имеет x = 0, второй получит x = 10, третий x = 20 и так далее.

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

Индексная зависимость значений

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

  • базовое значение
  • шаг изменения
  • функция распределения

Линейная модель:

value(i) = start + i * step

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

Использование в конфигурации mo.js

В структуре объекта анимации Stagger применяется непосредственно к свойствам tween-объекта:

const timeline = new mojs.Timeline();

const burst = new mojs.Burst({
  radius:   { 0: 100 },
  count: 10,
  children: {
    shape: 'circle',
    fill: 'white',
    x: 'stagger(15)',
    delay: 'stagger(50)'
  }
});

timeline.add(burst);
timeline.play();

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

Распределение по сетке

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

  • строка
  • столбец
  • центр
  • диагональ

Пример каскада по сетке:

x: 'stagger(20, { grid: [5, 5], from: 'center' })'

В этом случае значение определяется положением элемента в сетке 5×5. Центр становится точкой отсчёта, а значения расходятся симметрично в разные стороны.

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

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

Параметр направления определяет порядок, в котором применяется каскад. Возможные варианты:

  • от начала к концу
  • от конца к началу
  • от центра наружу
  • случайное распределение

Логика направления влияет на восприятие движения. Например, при анимации появления интерфейсных элементов можно задать последовательность слева направо:

opacity: 'stagger(1, { direction: 1 })'

Обратное направление создаёт эффект сворачивания или исчезновения.

Смещение относительно базового значения

Stagger не заменяет базовое значение параметра, а модифицирует его. Это позволяет комбинировать фиксированные и динамические компоненты:

y: 50 + 'stagger(5)'

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

Функциональная форма Stagger

Помимо строковой записи, Stagger может задаваться как функция, возвращающая вычисляемое значение:

x: function (i) {
  return i * 12;
}

Такая форма даёт полный контроль над логикой распределения. В отличие от декларативной записи, функциональный вариант позволяет внедрять условные конструкции, математические преобразования и зависимости от внешнего состояния.

Нелинейные распределения

Линейный шаг является базовым случаем. Более сложные эффекты достигаются через нелинейные функции:

  • квадратичное увеличение
  • экспоненциальный рост
  • синусоидальные колебания

Пример ускоряющегося каскада:

scale: 'stagger(1, { modifier: function (v, i) {
  return v * v;
}})'

В этом случае элементы увеличиваются неравномерно, создавая эффект ускорения или нарастания интенсивности.

Применение в анимации появления

Stagger активно используется для построения последовательных появлений элементов интерфейса. Типичный сценарий включает комбинацию opacity и transform:

children: {
  opacity: 'stagger(1)',
  y: 'stagger(20)',
  delay: 'stagger(40)'
}

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

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

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

Stagger может применяться одновременно к нескольким параметрам, создавая согласованные траектории движения:

children: {
  x: 'stagger(10)',
  y: 'stagger(10)',
  rotate: 'stagger(15)'
}

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

Контроль плотности каскада

Изменение шага напрямую влияет на визуальную плотность эффекта:

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

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

Использование с Burst-эффектами

В Burst-анимациях Stagger становится ключевым инструментом формирования сложных разлётов:

new mojs.Burst({
  count: 12,
  radius: { 0: 120 },
  children: {
    shape: 'rect',
    x: 'stagger(8)',
    delay: 'stagger(30)',
    duration: 600
  }
});

Здесь создаётся эффект расширяющегося облака, в котором элементы не просто расходятся, а делают это с контролируемым смещением.

Комбинирование с easing

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

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

Влияние индекса на визуальную иерархию

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

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