Управление дочерними фигурами

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

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


Burst как контейнер дочерних фигур

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

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

Ключевые особенности Burst:

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

Пример базовой структуры:

const burst = new mojs.Burst({
  radius: { 0: 100 },
  count: 10,
  children: {
    shape: 'circle',
    fill: 'white',
    duration: 1000
  }
});

Здесь children описывает конфигурацию дочерних фигур, которая применяется ко всем элементам массива.


Конфигурация children

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

Поддерживаются любые параметры Shape, включая:

  • shape
  • radius
  • fill и stroke
  • strokeWidth
  • duration
  • delay
  • easing

Особенность заключается в том, что значения могут быть как фиксированными, так и интерполируемыми.

Пример динамической конфигурации:

children: {
  shape: 'rect',
  radius: { 5: 20 },
  fill: 'cyan',
  duration: 800,
  delay: 'stagger(50)'
}

Функция stagger() автоматически распределяет задержку между дочерними элементами, создавая эффект последовательного запуска анимации.


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

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

Индекс применяется в следующих сценариях:

  • смещение задержки (delay)
  • изменение масштаба (scale)
  • поворот (angle)
  • радиальное распределение

Механизм распределения основан на формуле нормализации индекса:

  • i — индекс элемента
  • n — общее количество детей

На основе этого вычисляются интерполяции параметров:

  • линейные
  • экспоненциальные
  • синусоидальные

Например, постепенное уменьшение размера:

children: {
  radius: (i, t, total) => 10 + (total - i) * 2
}

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

Дочерние фигуры в mo.js наследуют часть параметров от родительского объекта Burst, если они явно не переопределены.

Наследуются:

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

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

Это позволяет:

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

Пространственное распределение дочерних фигур

Burst использует полярную систему координат для размещения детей. Каждая фигура получает угол и радиус относительно центра родителя.

Основные режимы распределения:

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

Параметр radius в Burst определяет диапазон разлёта:

radius: { 0: 120 }

Это означает анимацию от центра к внешнему радиусу.


Анимация дочерних элементов

Каждая дочерняя фигура в Burst является полноценной анимационной единицей со своим жизненным циклом.

Основные стадии:

  1. инициализация параметров
  2. вычисление позиции относительно родителя
  3. запуск анимации свойств
  4. завершение и удаление из DOM

Свойства анимации могут быть синхронизированы или независимы:

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

Пример каскадной анимации:

children: {
  delay: 'stagger(100)',
  duration: 600,
  y: { 0: -80 }
}

Синхронизация через Timeline

При необходимости управления несколькими группами дочерних фигур используется mojs.Timeline. Он позволяет объединять несколько Burst и Shape в единую временную ось.

В контексте дочерних фигур это особенно важно для:

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

Пример:

const burst1 = new mojs.Burst({ count: 5, children: { shape: 'circle' } });
const burst2 = new mojs.Burst({ count: 8, children: { shape: 'rect' } });

const timeline = new mojs.Timeline().add(burst1, burst2);
timeline.play();

Динамическое изменение дочерних элементов

mo.js позволяет изменять параметры дочерних фигур во время выполнения анимации через метод tune().

Это даёт возможность:

  • менять количество детей
  • обновлять форму и стиль
  • модифицировать траекторию
  • перестраивать Burst без пересоздания объекта

Пример динамического обновления:

burst.tune({
  count: 15,
  children: {
    fill: 'orange'
  }
}).replay();

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


Композиция вложенных Burst

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

Такая структура формирует:

  • первичный взрыв
  • вторичные разлеты
  • каскадные эффекты разрушения

Пример концепции:

const innerBurst = new mojs.Burst({
  count: 3,
  radius: { 0: 60 },
  children: { shape: 'circle' }
});

const outerBurst = new mojs.Burst({
  count: 5,
  radius: { 0: 120 },
  children: {
    shape: 'rect',
    onComplete() {
      innerBurst.replay();
    }
  }
});

Производительность при большом количестве детей

При увеличении числа дочерних фигур возникает нагрузка на DOM и GPU-композицию. mo.js использует оптимизации:

  • минимизация reflow через transform
  • использование requestAnimationFrame
  • переиспользование объектов конфигурации
  • ограничение перерисовки свойств

Рекомендации по структуре:

  • избегать чрезмерного количества Burst одновременно
  • использовать одинаковые children-конфигурации
  • минимизировать изменение layout-свойств (width, height, top, left)

Паттерны построения сложных эффектов

На практике управление дочерними фигурами применяется в нескольких устойчивых схемах:

Радиальный взрыв

  • равномерное распределение по окружности
  • увеличение радиуса во времени
  • уменьшение opacity к концу анимации

Каскад частиц

  • staggered delay
  • направленный разлёт
  • различие в масштабе через индекс

Многослойная структура

  • несколько Burst с разными радиусами
  • разные типы shapes
  • синхронизация через Timeline

Векторный поток

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

Абстракция управления группами

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

  • генератора конфигураций
  • координатора времени
  • распределителя параметров
  • контроллера жизненного цикла

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