Переход с других библиотек

Архитектурная модель анимации в Popmotion

Popmotion строится вокруг функционального подхода: анимация рассматривается как поток значений во времени. Это принципиально отличается от императивных API, где изменяется DOM напрямую через методы объектов.

Ключевые сущности:

  • tween — интерполяция между значениями
  • spring — физическая модель пружины
  • keyframes — последовательности состояний
  • timeline — синхронизация нескольких анимаций
  • styler / value — абстракции над DOM-значениями

При переходе с других библиотек важно перестроить мышление: вместо «запустить анимацию элемента» появляется «создать поток значений и применить его к стилю».


Переход с jQuery animate

В 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)
});

Различие:

  • jQuery скрывает модель анимации
  • Popmotion требует явного управления потоком значений
  • появляется контроль над промежуточными состояниями

Переход с GSAP

В 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)
});

Ключевые различия при миграции:

  • GSAP объединяет селектор и анимацию
  • Popmotion разделяет выбор элемента и управление значением
  • GSAP timeline заменяется комбинацией timeline и вложенных animate

Сравнение таймлайнов

GSAP:

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

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);
  }
});

Миграционные особенности:

  • отсутствует автоматический selector engine
  • нет скрытой привязки свойств
  • логика преобразования значений становится явной

Замена easing-моделей

В классических библиотеках easing задаётся строкой:

ease: "easeOutBounce"

В Popmotion easing — это функция:

import { easeOut, tween } from "popmotion";

tween({
  from: 0,
  to: 1,
  ease: easeOut,
  onUpdate: v => console.log(v)
});

Особенность:

  • easing можно комбинировать
  • легко создавать кастомные кривые
  • проще тестировать математически

Переход от императивного управления стилями

Обычный подход:

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 })
});

Преимущества при миграции:

  • унификация работы с transform
  • автоматическая оптимизация batching
  • единый интерфейс для разных CSS свойств

Переход с React-анимационных библиотек

В системах вроде Framer Motion анимация привязана к жизненному циклу компонентов.

Popmotion отделён от UI-фреймворков:

import { animate } from "popmotion";

useEffect(() => {
  const controls = animate({
    from: 0,
    to: 1,
    onUpdate: v => setOpacity(v)
  });

  return () => controls.stop();
}, []);

Ключевое отличие:

  • нет встроенной интеграции с React
  • управление жизненным циклом вручную
  • выше гибкость, но больше ответственности

Перенос spring-анимаций

Во многих библиотеках 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)
  })
]);

Преобразование:

  • callback-based flow → dataflow composition
  • вложенность заменяется декларацией последовательности

Изменение модели контроля

В традиционных библиотеках часто присутствует:

  • pause()
  • resume()
  • reverse()

В Popmotion контроль реализуется через контроллеры:

const animation = animate({
  from: 0,
  to: 100,
  onUpdate: v => box.set("x", v)
});

animation.stop();

При миграции:

  • управление становится объектным
  • каждая анимация возвращает контроллер
  • состояние не скрыто внутри движка

Обработка событий и промежуточных значений

В других библиотеках события часто ограничены:

  • onStart
  • onComplete

Popmotion делает поток наблюдаемым:

animate({
  from: 0,
  to: 100,
  onUpdate: v => console.log(v),
  onComplete: () => console.log("done")
});

При необходимости можно строить более сложные реакции:

  • ветвления по значениям
  • синхронизация нескольких потоков
  • реактивные цепочки

Типичные ошибки при миграции

  • попытка сохранить DOM-ориентированное мышление
  • перенос конфигураций без адаптации модели данных
  • ожидание автоматического управления селекторами
  • смешивание прямого DOM и styler-абстракции
  • попытка копировать timeline API один-в-один

Стратегия адаптации к Popmotion

Миграция обычно сводится к трём шагам:

  1. Выделение источника значений

    • числа, координаты, состояния
  2. Определение преобразований

    • easing, spring, interpolation
  3. Привязка к побочным эффектам

    • DOM, canvas, state store

Такая структура заменяет классическую модель «элемент → анимация» на «данные → поток → отображение».