Использование в компонентах

GSAP (GreenSock Animation Platform) предоставляет мощные инструменты для анимации элементов в веб-приложениях. При работе с компонентной архитектурой, такой как React, Vue или Svelte, анимации GSAP интегрируются напрямую в жизненный цикл компонентов, обеспечивая управляемое и производительное взаимодействие с DOM.

Подключение GSAP к компоненту

Для начала необходимо импортировать библиотеку:

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, чтобы создавать последовательные эффекты.


Работа с 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 легко создавать каскадные эффекты.
  • Анимации запускаются после рендера, что предотвращает ошибки с отсутствующими элементами в DOM.

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

GSAP оптимизирован для высокой производительности, но при работе с компонентами есть несколько правил:

  1. Минимизировать количество одновременно анимируемых элементов.
  2. Использовать transform и opacity, так как они GPU-ускорены.
  3. Создавать и повторно использовать Timeline, вместо пересоздания анимаций на каждый рендер.
  4. Удалять слушатели событий при размонтировании компонента.

Интеграция с хуками состояния

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 с компонентами, обеспечивая плавные, управляемые и производительные анимации в современных веб-приложениях.