Управление очередями

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

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


Базовый механизм очереди

Каждый вызов Velocity() на одном DOM-элементе добавляется в внутреннюю очередь:

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

Поведение по умолчанию:

  • первая анимация запускается немедленно
  • последующие ожидают завершения предыдущих
  • порядок выполнения строго соответствует порядку вызовов

Очередь реализуется на уровне каждого элемента отдельно, что позволяет параллельно управлять множеством независимых DOM-узлов.


Параметр queue

Управление поведением очереди осуществляется через параметр queue.

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

Velocity(element, { opacity: 0.5 }, { queue: false });

Особенности:

  • анимация запускается немедленно
  • не блокирует последующие вызовы
  • выполняется параллельно с другими анимациями

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


Явное именование очереди

Velocity.js поддерживает именованные очереди:

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

Свойства:

  • каждая очередь существует независимо
  • можно формировать несколько потоков анимаций
  • выполнение внутри очереди остаётся последовательным

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

Цепочки анимаций формируются автоматически через очередь:

Velocity(element, { width: 100 }, { duration: 300 });
Velocity(element, { height: 100 }, { duration: 300 });
Velocity(element, { opacity: 0 }, { duration: 300 });

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

Для более сложных сценариев используется chaining через возврат Velocity:

Velocity(element, { x: 100 })
    .then(() => Velocity(element, { y: 100 }))
    .then(() => Velocity(element, { rotateZ: 180 }));

Параллельные и смешанные сценарии

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

Velocity(element, { opacity: 1 });
Velocity(element, { translateX: 200 }, { queue: false });
Velocity(element, { rotateZ: 90 }, { queue: false });

Характер поведения:

  • opacity изменяется последовательно
  • transform-анимации выполняются одновременно
  • очереди не блокируют друг друга

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


Очистка очереди

Velocity предоставляет управление накопленными анимациями через очистку очереди.

Velocity.Utilities.dequeue(element);

или через jQuery-совместимый интерфейс:

$(element).clearQueue();

Основные эффекты:

  • удаление ожидающих анимаций
  • сохранение текущей выполняемой анимации
  • предотвращение накопления устаревших вызовов

Очистка очереди критична при динамическом изменении UI, где предыдущие анимации теряют актуальность.


Остановка и принудительное завершение

Остановка текущей анимации

Velocity(element, "stop");

Поведение:

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

Полное завершение очереди

Velocity(element, "finish");

Характеристики:

  • мгновенный переход к конечному состоянию
  • выполнение всех queued-анимаций сразу
  • очистка внутренней очереди после завершения

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


Управление очередями на уровне нескольких элементов

При работе с группами элементов каждая очередь независима:

Velocity([el1, el2, el3], { opacity: 0.5 });
Velocity([el1, el2, el3], { translateX: 100 });

Поведение:

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

Взаимодействие queue и duration

Очередь влияет не только на порядок, но и на восприятие длительности сценария:

Velocity(element, { width: 200 }, { duration: 200 });
Velocity(element, { width: 300 }, { duration: 400 });

Суммарное время анимационного сценария равно сумме всех длительностей в очереди.

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

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

временная модель становится параллельной, и итоговая длительность определяется самой длинной анимацией.


Контроль через begin, complete и progress

Очередь тесно связана с колбэками жизненного цикла:

Velocity(element, {
    opacity: 0
}, {
    begin: function () {
        // старт анимации
    },
    complete: function () {
        // завершение шага очереди
    },
    progress: function () {
        // прогресс текущего шага
    }
});

Особенности:

  • begin вызывается при старте каждого шага очереди
  • complete срабатывает после завершения конкретной анимации
  • progress обновляется в процессе выполнения

Приоритет очередей и вложенные сценарии

Использование нескольких очередей позволяет создавать приоритетные слои анимаций:

Velocity(element, { x: 100 }, { queue: "background" });
Velocity(element, { x: 200 }, { queue: "foreground" });

Поведение:

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

Сброс состояния очереди

В случаях сложной динамики интерфейса применяется полный сброс:

Velocity(element, "stop", true);

или комбинации:

Velocity(element, "stop");
Velocity.Utilities.dequeue(element);

Результат:

  • остановка текущей анимации
  • удаление ожидающих задач
  • переход в статическое состояние

Паттерны построения анимационных потоков

Линейный поток

Velocity(element, { x: 100 });
Velocity(element, { x: 200 });
Velocity(element, { x: 300 });

Характеристика: строгая последовательность без ветвлений.


Разветвлённый поток

Velocity(element, { opacity: 0.5 });

if (state === "active") {
    Velocity(element, { scale: 1.2 });
} else {
    Velocity(element, { scale: 0.8 });
}

Характеристика: управление очередью через внешнюю логику.


Параллельно-серийная модель

Velocity(element, { rotateZ: 90 }, { queue: false });
Velocity(element, { translateX: 100 });
Velocity(element, { translateY: 100 });

Характеристика:

  • часть анимаций идёт параллельно
  • часть сохраняет строгую последовательность

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

Velocity(element, { x: 100 });
Velocity(element, { x: 200 });

Velocity(element, "stop");
Velocity(element, { x: 50 });

Характеристика: динамическая замена сценария выполнения.


Поведение очереди при быстром повторном вызове

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

for (let i = 0; i < 10; i++) {
    Velocity(element, { x: i * 10 });
}

Результат:

  • формируется цепочка из 10 последовательных шагов
  • итоговое состояние определяется последним вызовом
  • промежуточные состояния сохраняются в очереди до выполнения

При необходимости предотвращения накопления применяется:

Velocity(element, "stop", true);

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

Velocity(element, { x: 100 }, { queue: false });