Для запуска анимации в Popmotion используется базовая функция
animate, которая объединяет тайминг, интерполяцию значений
и управление жизненным циклом анимации в одном универсальном интерфейсе.
Модель работы строится вокруг изменения значения во времени с
последующей передачей результата в callback-функцию
onUpdate.
Основная форма запуска анимации строится вокруг набора параметров: начального значения, конечного значения и конфигурации временной функции.
import { animate } from "popmotion";
animate({
from: 0,
to: 100,
duration: 1000,
onUpdate: (latest) => {
console.log(latest);
}
});
В данном примере происходит линейное изменение числа от 0 до 100 за
одну секунду. Каждый кадр анимации вызывает onUpdate, куда
передаётся текущее интерполированное значение.
В основе Popmotion лежит принцип интерполяции между двумя состояниями. При изменении числовых значений библиотека вычисляет промежуточные точки на основе прогресса времени.
Формально процесс можно представить как:
fromtot в диапазоне от 0 до 1Для линейного случая:
value = from + (to - from) * t
Такой подход обеспечивает непрерывность движения и независимость от частоты кадров.
Для управления DOM-элементами используется ручное обновление стилей
внутри onUpdate. Popmotion не навязывает слой привязки к
DOM, оставляя контроль над рендерингом.
import { animate } from "popmotion";
const box = document.querySelector(".box");
animate({
from: 0,
to: 300,
duration: 800,
onUpdate: (x) => {
box.style.transform = `translateX(${x}px)`;
}
});
Здесь изменение числового значения напрямую преобразуется в
CSS-свойство transform. Такой подход позволяет использовать
анимацию для любых визуальных параметров: позиции, прозрачности,
масштабирования.
Popmotion поддерживает анимацию объектов, где изменяется сразу
несколько параметров. В этом случае from и to
принимают объектную форму, а onUpdate получает
промежуточное состояние объекта.
import { animate } from "popmotion";
const box = document.querySelector(".box");
animate({
from: { x: 0, opacity: 0 },
to: { x: 200, opacity: 1 },
duration: 1000,
onUpdate: (v) => {
box.style.transform = `translateX(${v.x}px)`;
box.style.opacity = v.opacity;
}
});
Интерполяция выполняется отдельно для каждого свойства объекта, что позволяет синхронизировать сложные анимации без дополнительной логики.
Поведение изменения значения во времени определяется функцией сглаживания. Без неё движение остаётся линейным и механистичным. Easing-функции позволяют моделировать ускорение, замедление и инерцию.
В Popmotion easing передаётся через параметр ease.
import { animate, easeOut } from "popmotion";
animate({
from: 0,
to: 400,
duration: 1000,
ease: easeOut,
onUpdate: (x) => {
box.style.transform = `translateX(${x}px)`;
}
});
Функция easeOut замедляет движение к концу анимации,
создавая эффект естественного торможения.
Easing работает через преобразование прогресса времени
t:
t' = easing(t)
После преобразования интерполяция применяется уже к модифицированному
значению t'.
Возвращаемый объект animate предоставляет контроль над
процессом выполнения. Анимацию можно остановить или повторно запустить в
зависимости от состояния интерфейса.
const animation = animate({
from: 0,
to: 1000,
duration: 2000,
onUpdate: (v) => {
element.style.transform = `translateY(${v}px)`;
}
});
setTimeout(() => {
animation.stop();
}, 1000);
Метод stop завершает выполнение и фиксирует текущее
значение.
Popmotion поддерживает настройку задержки старта и повторного выполнения анимации. Это позволяет формировать циклические движения без внешнего таймера.
animate({
from: 0,
to: 360,
duration: 1500,
delay: 300,
repeat: Infinity,
onUpdate: (v) => {
box.style.transform = `rotate(${v}deg)`;
}
});
Повторение реализуется через перезапуск временной шкалы после достижения конечного значения.
Одной из ключевых особенностей Popmotion является независимость от
частоты кадров. Анимация не привязана к
requestAnimationFrame напрямую, а использует временные
метки для вычисления прогресса.
При каждом обновлении вычисляется:
elapsed = currentTime - startTime
t = elapsed / duration
После нормализации значение t ограничивается диапазоном
[0, 1], что гарантирует стабильное поведение независимо от
нагрузки на систему.
Popmotion рассматривает анимацию как преобразование состояния, а не как побочный эффект. Это позволяет использовать её для вычисления значений вне DOM, например для математических моделей или управления данными интерфейса.
import { animate } from "popmotion";
let currentValue = 0;
animate({
from: 0,
to: 50,
duration: 1000,
onUpdate: (v) => {
currentValue = v;
}
});
Такой подход отделяет визуализацию от логики и делает анимацию универсальным инструментом вычисления переходных состояний.
Параметры from и to могут задаваться через
функции, что позволяет вычислять значения во время запуска анимации. Это
используется для реактивных интерфейсов.
animate({
from: () => 0,
to: () => window.innerWidth,
duration: 1200,
onUpdate: (x) => {
element.style.transform = `translateX(${x}px)`;
}
});
Функциональная форма позволяет учитывать текущее состояние среды в момент старта анимации.
Событие завершения позволяет синхронизировать последующие действия с концом перехода значений.
animate({
from: 0,
to: 1,
duration: 500,
onUpdate: (v) => {
element.style.opacity = v;
},
onComplete: () => {
element.style.display = "none";
}
});
Завершение вызывается после достижения конечного состояния или после принудительной остановки с завершением цикла.
Несколько независимых анимаций могут выполняться параллельно, формируя сложные сцены движения. Каждая анимация управляет своей областью состояния.
animate({
from: 0,
to: 200,
duration: 800,
onUpdate: (x) => {
box1.style.transform = `translateX(${x}px)`;
}
});
animate({
from: 0,
to: 1,
duration: 800,
onUpdate: (o) => {
box2.style.opacity = o;
}
});
Отсутствие глобального состояния делает поведение предсказуемым даже при большом количестве одновременно работающих анимаций.
Анимации могут запускаться в ответ на события интерфейса, формируя реактивное поведение системы. Важно, что каждая анимация является изолированной и не зависит от предыдущих запусков, если это не задано явно через внешнее состояние.
button.addEventListener("click", () => {
animate({
from: 0,
to: 150,
duration: 600,
onUpdate: (x) => {
panel.style.height = `${x}px`;
}
});
});
Такой подход обеспечивает предсказуемое повторное выполнение без накопления состояния между вызовами.
Popmotion строится на декларативном описании переходов. Вместо пошагового управления кадрами задаётся конечная цель и параметры перехода, после чего библиотека самостоятельно управляет вычислением промежуточных значений.
Основная модель можно свести к трём компонентам:
Такой подход позволяет отделить описание движения от его реализации и обеспечивает универсальность применения в различных слоях интерфейса.