В основе работы Velocity.js лежит концепция управляемого запуска анимаций через внешние события и внутренние состояния элементов. Триггер в контексте Velocity — это механизм, который инициирует выполнение анимационного сценария в ответ на действие пользователя, изменение состояния DOM или программное событие.
Velocity интегрируется с DOM-событиями напрямую, позволяя привязывать анимации к любым стандартным событиям браузера. Наиболее распространённый подход — запуск анимации в обработчике события:
Базовая идея заключается в том, что анимация не существует сама по себе — она всегда привязана к моменту времени, который определяется внешним сигналом.
element.addEventListener("click", () => {
Velocity(element, { opacity: 0, translateY: 20 }, { duration: 300 });
});
Такой подход превращает анимацию в реактивный слой интерфейса, где DOM-события выступают первичными триггерами.
Помимо стандартных событий, часто используются кастомные события, позволяющие отделить логику UI от логики управления анимацией. Это особенно важно при сложных интерфейсах, где один и тот же анимационный сценарий может запускаться из разных мест.
element.addEventListener("openModal", () => {
Velocity(element, "fadeIn", { duration: 200 });
});
document.dispatchEvent(new CustomEvent("openModal"));
Такой подход формирует событийную архитектуру, в которой анимации становятся реакцией на бизнес-события, а не на действия конкретных элементов.
Одним из частых триггеров выступает наведение курсора. В отличие от CSS-псевдоклассов, Velocity позволяет управлять более сложной логикой и динамическими параметрами анимации.
element.addEventListener("mouseenter", () => {
Velocity(element, { scale: 1.1 }, { duration: 150 });
});
element.addEventListener("mouseleave", () => {
Velocity(element, { scale: 1 }, { duration: 150 });
});
Подобная модель обеспечивает точный контроль над состояниями интерфейса, включая ускорение, замедление и отмену анимации при изменении направления взаимодействия.
Триггеры не всегда связаны с пользователем. Часто анимации инициируются программно в ответ на логику приложения. Это особенно важно в последовательных интерфейсах: модальные окна, мастера шагов, динамические панели.
Velocity(element, { width: "100%" }, {
duration: 400,
complete: () => {
Velocity(element, { opacity: 1 }, { duration: 200 });
}
});
Здесь завершение одной анимации становится триггером для следующей. Такая цепочная модель позволяет строить сложные сценарии без внешнего управления таймингами.
Velocity предоставляет встроенные хуки жизненного цикла анимации, которые выступают внутренними триггерами:
Velocity(element, { translateX: 200 }, {
duration: 500,
begin: () => {
element.classList.add("is-animating");
},
complete: () => {
element.classList.remove("is-animating");
}
});
Эти точки позволяют синхронизировать анимацию с состоянием интерфейса, управляя визуальной и логической согласованностью.
Каждый элемент в Velocity имеет очередь анимаций, которая влияет на то, как триггеры накладываются друг на друга. Повторный запуск анимации может либо прервать текущую, либо встать в очередь.
Velocity(element, { opacity: 0.5 }, { queue: true });
Velocity(element, { translateY: 50 }, { queue: true });
Контроль очереди позволяет создавать предсказуемые цепочки триггеров, где каждый следующий шаг зависит от завершения предыдущего.
Изменение состояния анимации само по себе может выступать триггером. Остановка текущего процесса и запуск нового сценария используется в интерактивных интерфейсах.
Velocity(element, "stop", true);
Velocity(element, { opacity: 1 }, { duration: 200 });
Такая модель применяется при быстрых пользовательских взаимодействиях, когда новые события должны мгновенно переопределять старые анимации.
В сложных DOM-структурах используется делегирование, позволяющее привязывать триггеры не к отдельным элементам, а к контейнерам. Это снижает нагрузку и упрощает управление динамическими элементами.
container.addEventListener("click", (e) => {
if (e.target.matches(".item")) {
Velocity(e.target, { scale: 0.9 }, { duration: 100 });
}
});
Такой подход особенно важен для списков, таблиц и динамически создаваемых компонентов.
Триггеры могут зависеть от состояния приложения. Анимация запускается только при выполнении определённых условий, что позволяет связывать визуальные эффекты с логикой данных.
if (isActive) {
Velocity(element, { opacity: 1 }, { duration: 300 });
} else {
Velocity(element, { opacity: 0.3 }, { duration: 300 });
}
Подобная модель превращает анимацию в часть состояния интерфейса, а не просто визуальный эффект.
На практике часто используется комбинация нескольких типов триггеров: пользовательские события, программные вызовы и внутренние хуки. Это позволяет строить сложные взаимодействия, где один и тот же элемент реагирует на разные источники сигналов.
function activate(element) {
Velocity(element, { scale: 1.2 }, { duration: 200 });
}
element.addEventListener("mouseenter", () => activate(element));
element.addEventListener("focus", () => activate(element));
document.addEventListener("activateItem", () => activate(element));
Такая архитектура делает поведение интерфейса предсказуемым и расширяемым, сохраняя единый механизм управления анимациями через триггеры.