Очередь анимаций в 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.
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. Это позволяет формировать строго детерминированные последовательности, где каждая стадия зависит от завершения предыдущей.
Каждый вызов 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 });
Все элементы получают идентичный набор задач, но фактическое завершение может происходить с небольшими расхождениями в зависимости от производительности рендеринга.
Для сложных сценариев используется структурированное описание шагов:
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 });
В таком подходе масштабирование и прозрачность выполняются последовательно, а вращение происходит независимо, создавая многослойную динамику без блокировки основного потока анимаций.