Queue

Очередь анимаций в Velocity.js строится вокруг принципа последовательного выполнения эффектов над одним и тем же DOM-элементом или группой элементов. Каждый новый вызов анимации не обязательно запускается сразу: он может быть помещён в стек исполнения, где управляется порядок, тайминги и синхронизация.

Внутри Velocity.js каждая анимация рассматривается как операция, которая может быть выполнена немедленно или поставлена в очередь. Если для элемента уже выполняется анимация, следующая добавляется в список ожидания и запускается только после завершения текущей.

Базовый вызов:

Velocity(element, { opacity: 0.5 }, { duration: 300 });
Velocity(element, { translateX: 200 }, { duration: 300 });
Velocity(element, { rotateZ: 45 }, { duration: 300 });

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

Роль параметра queue

Ключевой механизм управления очередью задаётся через параметр queue.

Velocity(element, { opacity: 0 }, { duration: 400, queue: true });

Значение true означает использование стандартной очереди выполнения. Это поведение по умолчанию и обеспечивает последовательное исполнение анимаций.

Отключение очереди:

Velocity(element, { scale: 1.5 }, { duration: 400, queue: false });

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

Имя очереди и изоляция потоков

Velocity.js поддерживает именованные очереди, позволяющие разделять независимые потоки анимации на одном элементе.

Velocity(element, { translateX: 100 }, { duration: 300, queue: "fx" });
Velocity(element, { translateY: 100 }, { duration: 300, queue: "fx" });

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

Velocity(element, { opacity: 0.3 }, { queue: "fade", duration: 200 });
Velocity(element, { opacity: 1 }, { queue: "fade", duration: 200 });

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

Последовательные цепочки и связывание вызовов

Velocity.js поддерживает цепочки вызовов, где каждая следующая анимация автоматически следует за предыдущей:

Velocity(element, { left: 100 }, { duration: 300 })
    .then(() => Velocity(element, { top: 100 }, { duration: 300 }))
    .then(() => Velocity(element, { left: 0 }, { duration: 300 }));

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

Promise-интерфейс и синхронизация

Каждый вызов Velocity возвращает объект, поддерживающий .promise(), который резолвится после завершения анимации.

Velocity(element, { opacity: 0 }, { duration: 300 }).promise().then(() => {
    Velocity(element, { opacity: 1 }, { duration: 300 });
});

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

Управление конкурентными анимациями

При одновременном запуске нескольких анимаций на одном элементе возможны конфликты состояний. Velocity.js решает это через внутреннюю систему приоритизации очередей.

Velocity(element, { width: 500 }, { duration: 400 });
Velocity(element, { width: 200 }, { duration: 400, queue: false });

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

Прерывание и очистка очереди

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

Velocity(element, "stop");

Остановка прерывает текущую анимацию, сохраняя текущее состояние элементов.

Более жёсткий вариант:

Velocity(element, "finish");

В этом случае все анимации немедленно доводятся до конечного состояния, включая те, что находятся в очереди.

Пауза и возобновление выполнения

Очередь может быть приостановлена и возобновлена:

Velocity(element, "pause");
Velocity(element, "resume");

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

Согласование очередей в группах элементов

При работе с коллекциями DOM-элементов каждая сущность имеет собственную очередь исполнения. Однако Velocity синхронизирует запуск, если используется групповой вызов:

Velocity(document.querySelectorAll(".box"), { opacity: 0 }, { duration: 300 });

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

Последовательные сценарии через RunSequence

Для сложных сценариев используется структурированное описание шагов:

Velocity.RunSequence([
    { elements: element, properties: { translateX: 100 }, options: { duration: 300 } },
    { elements: element, properties: { translateY: 100 }, options: { duration: 300 } },
    { elements: element, properties: { opacity: 0 }, options: { duration: 300 } }
]);

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

Влияние задержек на очередь

Задержка внутри анимации добавляет временной слот в очередь исполнения:

Velocity(element, { opacity: 0 }, { duration: 300, delay: 200 });

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

Приоритеты и поведение при перегрузке очереди

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

Velocity(element, "stop", true);

Жёсткая остановка очищает текущие и ожидающие анимации, предотвращая накопление устаревших состояний интерфейса.

Комбинирование очередей и параллельных эффектов

Сочетание очередных и неочередных анимаций позволяет строить гибридные модели поведения интерфейса:

Velocity(element, { scale: 1.2 }, { duration: 300 });
Velocity(element, { rotateZ: 360 }, { duration: 600, queue: false });
Velocity(element, { opacity: 0.5 }, { duration: 300 });

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