Фабрики анимаций

Парадигма фабричного создания анимаций

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

Фабрика анимаций в контексте mo.js — это функция-конструктор или класс, который принимает набор параметров и возвращает готовый объект анимации с предопределённым поведением. Такой подход позволяет:

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

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


Базовые фабрики mo.js

Shape — фабрика графических примитивов

Фабрика Shape отвечает за создание анимируемых геометрических объектов. Она позволяет описывать форму, её трансформации и поведение во времени.

const circle = new mojs.Shape({
  shape: 'circle',
  fill: 'none',
  stroke: '#4A90E2',
  strokeWidth: 4,
  radius: 50,
  duration: 800
});

circle.play();

Внутри фабрики происходит генерация SVG-элемента и привязка анимационных свойств:

  • радиус
  • прозрачность
  • трансформации (scale, rotate)
  • параметры обводки

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


Burst — фабрика разлёта частиц

Burst является композиционной фабрикой, создающей набор анимационных частиц, исходящих из одной точки.

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

burst.play();

Особенность фабрики заключается в автоматической генерации дочерних анимаций:

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

Tween — фабрика временных интерполяций

Tween представляет собой базовую фабрику временных значений, не привязанную к DOM или SVG. Она используется для управления числовыми параметрами.

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

tween.play();

Фабрика Tween служит основой для:

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

Параметризация фабрик

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

  • статическими значениями
  • диапазонами {from: to}
  • функциями, возвращающими значения на лету

Пример диапазонной параметризации:

const anim = new mojs.Shape({
  radius: { 0: 80 },
  opacity: { 1: 0 },
  duration: 1200
});

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

Функциональная параметризация:

const dynamic = new mojs.Shape({
  radius() {
    return Math.random() * 50 + 20;
  },
  duration: 600
});

Фабрика при каждом создании анимации пересчитывает значения, обеспечивая вариативность.


Композиционные фабрики и вложенность

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

const complex = new mojs.Burst({
  radius: { 0: 120 },
  count: 5,
  children: {
    shape: 'rect',
    radius: { 10: 40 },
    duration: 700,
    easing: 'cubic.out'
  }
});

В этом случае родительская фабрика управляет:

  • количеством экземпляров
  • общей геометрией сцены
  • синхронизацией времени

Дочерняя фабрика отвечает за визуальное поведение отдельного элемента.


Фабрики как генераторы сцен

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

function createPulse(color, radius) {
  return new mojs.Shape({
    shape: 'circle',
    fill: 'none',
    stroke: color,
    radius: { 0: radius },
    opacity: { 1: 0 },
    duration: 800
  });
}

const pulse1 = createPulse('#FF0000', 60);
const pulse2 = createPulse('#00FF00', 80);

pulse1.play();
pulse2.play();

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

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

Динамические фабрики и генерация во времени

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

function burstAt(x, y) {
  return new mojs.Burst({
    left: x,
    top: y,
    radius: { 0: 100 },
    count: 8,
    children: {
      shape: 'circle',
      fill: '#3D7EAA',
      duration: 900
    }
  }).play();
}

document.addEventListener('click', (e) => {
  burstAt(e.pageX, e.pageY);
});

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


Переиспользование и клонирование фабрик

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

const baseShape = new mojs.Shape({
  shape: 'circle',
  radius: 40,
  fill: '#333',
  duration: 500
});

const variant = baseShape.clone({
  fill: '#FF9900',
  radius: 70
});

Клонирование позволяет:

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

Фабрики и временные последовательности

Фабрики могут объединяться в временные цепочки через композиционные структуры.

const timeline = new mojs.Timeline();

const first = new mojs.Shape({
  radius: { 0: 50 },
  duration: 600
});

const second = new mojs.Shape({
  radius: { 50: 0 },
  duration: 600
});

timeline.add(first, second);
timeline.play();

Каждая фабрика сохраняет автономность, но при добавлении в таймлайн становится частью общей временной логики.


Параметры наследования в фабриках

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

const base = {
  duration: 800,
  easing: 'quad.out'
};

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

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


Фабрики и генеративные паттерны

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

function randomBurst() {
  return new mojs.Burst({
    radius: { 0: Math.random() * 150 },
    count: Math.floor(Math.random() * 10) + 5,
    children: {
      shape: ['circle', 'rect'],
      duration: 1000
    }
  });
}

Такие фабрики используются для:

  • визуализации данных
  • реактивных интерфейсов
  • игровых эффектов
  • интерактивных сцен

Фабрики как основа архитектуры анимаций

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

Фабрики формируют:

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