Pin для фиксации элементов

GSAP (GreenSock Animation Platform) предоставляет мощные возможности для анимации веб-элементов, а одна из ключевых функций в комбинации с ScrollTrigger — фиксация элементов на странице, или Pin. Pin позволяет закреплять элемент в определённой позиции в течение заданного диапазона прокрутки, создавая эффект “прилипшей” панели, с которой можно взаимодействовать во время скролла.

Синтаксис Pin

Pin реализуется через объект конфигурации ScrollTrigger. Основная структура выглядит следующим образом:

gsap.to(".element", {
  scrollTrigger: {
    trigger: ".element",
    start: "top top",
    end: "bottom top",
    pin: true,
    scrub: 1
  },
  x: 500,
  rotation: 360
});

Ключевые моменты:

  • trigger — элемент, относительно которого будет происходить фиксация.
  • start и end — позиции скролла, при которых начинается и заканчивается эффект закрепления. Можно использовать процентные значения, пиксели и ключевые позиции (top, center, bottom).
  • pin: true — активирует фиксацию элемента.
  • scrub — синхронизация анимации с прокруткой. Значение 1 создаёт плавное “растягивание” анимации на протяжении скролла.

Настройка Pin с отступами и внутренними элементами

Pin не всегда должен фиксировать элемент без изменений размера. Можно задавать дополнительные параметры:

gsap.to(".section", {
  scrollTrigger: {
    trigger: ".section",
    start: "top 20%",
    end: "bottom 80%",
    pin: true,
    pinSpacing: false
  },
  opacity: 0.5
});
  • pinSpacing — по умолчанию true, создаёт дополнительный отступ, чтобы страница не “прыгала”. Установка в false отключает этот отступ, позволяя анимировать элементы без влияния на поток документа.
  • Использование процентов в start и end позволяет гибко управлять моментом фиксации относительно видимой области.

Pin с динамическими размерами и nested элементы

Для сложных макетов часто нужно фиксировать родительский элемент, оставляя внутренние элементы анимированными:

gsap.to(".inner-box", {
  scrollTrigger: {
    trigger: ".outer-box",
    start: "top top",
    end: "+=1000",
    pin: ".outer-box",
    scrub: 2
  },
  y: 300
});
  • Pin может быть привязан не к самому элементу триггера, а к другому элементу с помощью строки селектора.
  • end: "+=1000" задаёт фиксацию на фиксированную длину скролла, что удобно для длинных анимаций.

Анимации нескольких pinned элементов

Когда на странице несколько элементов с pin, важно учитывать контекст скролла:

gsap.utils.toArray(".panel").forEach(panel => {
  gsap.to(panel.querySelector(".content"), {
    scrollTrigger: {
      trigger: panel,
      start: "top top",
      end: "bottom top",
      pin: true,
      scrub: true
    },
    x: 200
  });
});
  • Использование gsap.utils.toArray упрощает создание одинаковых эффектов для нескольких блоков.
  • Каждое pin создаёт свой отдельный ScrollTrigger, что предотвращает конфликты между элементами.
  • Pin работает корректно с анимациями внутри секций, даже если они расположены горизонтально или имеют разные размеры.

Advanced: Pin с адаптивной высотой

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

ScrollTrigger.addEventListener("refreshInit", () => {
  gsap.set(".adaptive-box", {height: "auto"});
});

gsap.to(".adaptive-box", {
  scrollTrigger: {
    trigger: ".adaptive-box",
    start: "top top",
    end: "bottom+=200 top",
    pin: true,
    markers: true
  },
  backgroundColor: "#ff0000"
});
  • Событие refreshInit позволяет пересчитывать размеры перед фиксацией, предотвращая смещения.
  • markers: true — отладочный инструмент для визуального контроля зон start/end.

Рекомендации по использованию Pin

  1. Не злоупотреблять: слишком много pinned элементов создают перегруженную прокрутку.
  2. Scrub + Pin создают плавные эффекты привязки анимации к скроллу.
  3. Использовать pinSpacing: false при сложной верстке, чтобы предотвратить лишние отступы.
  4. При адаптивных интерфейсах обновлять ScrollTrigger при изменении размеров экрана через ScrollTrigger.refresh().

Pin в GSAP — это мощный инструмент для создания интерактивных и динамичных интерфейсов, когда элементы остаются на экране и реагируют на прокрутку. С правильной настройкой start, end, pinSpacing и scrub можно добиться плавных, профессиональных эффектов фиксации.