Синхронизация элементов

В Motion One координация нескольких элементов достигается через единый контекст времени, где анимации начинают, продолжаются и завершаются относительно общей системы отсчёта. Такой подход позволяет строить сложные сцены, в которых поведение элементов строго детерминировано и не зависит от ручного управления задержками.

Основой синхронизации выступает функция создания анимаций с единым таймингом и возможностью объединения в последовательности или параллельные группы.

import { animate } from "motion";

const box = document.querySelector(".box");
const title = document.querySelector(".title");

animate(box, { x: 200, opacity: 1 }, { duration: 1 });
animate(title, { y: -50, opacity: 1 }, { duration: 1 });

В приведённом примере оба элемента запускаются одновременно, но их синхронизация ограничена лишь стартовым моментом. Для более точного управления используется композиция через таймлайн.

Таймлайн как механизм координации

Таймлайн позволяет объединять несколько анимаций в единую структуру времени, где каждая операция получает собственное смещение относительно общей шкалы.

import { timeline } from "motion";

timeline([
  [".box", { x: 200 }, { duration: 0.6 }],
  [".title", { opacity: 1 }, { duration: 0.4 }, "-=0.2"],
  [".subtitle", { y: 30 }, { duration: 0.5 }, "+=0.1"]
]);

Каждый элемент таймлайна описывается массивом, где задаются:

  • цель анимации
  • свойства
  • параметры времени
  • позиция в общей шкале

Относительные смещения "-=0.2" и "+=0.1" позволяют точно выстраивать пересечения и паузы между элементами, формируя плотную синхронизацию.

Параллельные и последовательные группы

Синхронизация часто требует разделения анимаций на блоки, которые либо идут строго последовательно, либо проигрываются одновременно.

Последовательное выполнение

timeline([
  [".step-1", { opacity: 1 }, { duration: 0.4 }],
  [".step-2", { opacity: 1 }, { duration: 0.4 }],
  [".step-3", { opacity: 1 }, { duration: 0.4 }]
]);

Каждый следующий шаг начинается после завершения предыдущего, формируя линейную структуру.

Параллельное выполнение

timeline([
  [".left", { x: 100 }, { duration: 0.8 }],
  [".right", { x: -100 }, { duration: 0.8 }],
  [".center", { scale: 1.2 }, { duration: 0.8 }]
]);

Если не задано смещение, все элементы стартуют одновременно, сохраняя общий временной контур.

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

Более сложные сценарии требуют частичного наложения анимаций. Motion One позволяет управлять этим через позиционные параметры в таймлайне.

timeline([
  [".panel", { x: 300 }, { duration: 1 }],
  [".overlay", { opacity: 1 }, { duration: 0.4 }, "-=0.7"],
  [".content", { y: -20 }, { duration: 0.5 }, "-=0.3"]
]);

Перекрытия создают ощущение непрерывного движения, где элементы взаимодействуют во времени, а не существуют изолированно.

Использование stagger для групповой синхронизации

Stagger позволяет синхронизировать большое количество однотипных элементов с равномерным распределением задержек.

import { animate, stagger } from "motion";

animate(
  ".item",
  { opacity: 1, y: 0 },
  {
    delay: stagger(0.1),
    duration: 0.5
  }
);

Механизм stagger распределяет запуск анимаций по формуле последовательного смещения, сохраняя общую структуру группы.

Радиальная и индексная синхронизация

Stagger может учитывать порядок элементов и их положение в DOM.

stagger(0.08, { start: 0.2 });

В результате элементы начинают анимацию не одновременно, но сохраняют единый ритм, что создаёт эффект волны.

Синхронизация через контролируемые анимации

Каждая анимация в Motion One возвращает управляющий объект, который позволяет координировать несколько процессов вручную.

const box = animate(".box", { x: 200 }, { duration: 1 });
const text = animate(".text", { opacity: 1 }, { duration: 1 });

box.pause();
text.pause();

setTimeout(() => {
  box.play();
  text.play();
}, 500);

Такой подход используется при необходимости внешнего контроля над временной логикой, например при взаимодействии с интерфейсом или состояниями приложения.

Синхронизация через события завершения

Координация анимаций может строиться на основе завершения предыдущих процессов.

animate(".box", { x: 200 }, { duration: 1 }).finished.then(() => {
  animate(".text", { opacity: 1 }, { duration: 0.5 });
});

Механизм finished создаёт цепочку зависимостей, где следующий элемент строго привязан к завершению предыдущего.

Общая синхронизация через shared timing

Motion One использует единый временной контекст, в котором можно задавать согласованные параметры для нескольких анимаций.

const options = {
  duration: 0.8,
  easing: "ease-in-out"
};

animate(".a", { x: 100 }, options);
animate(".b", { y: 100 }, options);
animate(".c", { scale: 1.2 }, options);

Общий объект параметров гарантирует идентичное поведение времени и кривых движения, что упрощает визуальную согласованность.

Координация входящих и исходящих состояний

Синхронизация часто применяется для управления состояниями появления и исчезновения элементов. В таких сценариях важно согласовать вход и выход разных компонентов.

animate(".modal", { opacity: 1, scale: 1 }, { duration: 0.4 });

animate(".backdrop", { opacity: 1 }, { duration: 0.4 });

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

Синхронизация групп через функции-композиции

Для сложных интерфейсов используется абстракция, объединяющая несколько анимаций в единый блок.

function openMenu() {
  return timeline([
    [".menu", { x: 0 }, { duration: 0.5 }],
    [".menu-item", { opacity: 1 }, { duration: 0.3 }, stagger(0.05)],
    [".overlay", { opacity: 1 }, { duration: 0.4 }, "-=0.3"]
  ]);
}

Такая композиция позволяет повторно использовать синхронизированные сценарии без дублирования логики.

Согласование трансформаций между элементами

Синхронизация часто требуется при одновременном изменении свойств нескольких элементов, связанных общей визуальной логикой.

timeline([
  [".image", { scale: 1.1 }, { duration: 0.6 }],
  [".caption", { y: -10, opacity: 1 }, { duration: 0.6 }, "<"],
  [".border", { scaleX: 1 }, { duration: 0.6 }, "<"]
]);

Символ < указывает на одновременный старт с предыдущим элементом, обеспечивая строгую временную привязку.

Синхронизация в сложных интерфейсных сценах

При построении интерфейсных переходов с множеством элементов синхронизация становится центральным механизмом управления визуальной логикой. Каждое состояние интерфейса представляет собой набор согласованных анимаций, которые должны завершаться в строго определённые моменты.

timeline([
  [".header", { y: 0 }, { duration: 0.4 }],
  [".content", { opacity: 1 }, { duration: 0.6 }, "-=0.2"],
  [".sidebar", { x: 0 }, { duration: 0.5 }, "-=0.4"],
  [".footer", { opacity: 1 }, { duration: 0.3 }]
]);

В таких структурах важна не только последовательность, но и баланс перекрытий, создающий ощущение цельного движения интерфейса.

Согласование скорости и ритма между элементами

Единый ритм анимаций достигается через унификацию длительностей и easing-функций. Это создаёт ощущение, что элементы принадлежат одной системе движения.

const rhythm = {
  duration: 0.7,
  easing: "ease-out"
};

animate(".card", { y: 0 }, rhythm);
animate(".icon", { scale: 1 }, rhythm);
animate(".text", { opacity: 1 }, rhythm);

При таком подходе синхронизация достигается не только временными смещениями, но и общими динамическими характеристиками движения.