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

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

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

Ключевая идея:

  • каждому элементу назначается собственный delay
  • задержка вычисляется на основе его позиции в наборе
  • анимации используют одинаковую базовую конфигурацию
import { animate } from "motion";

const items = document.querySelectorAll(".item");

items.forEach((item, index) => {
  animate(
    item,
    {
      opacity: [0, 1],
      transform: ["translateY(20px)", "translateY(0px)"]
    },
    {
      duration: 0.5,
      delay: index * 0.1
    }
  );
});

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

Использование временной сетки

В Motion One задержка не обязана быть линейной. Последовательность может строиться на произвольной функции времени:

  • квадратическое ускорение
  • логарифмическое распределение
  • случайное смещение в пределах диапазона
items.forEach((item, index) => {
  const delay = Math.pow(index, 1.2) * 0.08;

  animate(
    item,
    {
      opacity: [0, 1],
      transform: ["scale(0.9)", "scale(1)"]
    },
    {
      duration: 0.4,
      delay
    }
  );
});

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

Каскадная анимация через общий контроллер времени

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

import { timeline } from "motion";

timeline([
  [".item-1", { opacity: [0, 1], y: [20, 0] }, { duration: 0.4 }],
  [".item-2", { opacity: [0, 1], y: [20, 0] }, { at: "+0.1", duration: 0.4 }],
  [".item-3", { opacity: [0, 1], y: [20, 0] }, { at: "+0.1", duration: 0.4 }]
]);

Здесь параметр at задаёт относительное смещение во времени относительно предыдущего ключевого кадра, формируя строго контролируемую последовательность.

Построение последовательности через массив состояний

Когда требуется масштабируемая система анимаций, последовательность описывается как структура данных. В Motion One это позволяет отделить логику от DOM-манипуляций.

const sequence = [
  { selector: ".item-1", delay: 0 },
  { selector: ".item-2", delay: 0.1 },
  { selector: ".item-3", delay: 0.2 }
];

sequence.forEach(({ selector, delay }) => {
  animate(
    selector,
    {
      opacity: [0, 1],
      transform: ["translateY(15px)", "translateY(0px)"]
    },
    {
      duration: 0.45,
      delay
    }
  );
});

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

Синхронизация с появлением DOM-структур

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

function animateList(container) {
  const items = container.querySelectorAll(".item");

  items.forEach((item, index) => {
    animate(
      item,
      {
        opacity: [0, 1],
        transform: ["translateY(10px)", "translateY(0)"]
      },
      {
        duration: 0.3,
        delay: index * 0.08
      }
    );
  });
}

const observer = new MutationObserver((mutations) => {
  mutations.forEach(() => {
    const container = document.querySelector(".list");
    if (container) animateList(container);
  });
});

observer.observe(document.body, { childList: true, subtree: true });

Такой механизм позволяет связывать последовательность появления с жизненным циклом интерфейса.

Управление ритмом и плотностью появления

В сложных интерфейсах важна не только последовательность, но и ритм. В Motion One ритм формируется через комбинацию duration и delay.

Основные паттерны:

  • плотное появление (минимальные задержки)
  • растянутый каскад (увеличивающиеся задержки)
  • группировка (сброс задержки каждые N элементов)
items.forEach((item, index) => {
  const groupSize = 4;
  const groupIndex = Math.floor(index / groupSize);
  const withinGroupIndex = index % groupSize;

  animate(
    item,
    {
      opacity: [0, 1],
      transform: ["translateY(25px)", "translateY(0px)"]
    },
    {
      duration: 0.35,
      delay: groupIndex * 0.2 + withinGroupIndex * 0.08
    }
  );
});

Так формируется структурированное появление блоками, а не линейной цепочкой.

Последовательное появление с обратным порядком

Иногда требуется инвертированная последовательность, где элементы появляются с конца массива. В Motion One это достигается изменением индекса:

items.forEach((item, index) => {
  const reversedIndex = items.length - 1 - index;

  animate(
    item,
    {
      opacity: [0, 1],
      transform: ["scale(0.8)", "scale(1)"]
    },
    {
      duration: 0.4,
      delay: reversedIndex * 0.1
    }
  );
});

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

Комбинирование последовательности с переходами состояния

В Motion One последовательное появление часто комбинируется с изменением состояния элементов: hover, active, loaded.

items.forEach((item, index) => {
  animate(
    item,
    {
      opacity: [0, 1],
      transform: ["translateY(30px)", "translateY(0px)"]
    },
    {
      duration: 0.5,
      delay: index * 0.07
    }
  );

  item.addEventListener("mouseenter", () => {
    animate(item, { scale: 1.05 }, { duration: 0.2 });
  });

  item.addEventListener("mouseleave", () => {
    animate(item, { scale: 1 }, { duration: 0.2 });
  });
});

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