В основе архитектуры Popmotion лежит функциональный подход к созданию анимаций. Вместо работы с классами или императивными контроллерами библиотека использует фабрики анимаций — функции, которые возвращают анимационные действия (actions). Эти действия представляют собой управляемые потоки значений во времени, которые можно запускать, останавливать и комбинировать.
Фабрика в Popmotion — это не просто генератор значений, а механизм описания поведения анимации. Она инкапсулирует математическую модель движения, начальные параметры, длительность и способ интерполяции.
Каждая фабрика в Popmotion строится вокруг одной идеи: описание анимации как функции времени. Вызов фабрики возвращает объект действия, который реализует единый интерфейс управления:
Такой подход позволяет рассматривать анимацию как поток данных, а не как одноразовый эффект.
Пример общей структуры:
const animation = factory(config);
animation.start((value) => {
// обработка значения анимации
});
Фабрика здесь выступает как слой конфигурации, отделённый от выполнения.
Одной из ключевых фабрик является tween. Она реализует
линейную или криволинейную интерполяцию между значениями за заданное
время.
Математическая основа tween — нормализация времени:
progress = elapsed / duration
value = from + (to - from) * easing(progress)
Фабрика tween принимает параметры:
Пример использования:
import { tween } from 'popmotion';
const fade = tween({
from: 0,
to: 1,
duration: 500
});
fade.start(v => {
element.style.opacity = v;
});
Внутренне tween не хранит состояние между кадрами, а
вычисляет значение на основе времени старта и текущего timestamp.
Easing-функции изменяют линейный прогресс, создавая нелинейное движение:
Формально easing — это функция:
easing: [0, 1] → [0, 1]
Фабрика spring моделирует движение на основе физики
пружины. В отличие от tween, здесь отсутствует фиксированная
длительность.
Основное уравнение:
F = -k * x - c * 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-фабрика особенно полезна для UI-анимаций, имитирующих реальную физику взаимодействий.
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`;
});
Если временные метки не заданы, Popmotion распределяет их равномерно. Между ключевыми точками используется интерполяция, аналогичная tween, но ограниченная сегментами.
Keyframes можно рассматривать как расширенный tween с множеством контрольных точек.
Фабрика 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)`;
});
Физическая фабрика используется для инерции, прокрутки и кинетических эффектов.
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 объединяет единый принцип: время отделено от логики изменения значений. Независимо от типа анимации:
Во всех случаях время выступает как независимая переменная, а значение — как её функция.
Каждая фабрика может быть рассмотрена как поток:
time → factory → value stream → subscriber
Это позволяет:
Фабрики становятся строительными блоками, из которых формируется сложная анимационная система без необходимости централизованного контроллера состояния.