GSAP (GreenSock Animation Platform) предоставляет мощные инструменты для анимации элементов в веб-приложениях. При работе с компонентной архитектурой, такой как React, Vue или Svelte, анимации GSAP интегрируются напрямую в жизненный цикл компонентов, обеспечивая управляемое и производительное взаимодействие с DOM.
Для начала необходимо импортировать библиотеку:
import { gsap } from "gsap";
В компонентной архитектуре важно работать с рефами
элементов, чтобы GSAP мог напрямую управлять DOM-узлами.
Например, в React используется useRef:
import { useRef, useEffect } from "react";
function Box() {
const boxRef = useRef(null);
useEffect(() => {
gsap.to(boxRef.current, { x: 200, duration: 2 });
}, []);
return <div ref={boxRef} className="box"></div>;
}
Ключевой момент: GSAP работает с конкретными DOM-элементами, поэтому важно гарантировать, что элемент существует на момент вызова анимации.
Для создания плавных переходов при появлении и исчезновении компонентов используется эффект монтирования/размонтирования.
import { useRef, useEffect } from "react";
import { gsap } from "gsap";
function FadeInOut({ isVisible }) {
const elementRef = useRef(null);
useEffect(() => {
if (isVisible) {
gsap.to(elementRef.current, { opacity: 1, duration: 0.5 });
} else {
gsap.to(elementRef.current, { opacity: 0, duration: 0.5 });
}
}, [isVisible]);
return <div ref={elementRef} style={{ opacity: 0 }}>Контент</div>;
}
Использование useEffect с зависимостью позволяет
реагировать на изменение состояния компонента. Анимации можно
комбинировать с Timeline, чтобы создавать
последовательные эффекты.
GSAP Timeline обеспечивает управление несколькими
анимациями в рамках одного компонента. Это особенно полезно для создания
сложных эффектов при рендеринге:
import { useRef, useEffect } from "react";
import { gsap } from "gsap";
function AnimatedCard() {
const cardRef = useRef(null);
useEffect(() => {
const tl = gsap.timeline({ defaults: { duration: 0.5, ease: "power1.out" } });
tl.from(cardRef.current, { y: -50, opacity: 0 })
.to(cardRef.current, { rotation: 10 })
.to(cardRef.current, { rotation: 0 });
}, []);
return <div ref={cardRef} className="card">Карточка</div>;
}
Преимущества Timeline:
GSAP отлично сочетается с событиями пользовательского интерфейса. Например, можно создать анимацию при наведении:
function HoverButton() {
const buttonRef = useRef(null);
useEffect(() => {
const el = buttonRef.current;
const hoverAnim = gsap.to(el, { scale: 1.2, paused: true, duration: 0.3 });
const handleMouseEnter = () => hoverAnim.play();
const handleMouseLeave = () => hoverAnim.reverse();
el.addEventListener("mouseenter", handleMouseEnter);
el.addEventListener("mouseleave", handleMouseLeave);
return () => {
el.removeEventListener("mouseenter", handleMouseEnter);
el.removeEventListener("mouseleave", handleMouseLeave);
};
}, []);
return <button ref={buttonRef}>Наведите на меня</button>;
}
Ключевой момент: использование paused анимации позволяет управлять воспроизведением анимации без повторного создания объектов.
В компонентах, где содержимое генерируется динамически, необходимо применять GSAP после рендеринга элементов. Например, для списка:
function ItemList({ items }) {
const listRef = useRef([]);
useEffect(() => {
gsap.from(listRef.current, {
y: 20,
opacity: 0,
stagger: 0.1,
duration: 0.5
});
}, [items]);
return (
<ul>
{items.map((item, index) => (
<li key={item.id} ref={el => (listRef.current[index] = el)}>
{item.text}
</li>
))}
</ul>
);
}
Особенности работы с динамическими списками:
stagger легко создавать каскадные эффекты.GSAP оптимизирован для высокой производительности, но при работе с компонентами есть несколько правил:
transform и opacity, так как
они GPU-ускорены.Timeline, вместо
пересоздания анимаций на каждый рендер.GSAP может сочетаться с любыми состояниями компонента, включая анимацию при изменении данных:
function Counter() {
const [count, setCount] = useState(0);
const counterRef = useRef(null);
useEffect(() => {
gsap.fromTo(counterRef.current, { scale: 1 }, { scale: 1.3, duration: 0.2, yoyo: true, repeat: 1 });
}, [count]);
return (
<div>
<span ref={counterRef}>{count}</span>
<button onCl ick={() => setCount(prev => prev + 1)}>Увеличить</button>
</div>
);
}
Такой подход обеспечивает реактивность анимаций, позволяя визуально подчеркнуть изменения данных.
Эта методика позволяет глубоко интегрировать GSAP с компонентами, обеспечивая плавные, управляемые и производительные анимации в современных веб-приложениях.