Архитектура Motion One отличается минимализмом и опорой на нативные Web Animations API, что напрямую влияет на способ переноса логики из Anime.js. В отличие от Anime.js, где анимация строится через централизованный движок и объектную конфигурацию с собственным интерпретатором ключевых кадров, Motion One работает поверх браузерного слоя анимаций, делая основной упор на декларативные вызовы и прямое управление эффектами.
Ключевое различие заключается в модели исполнения: Anime.js создаёт внутренний таймлайн и обновляет свойства через requestAnimationFrame, тогда как Motion One делегирует большую часть работы браузеру, оставляя библиотеке роль координатора параметров.
В Anime.js базовая анимация обычно описывается через функцию
anime:
anime({
targets: '.box',
translateX: 250,
opacity: 0.5,
duration: 800,
easing: 'easeInOutQuad'
});
Эквивалент в Motion One строится через функцию
animate:
import { animate } from "motion";
animate(
".box",
{
x: 250,
opacity: 0.5
},
{
duration: 0.8,
easing: "ease-in-out"
}
);
Основные отличия проявляются в нескольких деталях:
x,
y, scale), а не строковые
transform-цепочкиAnime.js активно использует массивы keyframes:
anime({
targets: ".box",
translateX: [0, 100, 200],
opacity: [1, 0.5, 1],
duration: 1200
});
В Motion One ключевые кадры выражаются через массив значений:
animate(
".box",
{
x: [0, 100, 200],
opacity: [1, 0.5, 1]
},
{
duration: 1.2
}
);
Различие заключается в том, что Motion One интерпретирует массивы как часть Web Animations Keyframes без промежуточного преобразования в собственный формат. Это уменьшает слой абстракции и делает поведение более предсказуемым при сложных анимациях.
В Anime.js используется объект timeline:
const tl = anime.timeline();
tl.add({
targets: ".box",
translateX: 100,
duration: 500
}).add({
targets: ".box",
translateY: 100,
duration: 500
});
В Motion One композиция строится через timeline:
import { timeline } from "motion";
timeline([
[".box", { x: 100 }, { duration: 0.5 }],
[".box", { y: 100 }, { duration: 0.5 }]
]);
Здесь наблюдается сдвиг парадигмы:
Anime.js оперирует строковыми значениями трансформаций:
translateX: "100px"
Motion One разделяет числовые значения и единицы автоматически:
x: 100
Система преобразования встроена в библиотеку и учитывает тип свойства:
x, y, rotate,
scale) работают без единицТакое разделение снижает количество ошибок, связанных с конкатенацией строк и ручным указанием единиц измерения.
Anime.js использует строковые идентификаторы:
easing: "easeOutExpo"
Motion One поддерживает как строки, так и функции:
easing: "ease-out"
или
import { spring } from "motion";
animate(".box", {
x: 200
}, {
easing: spring()
});
Поддержка физических моделей, таких как spring, делает Motion One ближе к системам анимации UI уровня iOS и современных дизайн-систем.
Anime.js:
anime({
targets: ".item",
translateY: 50,
delay: anime.stagger(100)
});
Motion One:
import { stagger, animate } from "motion";
animate(
".item",
{ y: 50 },
{
delay: stagger(0.1)
}
);
Существенное отличие заключается в единицах времени: в Motion One задержки выражаются в секундах, что сохраняет консистентность всей временной модели библиотеки.
Anime.js возвращает объект анимации с методами управления:
const anim = anime({ ... });
anim.pause();
anim.play();
anim.seek(500);
Motion One возвращает controls-объект:
import { animate } from "motion";
const controls = animate(".box", { x: 100 });
controls.pause();
controls.play();
controls.stop();
Дополнительно поддерживается подписка на прогресс:
controls.on("update", latest => {
console.log(latest);
});
Такой подход делает управление состоянием ближе к реактивной модели.
Anime.js требует сторонних решений для работы со скроллом. Motion One включает встроенные утилиты.
import { inView } from "motion";
inView(".box", ({ target }) => {
animate(target, { opacity: 1, y: 0 });
});
Подход строится вокруг наблюдения за элементом через IntersectionObserver, что устраняет необходимость в дополнительных плагинах.
Anime.js часто использует строковые значения transform:
translate: "100px 50px"
Motion One разделяет координаты:
x: 100,
y: 50
Это изменение влияет на читаемость и композицию сложных анимаций, особенно при комбинировании нескольких трансформаций.
При миграции многошаговых сценариев из Anime.js структура обычно
разбивается на независимые вызовы animate или массивы
timeline.
Anime.js:
anime({
targets: ".box",
translateX: 100,
opacity: 0,
duration: 600,
delay: 200
});
Motion One:
animate(
".box",
{ x: 100, opacity: 0 },
{
duration: 0.6,
delay: 0.2
}
);
Сложные сценарии часто декомпозируются:
timeline([
[".box", { x: 100 }, { duration: 0.4 }],
[".box", { opacity: 0 }, { duration: 0.2 }]
]);
Anime.js выполняет вычисления анимаций через собственный цикл обновления, что даёт гибкость, но увеличивает нагрузку при большом количестве элементов.
Motion One делегирует интерполяцию браузеру:
Это особенно заметно при анимации списков, сеток и интерфейсных переходов с большим количеством DOM-узлов.
| Anime.js | Motion One |
|---|---|
targets |
селектор или элемент |
translateX |
x |
translateY |
y |
duration: 1000 |
duration: 1 |
easing: "easeOut" |
"ease-out" или функция |
anime.timeline() |
timeline([...]) |
anime.stagger() |
stagger() |
Anime.js часто использует повторные инстансы анимаций или reset через параметры.
Motion One позволяет повторно использовать controls:
const controls = animate(".box", { x: 100 });
controls.stop();
controls.play();
Поведение становится более линейным: анимация рассматривается как управляемый процесс, а не одноразовый запуск конфигурации.
При переносе крупных проектов наблюдается типовая структурная трансформация:
animatetimelineТакая перестройка снижает плотность абстракций и делает код ближе к спецификации браузера, на которой основана анимация.