Архитектура анимаций в библиотеке строится вокруг композиции объектов, где один анимационный элемент может содержать другие, наследовать их поведение и управлять их жизненным циклом. Дочерние элементы представляют собой вложенные анимации, связанные с родительским объектом через общие параметры времени, трансформаций и триггеров запуска.
Внутренняя модель позволяет рассматривать сложные эффекты как дерево анимаций, где корневой элемент управляет синхронизацией, а листья отвечают за визуальные детали.
Любой составной эффект формируется через объединение базовых сущностей:
Дочерние элементы появляются при вложении одного объекта в другой,
чаще всего внутри Timeline или Burst. При этом
каждый вложенный элемент может иметь собственный набор параметров, но
подчиняется общему контексту времени.
Ключевая особенность — отсутствие жёсткого наследования в классическом ООП-смысле. Вместо этого используется композиция и переопределение свойств на уровне конфигурации.
При создании дочерних объектов происходит частичное наследование параметров родителя. Наиболее значимые категории:
Если дочерний элемент явно не переопределяет значение, оно берётся из родительского контекста. Это создаёт предсказуемую систему каскадной настройки.
Пример базовой структуры:
const timeline = new mojs.Timeline();
const circle = new mojs.Shape({
parent: timeline.el,
shape: 'circle',
radius: { 0: 40 },
duration: 800
});
const square = new mojs.Shape({
parent: timeline.el,
shape: 'rect',
radius: { 0: 30 },
duration: 800
});
Здесь оба элемента связаны через общий контейнер временной шкалы, что делает их синхронизированными дочерними объектами.
Timeline является основным механизмом управления дочерними элементами. Он не только группирует анимации, но и обеспечивает их координацию по времени.
Основные свойства Timeline:
Каждый дочерний элемент внутри Timeline может иметь собственный offset, определяющий момент старта относительно родителя.
const tl = new mojs.Timeline();
const child1 = new mojs.Shape({
shape: 'circle',
radius: 20,
duration: 400
});
const child2 = new mojs.Shape({
shape: 'rect',
radius: 20,
duration: 400,
delay: 200
});
tl.add(child1, child2);
tl.play();
В этом случае второй элемент становится логическим продолжением первого, хотя оба принадлежат одному контейнеру.
Burst представляет собой специализированный контейнер для генерации множества дочерних элементов одновременно. Каждый элемент в Burst является автономной частицей, но создаётся на основе общей конфигурации.
Основные параметры управления дочерними элементами в Burst:
Каждая частица наследует базовые свойства, но может получать случайные вариации через функции или диапазоны значений.
const burst = new mojs.Burst({
radius: { 0: 100 },
count: 8,
children: {
shape: 'circle',
radius: 10,
fill: 'orange',
duration: 700
}
});
Здесь children задаёт шаблон, который применяется ко
всем создаваемым элементам.
Дочерние элементы могут модифицировать наследуемые свойства через явное переопределение. Приоритет всегда отдаётся локальной конфигурации.
Типичные сценарии:
const burst = new mojs.Burst({
radius: { 0: 120 },
count: 6,
children: {
shape: 'rect',
radius: { 5: 15 },
duration: { 600: 1200 },
delay: 'stagger(50)'
}
});
Функция stagger позволяет распределять параметры по
дочерним элементам, создавая эффект последовательного запуска.
Одним из ключевых механизмов является возможность передачи функций вместо статических значений. Это позволяет вычислять параметры для каждого дочернего элемента отдельно.
Функциональные параметры получают индекс элемента и общее количество:
const burst = new mojs.Burst({
count: 10,
children: {
radius: function (i, t) {
return 5 + i * 2;
},
fill: function (i) {
return i % 2 === 0 ? 'red' : 'blue';
}
}
});
Такая модель создаёт детерминированную вариативность без необходимости ручного создания каждого элемента.
Stagger — механизм автоматического распределения значений между дочерними элементами. Он применяется к числовым, цветовым и временным параметрам.
Основные сценарии использования:
const burst = new mojs.Burst({
count: 5,
children: {
delay: 'stagger(100)',
angle: 'stagger(0, 360)',
radius: 20
}
});
Каждый дочерний элемент получает уникальное значение, вычисляемое на основе позиции в массиве.
Дочерние элементы могут сами содержать вложенные анимации, формируя многоуровневые структуры. Это используется для создания сложных сценических эффектов.
Пример композиции:
Такая структура позволяет строить каскадные эффекты, где один визуальный элемент порождает следующий уровень анимации.
const innerShape = new mojs.Shape({
shape: 'circle',
radius: 10,
duration: 300
});
const burst = new mojs.Burst({
count: 4,
children: {
shape: 'circle',
radius: 20,
onStart: function () {
innerShape.play();
}
}
});
Здесь дочерние элементы управляют запуском вложенных анимаций.
Временная модель дочерних элементов основана на нескольких уровнях контроля:
Каждый уровень может влиять на скорость и момент старта анимации.
Основные параметры:
Комбинация этих параметров позволяет создавать сложные временные зависимости между элементами.
Дочерние элементы могут реагировать на жизненные события:
Эти события позволяют связывать поведение элементов между собой.
const shape = new mojs.Shape({
shape: 'circle',
radius: 30,
onStart: function () {
console.log('child started');
},
onComplete: function () {
console.log('child finished');
}
});
Событийная модель часто используется для каскадных эффектов, где завершение одного элемента запускает следующий.
Callback-функции позволяют изменять параметры дочерних элементов в процессе выполнения. Это создаёт динамическое поведение, зависящее от состояния анимации.
Основные точки вмешательства:
Через них можно изменять позицию, масштаб или цвет в реальном времени, создавая адаптивные эффекты.
При работе с большим количеством вложенных объектов важна синхронизация. Она достигается через:
Синхронизация позволяет избежать рассинхрона визуальных эффектов и обеспечивает целостность композиции.
Дочерние элементы могут создаваться во время выполнения анимации. Это используется для реактивных эффектов, реагирующих на пользовательские действия или внутренние события системы.
Механизм включает:
Такой подход превращает статическую анимацию в динамическую систему, способную расширяться во время исполнения.