Переход с jQuery.animate

Механизм jQuery.animate() основан на внутренней очереди FX, которая обрабатывает изменения CSS-свойств через setInterval/requestAnimationFrame (в зависимости от версии jQuery) и последовательно применяет вычисленные промежуточные значения. Такой подход тесно связан с DOM-обёрткой jQuery и предполагает синхронную модель очередей анимаций.

Velocity.js реализует собственный движок анимаций, который полностью отделён от очередей jQuery и использует высокопроизводительный цикл на основе requestAnimationFrame. Основное отличие заключается в том, что Velocity оптимизирует вычисления, минимизирует forced reflow и поддерживает батчинг изменений стилей.

Ключевая разница проявляется в управлении состоянием:

  • jQuery хранит очередь анимаций внутри каждого DOM-элемента через .queue()
  • Velocity управляет очередями централизованно, вне DOM-структуры
  • jQuery ориентирован на последовательные эффекты
  • Velocity допускает параллельные и групповые анимации без блокировки потока

Базовая замена синтаксиса

Типичный вызов jQuery:

$(".box").animate({
  left: "200px",
  opacity: 0.5
}, 400);

Эквивалент в Velocity.js:

Velocity(document.querySelectorAll(".box"), {
  left: "200px",
  opacity: 0.5
}, {
  duration: 400
});

На уровне API заметно, что Velocity не привязан к jQuery-обёртке. Первый аргумент может быть NodeList, HTMLElement или jQuery-коллекция (если подключен адаптер).


Особенности интерполяции значений

jQuery.animate ограничен набором свойств, которые могут быть анимированы без дополнительных плагинов. В основном это числовые CSS-значения.

Velocity расширяет модель интерполяции:

  • Поддержка transform-свойств (translateX, translateY, scale, rotate)
  • Анимация цвета с интерполяцией RGB/HEX
  • Поддержка сложных easing-функций
  • Возможность анимации SVG-атрибутов

Пример трансформации:

Velocity(element, {
  translateX: "200px",
  rotateZ: "45deg",
  scale: 1.2
}, {
  duration: 600
});

В jQuery подобная задача требует отдельного подключения jQuery UI или ручного управления transform.


Очереди анимаций и управление потоком

jQuery использует встроенную систему очередей:

$(".box")
  .animate({ left: 100 })
  .animate({ top: 100 });

Velocity заменяет очередь на последовательность промисоподобных вызовов через Promise-подобный API или sequence.

Пример последовательной анимации:

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

Также поддерживается queue: false, позволяющий запускать анимации параллельно:

Velocity(element, { left: "100px" }, { queue: false });
Velocity(element, { top: "100px" }, { queue: false });

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

Основное ограничение jQuery.animate() — частые обращения к layout-свойствам DOM, что вызывает reflow. Особенно это заметно при анимации большого количества элементов.

Velocity минимизирует проблему за счёт:

  • Кэширования начальных значений
  • Группировки изменений стилей
  • Использования requestAnimationFrame
  • Оптимизации работы с transform вместо layout-параметров

На практике это даёт стабильные 60 FPS на сценариях, где jQuery начинает деградировать.


Easing-функции и контроль динамики

jQuery поддерживает ограниченный набор easing (например, swing, linear) без дополнительных плагинов.

Velocity включает расширенную систему:

Velocity(element, { opacity: 1 }, {
  duration: 800,
  easing: "easeInOutCubic"
});

Поддерживаются:

  • встроенные математические функции
  • spring-анимации
  • bounce и elastic эффекты
  • кастомные easing-функции через массивы или функции

Пример пользовательского easing:

Velocity.Easings.custom = function (p) {
  return Math.sin(p * Math.PI);
};

Работа с display и visibility

jQuery автоматически управляет display: none/block в методах .show() и .hide().

Velocity предоставляет более явный контроль:

Velocity(element, "fadeIn", { duration: 300 });
Velocity(element, "fadeOut", { duration: 300 });

При этом состояние display сохраняется и восстанавливается корректно без вмешательства разработчика в inline-стили.


Переход от animate() к Velocity: соответствие свойств

jQuery.animate Velocity.js
left, top translateX, translateY
opacity opacity
width, height width, height
toggle fadeIn, fadeOut
hide/show fadeOut / fadeIn
callback then() или complete

Важно учитывать, что Velocity поощряет использование transform вместо изменения геометрии layout, что снижает нагрузку на браузер.


Обработка callback и завершения анимации

jQuery использует callback как третий аргумент:

$(".box").animate({ left: 100 }, 400, function () {
  console.log("done");
});

Velocity использует объект настроек:

Velocity(element, { left: "100px" }, {
  duration: 400,
  complete: function () {
    console.log("done");
  }
});

Также возможно использование Promise-подобного поведения:

Velocity(element, { opacity: 0 }).then(() => {
  // следующая операция
});

Пакетная анимация нескольких элементов

jQuery применяет одинаковую анимацию ко всем элементам коллекции, но не оптимизирует их выполнение как единую задачу.

Velocity обрабатывает коллекции как единый batch:

Velocity(document.querySelectorAll(".item"), {
  opacity: 1,
  translateY: "0px"
}, {
  duration: 500,
  stagger: 100
});

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


Отказ от jQuery.animate в пользу Velocity: структурные изменения

Переход требует пересмотра архитектуры анимаций:

  • отказ от цепочек .animate().delay().animate()
  • перенос логики в явные состояния
  • использование transform вместо layout-изменений
  • разделение UI-логики и анимационного слоя

Пример рефакторинга:

Было (jQuery):

$(".box")
  .animate({ left: 100 }, 300)
  .animate({ top: 100 }, 300)
  .fadeOut(200);

Стало (Velocity):

Velocity(element, { translateX: "100px" }, { duration: 300 })
  .then(() => Velocity(element, { translateY: "100px" }, { duration: 300 }))
  .then(() => Velocity(element, "fadeOut", { duration: 200 }));

Поддержка SVG и нестандартных DOM-атрибутов

jQuery.animate практически не работает с SVG без дополнительных плагинов.

Velocity поддерживает SVG-атрибуты напрямую:

Velocity(svgElement, {
  strokeDashoffset: 0
}, {
  duration: 1000
});

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


Синхронизация состояния и отмена анимаций

jQuery предоставляет .stop():

$(".box").stop(true, true);

Velocity расширяет управление:

Velocity(element, "stop", true);

Также возможна очистка очереди и принудительное завершение текущего состояния.


Итоговая модель перехода

Системная замена jQuery.animate на Velocity.js фактически означает переход от DOM-ориентированной очереди к независимому анимационному движку, где управление состояниями отделено от структуры элементов. Это позволяет снизить связанность кода, повысить предсказуемость анимаций и уменьшить нагрузку на layout-движок браузера.