Popmotion строится вокруг функционального подхода: анимация рассматривается как поток значений во времени. Это принципиально отличается от императивных API, где изменяется DOM напрямую через методы объектов.
Ключевые сущности:
При переходе с других библиотек важно перестроить мышление: вместо «запустить анимацию элемента» появляется «создать поток значений и применить его к стилю».
В jQuery анимация основана на изменении свойств DOM с внутренним таймером:
$("#box").animate({
left: "200px",
opacity: 0.5
}, 400);
В Popmotion аналогичная логика разделяется на источник значений и их применение:
import { animate, styler } from "popmotion";
const box = document.querySelector(".box");
const boxStyler = styler(box);
animate({
from: { x: 0, opacity: 1 },
to: { x: 200, opacity: 0.5 },
duration: 400,
onUpdate: (v) => boxStyler.set(v)
});
Различие:
В GSAP анимация описывается декларативно через твины:
gsap.to(".box", {
duration: 1,
x: 300,
opacity: 0
});
В Popmotion аналог строится через animate:
import { animate, styler } from "popmotion";
const box = styler(document.querySelector(".box"));
animate({
from: 0,
to: 300,
duration: 1000,
onUpdate: v => box.set("x", v)
});
Ключевые различия при миграции:
timeline и
вложенных animateGSAP:
const tl = gsap.timeline();
tl.to(".box", { x: 100 })
.to(".box", { y: 100 });
Popmotion:
import { timeline, animate } from "popmotion";
timeline([
animate({
from: 0,
to: 100,
onUpdate: v => boxStyler.set("x", v)
}),
animate({
from: 0,
to: 100,
onUpdate: v => boxStyler.set("y", v)
})
]);
Особенность Popmotion:
Anime.js использует объект конфигурации с автоматическим выбором targets:
anime({
targets: ".box",
translateX: 250,
opacity: 0,
duration: 800
});
В Popmotion требуется явное управление target:
import { animate, styler } from "popmotion";
const box = styler(document.querySelector(".box"));
animate({
from: 0,
to: 250,
duration: 800,
onUpdate: v => {
box.set("x", v);
box.set("opacity", 1 - v / 250);
}
});
Миграционные особенности:
В классических библиотеках easing задаётся строкой:
ease: "easeOutBounce"
В Popmotion easing — это функция:
import { easeOut, tween } from "popmotion";
tween({
from: 0,
to: 1,
ease: easeOut,
onUpdate: v => console.log(v)
});
Особенность:
Обычный подход:
element.style.transform = `translateX(${x}px)`;
Popmotion вводит слой абстракции:
import { styler, animate } from "popmotion";
const node = document.querySelector(".box");
const box = styler(node);
animate({
from: 0,
to: 300,
onUpdate: v => box.set({ x: v })
});
Преимущества при миграции:
В системах вроде Framer Motion анимация привязана к жизненному циклу компонентов.
Popmotion отделён от UI-фреймворков:
import { animate } from "popmotion";
useEffect(() => {
const controls = animate({
from: 0,
to: 1,
onUpdate: v => setOpacity(v)
});
return () => controls.stop();
}, []);
Ключевое отличие:
Во многих библиотеках spring скрыт внутри high-level API:
spring: true
В Popmotion spring — самостоятельная модель:
import { spring } from "popmotion";
spring({
from: 0,
to: 300,
stiffness: 200,
damping: 20,
onUpdate: v => console.log(v)
}).start();
При миграции важно учитывать:
Императивные библиотеки часто используют коллбэки:
animate(el, { x: 100 }, () => {
animate(el, { y: 100 });
});
В Popmotion:
import { timeline, animate } from "popmotion";
timeline([
animate({
from: 0,
to: 100,
onUpdate: v => box.set("x", v)
}),
animate({
from: 0,
to: 100,
onUpdate: v => box.set("y", v)
})
]);
Преобразование:
В традиционных библиотеках часто присутствует:
В Popmotion контроль реализуется через контроллеры:
const animation = animate({
from: 0,
to: 100,
onUpdate: v => box.set("x", v)
});
animation.stop();
При миграции:
В других библиотеках события часто ограничены:
Popmotion делает поток наблюдаемым:
animate({
from: 0,
to: 100,
onUpdate: v => console.log(v),
onComplete: () => console.log("done")
});
При необходимости можно строить более сложные реакции:
Миграция обычно сводится к трём шагам:
Выделение источника значений
Определение преобразований
Привязка к побочным эффектам
Такая структура заменяет классическую модель «элемент → анимация» на «данные → поток → отображение».