Сложные анимационные сценарии в Motion One строятся на комбинации
последовательного и параллельного исполнения. Базовая функция
animate() позволяет запускать отдельные анимации, однако
при масштабировании интерфейсов требуется управление целыми группами
эффектов, их синхронизация и точное позиционирование во времени.
Последовательность возникает тогда, когда одна анимация должна стартовать после завершения другой. Параллельность — когда несколько анимаций выполняются одновременно, но с возможностью независимого контроля длительности и задержек.
Ключевая особенность Motion One заключается в том, что управление временем вынесено в отдельный слой — таймлайн.
Таймлайн в Motion One представляет собой контейнер, управляющий набором анимаций как единым процессом. Каждая добавленная анимация получает относительное положение во времени.
import { timeline } from "motion";
timeline([
["div", { opacity: 1 }, { duration: 0.3 }],
["div", { x: 100 }, { duration: 0.5 }]
]);
Каждый элемент массива описывает отдельный шаг. Первый параметр — цель, второй — свойства, третий — опции.
Важный принцип: временная структура определяется порядком элементов, а не вложенностью кода.
Для создания сложных сценариев недостаточно линейной
последовательности. Motion One поддерживает смещение во времени с
помощью параметра at.
timeline([
["h1", { opacity: 1 }, { duration: 0.4 }],
["h1", { y: -20 }, { at: 0.2, duration: 0.5 }],
["p", { opacity: 1 }, { at: "<", duration: 0.3 }]
]);
Значения at позволяют управлять моментом старта
относительно:
"<")">")Это позволяет строить многослойные сцены без необходимости ручного расчета задержек.
При работе с коллекциями DOM-элементов важно управлять их поведением
как единой системой. Motion One предоставляет механизм stagger через
вспомогательную функцию stagger.
import { animate, stagger } from "motion";
animate(
".card",
{ opacity: 1, transform: "translateY(0px)" },
{ delay: stagger(0.1) }
);
Каждый элемент получает смещённую задержку, формируя каскадный эффект.
При использовании внутри таймлайна stagger усиливает контроль над группами:
timeline([
[
".item",
{ scale: 1 },
{ delay: stagger(0.05), duration: 0.3 }
]
]);
Сложные интерфейсы требуют объединения независимых анимационных блоков. Вместо монолитного таймлайна используется композиция функций, возвращающих части сценария.
const fadeIn = (target) => [
[target, { opacity: 1 }, { duration: 0.3 }]
];
const slideUp = (target) => [
[target, { y: 0 }, { duration: 0.5 }]
];
timeline([
...fadeIn("header"),
...slideUp("header"),
...fadeIn("section")
]);
Такой подход позволяет формировать библиотеку переиспользуемых анимационных блоков.
При параллельном выполнении нескольких эффектов важно учитывать их взаимодействие по свойствам трансформации и композиции кадров.
timeline([
["box", { x: 200 }, { duration: 1 }],
["box", { rotate: 180 }, { at: 0, duration: 1 }]
]);
Обе анимации стартуют одновременно, создавая комбинированное движение. Motion One объединяет трансформации в единый CSS transform, минимизируя конфликт между свойствами.
Якоря времени позволяют привязывать анимации к ключевым точкам сценария.
0 — начало таймлайна"<" — начало предыдущей анимации">" — конец предыдущей анимацииtimeline([
["title", { opacity: 1 }, { duration: 0.4 }],
["subtitle", { opacity: 1 }, { at: "<", duration: 0.3 }],
["button", { scale: 1 }, { at: ">", duration: 0.2 }]
]);
Такая модель исключает необходимость ручного вычисления временных смещений и делает структуру анимации декларативной.
Таймлайн может быть растянут или сжат через изменение длительности отдельных шагов или добавление пауз.
timeline([
["overlay", { opacity: 1 }, { duration: 0.2 }],
["modal", { scale: 1 }, { duration: 0.6 }],
["overlay", { opacity: 0 }, { at: "+0.5", duration: 0.2 }]
]);
Параметр at с числовым значением позволяет вводить явные
задержки, формируя паузы между блоками.
Сложные интерфейсы часто требуют вложенных сценариев, где один таймлайн становится частью другого.
const modalTimeline = timeline([
["modal", { scale: 1 }, { duration: 0.4 }],
["content", { opacity: 1 }, { at: "<", duration: 0.3 }]
]);
timeline([
modalTimeline,
["backdrop", { opacity: 1 }, { duration: 0.2 }]
]);
Вложенный таймлайн исполняется как единый шаг, но сохраняет внутреннюю структуру.
Анимации могут формироваться на основе данных, что особенно важно при работе с динамическими интерфейсами.
const items = ["a", "b", "c"];
timeline(
items.map((item, index) => [
`#${item}`,
{ opacity: 1, y: 0 },
{ at: index * 0.1, duration: 0.4 }
])
);
Такой подход позволяет масштабировать последовательности без изменения структуры кода.
Сложные сценарии требуют возможности прерывания текущего выполнения и перезапуска с нового состояния.
const controls = timeline([
["panel", { x: 300 }, { duration: 0.6 }],
["panel", { opacity: 0 }, { duration: 0.3 }]
]);
controls.pause();
controls.play();
controls.stop();
Управляющий объект предоставляет доступ к состоянию анимации и позволяет синхронизировать её с пользовательскими событиями.
В крупных интерфейсах часто используются несколько независимых таймлайнов, работающих синхронно.
const intro = timeline([
["title", { opacity: 1 }, { duration: 0.4 }]
]);
const content = timeline([
["text", { y: 0 }, { duration: 0.5 }]
]);
intro.finished.then(() => {
content.play();
});
Такой подход разделяет сценарии на логические блоки и упрощает управление сложной сценой.
Единообразие поведения достигается через согласование параметров длительности, easing и задержек.
timeline([
["card", { scale: 1 }, { duration: 0.3, easing: "ease-out" }],
["icon", { rotate: 180 }, { at: "<", duration: 0.3, easing: "ease-out" }],
["text", { opacity: 1 }, { at: ">-0.1", duration: 0.2 }]
]);
Комбинации относительных смещений и одинаковых easing-функций создают визуально согласованные сцены.
Атомарный подход предполагает создание минимальных анимационных функций, каждая из которых отвечает за одно свойство или эффект.
const fade = (target) => [target, { opacity: 1 }, { duration: 0.2 }];
const move = (target) => [target, { y: 0 }, { duration: 0.4 }];
const rotate = (target) => [target, { rotate: 90 }, { duration: 0.3 }];
Комбинация таких атомов формирует сложные сцены без дублирования логики.
timeline([
fade("element"),
move("element"),
rotate("element")
]);
При росте приложения анимации перестают быть локальной задачей и превращаются в отдельную систему управления состояниями интерфейса. Motion One позволяет структурировать такие системы через:
Такой подход снижает сложность сопровождения и делает поведение интерфейса предсказуемым даже при большом количестве одновременно активных эффектов