Stimulus — это легковесный JavaScript-фреймворк, ориентированный на добавление интерактивности к HTML с минимальной структурной перегрузкой. Одной из ключевых возможностей является управление состояниями элементов на странице, включая анимации появления и исчезновения.
Для работы с анимациями создаются контроллеры. Контроллер — это
класс, наследуемый от Stimulus.Controller, который
связывается с DOM-элементом через атрибут data-controller.
Действия элемента (actions) позволяют отслеживать события,
инициирующие анимацию.
Пример базового контроллера:
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["element"];
show() {
this.elementTarget.classList.add("visible");
this.elementTarget.classList.remove("hidden");
}
hide() {
this.elementTarget.classList.add("hidden");
this.elementTarget.classList.remove("visible");
}
}
HTML-структура:
<div data-controller="fade">
<div data-fade-target="element" class="hidden">Контент для анимации</div>
<button data-action="click->fade#show">Показать</button>
<button data-action="click->fade#hide">Скрыть</button>
</div>
Stimulus сам по себе не реализует анимации, но отлично интегрируется с CSS-переходами. Для появления и исчезновения элементов применяются классы:
.hidden {
opacity: 0;
transition: opacity 0.5s ease-out;
pointer-events: none;
}
.visible {
opacity: 1;
transition: opacity 0.5s ease-in;
}
transition обеспечивает плавное изменение свойств, а
управление классами через контроллер запускает анимацию.
Ключевой момент: разделение логики отображения
(JavaScript) и анимации (CSS) повышает гибкость и упрощает
поддержку.
Часто требуется не только скрыть элемент визуально, но и удалить его
из DOM после завершения анимации. Для этого используется событие
transitionend:
hide() {
this.elementTarget.classList.add("hidden");
this.elementTarget.addEventListener("transitionend", () => {
this.elementTarget.remove();
}, { once: true });
}
Использование { once: true } гарантирует, что обработчик
сработает один раз и автоматически удалится, предотвращая утечки
памяти.
Stimulus предоставляет методы жизненного цикла контроллера. Метод
connect() вызывается при инициализации контроллера, что
позволяет запускать анимацию при появлении элемента на странице:
connect() {
this.elementTarget.classList.add("hidden");
requestAnimationFrame(() => {
this.elementTarget.classList.add("visible");
this.elementTarget.classList.remove("hidden");
});
}
requestAnimationFrame обеспечивает корректное
срабатывание переходов, гарантируя, что браузер сначала применит
начальное состояние (hidden), а затем плавно перейдет к
visible.
Для создания цепочек анимаций используется сочетание таймеров и
событий transitionend. Например, последовательное появление
нескольких элементов:
showSequence() {
this.elementTargets.forEach((el, index) => {
setTimeout(() => {
el.classList.add("visible");
el.classList.remove("hidden");
}, index * 200); // задержка 200ms между элементами
});
}
В static targets можно определить массив элементов,
которые будут анимироваться в порядке DOM.
Stimulus совместим с библиотеками вроде GSAP или Anime.js, позволяя управлять сложными анимациями через контроллеры:
import { Controller } from "@hotwired/stimulus";
import gsap from "gsap";
export default class extends Controller {
static targets = ["element"];
show() {
gsap.to(this.elementTarget, { opacity: 1, y: 0, duration: 0.5 });
}
hide() {
gsap.to(this.elementTarget, { opacity: 0, y: -20, duration: 0.5 });
}
}
Преимущество такого подхода — точный контроль над временными кривыми и эффектами, недоступными стандартным CSS.
connect(), disconnect() и
initialize() позволяют запускать и останавливать анимации
корректно.{ once: true } или
удалять слушатели в disconnect().Stimulus обеспечивает структурированное и легковесное управление анимациями, позволяя создавать как простые появления/исчезновения, так и сложные интерактивные последовательности без избыточного кода.