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

В основе архитектуры Popmotion лежит функциональный подход к созданию анимаций. Вместо работы с классами или императивными контроллерами библиотека использует фабрики анимаций — функции, которые возвращают анимационные действия (actions). Эти действия представляют собой управляемые потоки значений во времени, которые можно запускать, останавливать и комбинировать.

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

Природа фабрик анимаций

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

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

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

Пример общей структуры:

const animation = factory(config);

animation.start((value) => {
  // обработка значения анимации
});

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


Tween как базовая фабрика интерполяции

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

Математическая основа tween — нормализация времени:

progress = elapsed / duration
value = from + (to - from) * easing(progress)

Фабрика tween принимает параметры:

  • начальное значение
  • конечное значение
  • длительность
  • функцию easing

Пример использования:

import { tween } from 'popmotion';

const fade = tween({
  from: 0,
  to: 1,
  duration: 500
});

fade.start(v => {
  element.style.opacity = v;
});

Внутренне tween не хранит состояние между кадрами, а вычисляет значение на основе времени старта и текущего timestamp.

Роль easing-функций

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

  • ускорение
  • замедление
  • эластичность
  • bounce-эффекты

Формально easing — это функция:

easing: [0, 1] → [0, 1]

Spring как физическая фабрика

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

Основное уравнение:

F = -k * x - c * v

где:

  • k — жёсткость пружины
  • c — демпфирование
  • x — смещение от цели
  • v — скорость

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

import { spring } from 'popmotion';

const scaleUp = spring({
  from: 1,
  to: 2,
  stiffness: 200,
  damping: 20
});

scaleUp.start(v => {
  element.style.transform = `scale(${v})`;
});

Особенности spring-фабрики

  • отсутствие фиксированной длительности
  • зависимость от физического состояния
  • естественное затухание
  • возможность «перелёта» через цель

Spring-фабрика особенно полезна для UI-анимаций, имитирующих реальную физику взаимодействий.


Keyframes как фабрика состояний

keyframes описывает анимацию через набор промежуточных значений, распределённых во времени.

Каждый кадр определяется парой:

(time, value)

Функция интерполирует значения между ключевыми точками.

import { keyframes } from 'popmotion';

const move = keyframes({
  values: [0, 100, 50, 200],
  times: [0, 0.3, 0.6, 1],
  duration: 1000
});

move.start(v => {
  element.style.left = `${v}px`;
});

Интерполяция внутри keyframes

Если временные метки не заданы, Popmotion распределяет их равномерно. Между ключевыми точками используется интерполяция, аналогичная tween, но ограниченная сегментами.

Keyframes можно рассматривать как расширенный tween с множеством контрольных точек.


Physics как универсальная фабрика движения

Фабрика physics реализует более общий подход, чем spring. Она позволяет задавать:

  • начальную скорость
  • трение
  • ускорение
  • импульсы

Базовая модель:

velocity = velocity * friction + acceleration
position = position + velocity
import { physics } from 'popmotion';

const drift = physics({
  from: 0,
  velocity: 500,
  friction: 0.9
});

drift.start(v => {
  element.style.transform = `translateX(${v}px)`;
});

Отличие от spring

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

Физическая фабрика используется для инерции, прокрутки и кинетических эффектов.


Decay как фабрика затухания

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

Формула упрощённого затухания:

velocity(t) = initialVelocity * (1 - decayRate)^t
import { decay } from 'popmotion';

const inertia = decay({
  from: 0,
  velocity: 800,
  power: 0.8
});

inertia.start(v => {
  element.scrollLeft = v;
});

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


Комбинирование фабрик через композицию

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

Пайплайн значений

Выход одной фабрики может служить входом другой:

spring({ from: 0, to: 1 })
  .pipe(v => v * 100)
  .start(v => {
    element.style.opacity = v;
  });

Параллельные анимации

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

  • одна отвечает за позицию
  • другая за прозрачность
  • третья за масштаб

Каждая фабрика остаётся независимой, но синхронизированной по времени старта.


Создание пользовательских фабрик

Фабрика в Popmotion — это функция, возвращающая action-объект. Это позволяет создавать собственные модели анимации, не ограничиваясь встроенными типами.

Минимальная структура:

const customFactory = (config) => {
  return {
    start: (update) => {
      let value = config.from;

      const interval = setInterval(() => {
        value += config.step;
        update(value);

        if (value >= config.to) {
          clearInterval(interval);
        }
      }, 16);

      return {
        stop: () => clearInterval(interval)
      };
    }
  };
};

Такая фабрика сохраняет совместимость с экосистемой Popmotion, поскольку реализует стандартный интерфейс start/stop.


Абстракция времени в фабриках

Фабрики Popmotion объединяет единый принцип: время отделено от логики изменения значений. Независимо от типа анимации:

  • tween использует линейное время
  • spring опирается на физическую симуляцию
  • physics работает с инерцией
  • keyframes управляет временными точками

Во всех случаях время выступает как независимая переменная, а значение — как её функция.


Поведение фабрик как потоков данных

Каждая фабрика может быть рассмотрена как поток:

time → factory → value stream → subscriber

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

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

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