Пиннинг секций

Пиннинг (pinning) в библиотеке ScrollMagic позволяет закреплять элементы на экране при прокрутке, создавая эффект «залипания» контента. Это особенно полезно для создания интерактивных секций, параллакс-эффектов и анимаций, которые должны оставаться видимыми на определённый промежуток времени.

Создание сцены с пиннингом

Для пиннинга необходим объект Scene. Основная структура выглядит следующим образом:

var controller = new ScrollMagic.Controller();

var scene = new ScrollMagic.Scene({
    triggerElement: "#section", // Элемент, при котором начнется пиннинг
    duration: 500,              // Длительность пиннинга в пикселях
    triggerHook: 0              // Позиция триггера (0 — верх окна)
})
.setPin("#section")             // Элемент, который будет закреплен
.addTo(controller);

Пояснение ключевых параметров:

  • triggerElement — HTML-элемент, при достижении которого начинается пиннинг.
  • duration — длина прокрутки, на протяжении которой элемент будет закреплён. Может задаваться в пикселях или как процент от высоты окна.
  • triggerHook — точка на экране, где срабатывает триггер. Значение от 0 до 1: 0 — верх экрана, 0.5 — центр, 1 — низ.
  • .setPin() — метод, закрепляющий элемент. Можно передавать объект options, например {pushFollowers: false}, чтобы элементы ниже не смещались автоматически.

Push followers и фиксирование соседних элементов

По умолчанию ScrollMagic смещает все последующие элементы вниз, чтобы освободить место для закреплённого блока. Это поведение управляется опцией pushFollowers:

.setPin("#section", { pushFollowers: false });
  • pushFollowers: true (по умолчанию) — элементы после пинна будут сдвинуты вниз на время закрепления.
  • pushFollowers: false — элементы не будут смещаться; это полезно для наложения слоев и параллакс-эффектов.

Пиннинг с анимациями

Часто пиннинг используется совместно с анимациями через GSAP или встроенные методы ScrollMagic. Пример с анимацией изменения прозрачности:

var tween = gsap.to("#section", {opacity: 0, duration: 1});

var scene = new ScrollMagic.Scene({
    triggerElement: "#section",
    duration: 500,
    triggerHook: 0
})
.setPin("#section")
.setTween(tween)
.addTo(controller);

В этом примере элемент закрепляется, а его прозрачность плавно уменьшается по мере прокрутки.

Множественные сцены и последовательный пиннинг

Если нужно закрепить несколько секций подряд, каждая получает собственную сцену:

var sections = document.querySelectorAll(".section");

sections.forEach(function(section) {
    new ScrollMagic.Scene({
        triggerElement: section,
        duration: "100%",  // Длительность равна высоте окна
        triggerHook: 0
    })
    .setPin(section)
    .addTo(controller);
});
  • Использование "100%" в качестве duration делает пиннинг адаптивным к размеру окна.
  • Такой подход обеспечивает плавное последовательное закрепление секций при скролле.

Пиннинг внутри контейнера

Иногда требуется закрепить элемент только внутри родительского контейнера, чтобы после его окончания пиннинг прекращался. Для этого можно использовать дополнительные обёртки и ограничивать длительность сцены:

var scene = new ScrollMagic.Scene({
    triggerElement: "#container",
    duration: document.querySelector("#container").offsetHeight - document.querySelector("#section").offsetHeight,
    triggerHook: 0
})
.setPin("#section")
.addTo(controller);
  • duration вычисляется исходя из высоты контейнера минус высота закрепляемого элемента.
  • Это предотвращает «вылет» пинна за пределы родительского блока.

Оптимизация пиннинга

  1. Аппаратное ускорение: добавление transform: translateZ(0) к закреплённым элементам улучшает производительность.
  2. Избегать сложной вложенности: чем больше элементов внутри пинна, тем тяжелее браузеру рендерить.
  3. Использовать CSS для фиксирования фоновых слоёв: если необходимо только визуальное закрепление, иногда лучше заменить JS-пиннинг на position: sticky.

Настройка triggerHook для разных эффектов

  • triggerHook: 0 — закрепление начинается при достижении верхней границы окна.
  • triggerHook: 1 — закрепление начинается, когда элемент касается нижней границы.
  • triggerHook: 0.5 — закрепление начинается по центру окна.

Выбор значения зависит от желаемого эффекта и от того, когда элемент должен «залипать» относительно видимой области.

Пиннинг и адаптивность

На мобильных устройствах длинные пиннинги могут создавать неудобства. ScrollMagic позволяет отключать сцены по условию ширины экрана:

if(window.innerWidth > 768) {
    new ScrollMagic.Scene({
        triggerElement: "#section",
        duration: 500,
        triggerHook: 0
    })
    .setPin("#section")
    .addTo(controller);
}

Таким образом, закрепление работает только на десктопной версии сайта, а на мобильных устройствах элементы скроллятся стандартно.

Сложные эффекты с несколькими пинами

Для создания сложных параллакс-сцен или анимаций нескольких слоёв одновременно используется несколько сцен с различными triggerElement, duration и triggerHook. Их можно синхронизировать с общей анимацией GSAP:

var tl = gsap.timeline();

tl.to("#layer1", {y: -100, duration: 1})
  .to("#layer2", {y: -200, duration: 1}, 0); // одновременная анимация

var scene = new ScrollMagic.Scene({
    triggerElement: "#section",
    duration: 600,
    triggerHook: 0
})
.setPin("#section")
.setTween(tl)
.addTo(controller);

Такой подход позволяет создавать визуально богатые и интерактивные страницы с множеством слоёв, закрепляющихся и анимирующихся синхронно.

Пиннинг в ScrollMagic — это мощный инструмент для управления видимостью элементов и создания динамических пользовательских интерфейсов при прокрутке. Правильная настройка duration, triggerHook и опции pushFollowers позволяет добиться как простого закрепления, так и сложных анимационных эффектов.