Stagger для delay

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

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


Базовое использование stagger для delay

В mo.js stagger реализуется через функцию mojs.stagger(). Она возвращает значение, которое изменяется для каждого элемента в последовательности.

Пример:

const circles = new mojs.Shape({
  shape: 'circle',
  count: 5,
  delay: mojs.stagger(100)
});

Что происходит:

  • count: 5 создаёт 5 элементов

  • mojs.stagger(100) задаёт задержку:

    • 1-й элемент: 0 мс
    • 2-й: 100 мс
    • 3-й: 200 мс
    • и так далее

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


Формат функции stagger

Сигнатура:

mojs.stagger(step, options)

Параметры:

  • step — базовый шаг задержки между элементами (в миллисекундах)
  • options — объект с дополнительными настройками

Настройки stagger

1. start

Позволяет задать начальную задержку:

delay: mojs.stagger(100, { start: 200 })

Результат:

  • 1-й элемент: 200 мс
  • 2-й: 300 мс
  • 3-й: 400 мс

2. from

Определяет, откуда начинается расчёт последовательности:

delay: mojs.stagger(100, { from: 'center' })

Варианты:

  • 'start' — по умолчанию (с начала)
  • 'end' — с конца
  • 'center' — от центра к краям
  • конкретный индекс (например, 2)

Пример с center:

При count: 5:

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

3. direction

Изменяет направление расчёта:

delay: mojs.stagger(100, { direction: -1 })

Результат:

  • последовательность инвертируется

4. easing

Позволяет применять функцию сглаживания к распределению задержек:

delay: mojs.stagger(100, { easing: 'cubic.out' })

Это влияет не на саму анимацию, а на распределение задержек:

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

5. grid

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

delay: mojs.stagger(100, { grid: [3, 3], from: 'center' })

Особенности:

  • элементы рассматриваются как матрица
  • порядок расчёта задержек зависит от положения в сетке

Пример с Burst

stagger часто применяется в Burst для создания динамических эффектов:

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

Эффект:

  • частицы “взрываются” не одновременно
  • создаётся ощущение движения волны

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

stagger можно использовать не только для delay, но и для других параметров:

const shapes = new mojs.Shape({
  count: 5,
  delay: mojs.stagger(100),
  x: mojs.stagger(20),
  scale: mojs.stagger([1, 0.5])
});

Результат:

  • каждый элемент имеет уникальные:

    • задержку
    • позицию
    • масштаб

Массивы значений в stagger

Можно задавать диапазон:

delay: mojs.stagger([0, 500])

mo.js автоматически распределяет значения между элементами.

Пример:

  • 5 элементов → значения между 0 и 500 мс
  • равномерное распределение

Нелинейные последовательности

С помощью easing и диапазонов можно создавать сложные временные структуры:

delay: mojs.stagger([0, 1000], {
  easing: 'quad.inout'
})

Поведение:

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

Практическое применение

1. Анимация списков

items.forEach((el, i) => {
  new mojs.Html({
    el: el,
    delay: mojs.stagger(100)(i)
  }).play();
});

Позволяет создать эффект “появления по очереди”.


2. Волновые эффекты

delay: mojs.stagger(100, {
  from: 'center'
})

Используется для:

  • кнопок
  • карточек
  • элементов меню

3. Частицы и эффекты взрыва

delay: mojs.stagger(30)

Создаёт:

  • естественную хаотичность
  • ощущение физической динамики

Важные особенности

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

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

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

  • практически не влияет на производительность
  • не создаёт дополнительных таймеров
  • интегрируется в общий таймлайн mo.js

Однако при большом количестве элементов (100+) рекомендуется:

  • уменьшать шаг (step)
  • избегать сложных easing для delay

Расширенные паттерны

1. Пользовательская функция

stagger можно комбинировать с функциями:

delay: mojs.stagger(100, {
  start: 200,
  easing: (p) => Math.sin(p * Math.PI)
})

2. Вложенные stagger

const timeline = new mojs.Timeline();

timeline.add([
  new mojs.Burst({
    delay: mojs.stagger(100)
  }),
  new mojs.Burst({
    delay: mojs.stagger(200, { start: 500 })
  })
]);

Позволяет строить сложные временные композиции.


Типичные ошибки

Непонимание возвращаемого значения

delay: mojs.stagger(100)

Это не число, а функция-генератор. Она корректно работает только внутри mo.js.


Отсутствие count

Без count stagger не имеет смысла:

new mojs.Shape({
  delay: mojs.stagger(100) // не будет работать как ожидается
});

Слишком большой step

delay: mojs.stagger(1000)

Может привести к:

  • излишне затянутой анимации
  • потере визуальной связности

Визуальное восприятие stagger

Правильно настроенный stagger:

  • усиливает ощущение движения
  • делает анимацию более “живой”
  • создаёт ритм и структуру

Неправильный:

  • разрушает синхронность
  • делает интерфейс медленным
  • отвлекает от основного действия

Связь с таймлайнами

stagger особенно эффективен в связке с Timeline:

const timeline = new mojs.Timeline();

const anim = new mojs.Shape({
  count: 5,
  delay: mojs.stagger(100)
});

timeline.add(anim);
timeline.play();

Позволяет:

  • управлять всей последовательностью
  • комбинировать разные stagger-группы
  • синхронизировать сложные анимации

Итоговая роль stagger

stagger для delay — ключевой инструмент для:

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

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