Освобождение закрепленных элементов

В ScrollMagic закрепление элементов (pinning) позволяет фиксировать DOM-элемент на экране на определённый промежуток времени во время прокрутки страницы. Закреплённый элемент остаётся видимым и неподвижным относительно окна просмотра, пока сцена, к которой он привязан, активна. Для закрепления используется метод .setPin() объекта сцены.

const controller = new ScrollMagic.Controller();

const scene = new ScrollMagic.Scene({
    triggerElement: "#section1",
    duration: 300
})
.setPin("#pinElement")
.addTo(controller);

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

  • triggerElement — элемент, при появлении которого начинается сцена.
  • duration — длина сцены в пикселях, в течение которой элемент будет закреплён.
  • Метод .setPin() принимает селектор или DOM-элемент.
  • Элемент закрепляется по умолчанию в начале сцены.

Автоматическое освобождение элемента

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

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

Программное снятие закрепления

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

scene.removePin(true);

Параметры:

  • reset — логическое значение. Если true, ScrollMagic возвращает элемент в исходное положение на странице. Если false, элемент остаётся на месте в момент удаления закрепления.

Переход между закреплением и свободным состоянием

Можно динамически изменять закрепление во время прокрутки, создавая несколько сцен для одного элемента. Пример:

const scene1 = new ScrollMagic.Scene({
    triggerElement: "#startPin",
    duration: 200
})
.setPin("#dynamicPin")
.addTo(controller);

const scene2 = new ScrollMagic.Scene({
    triggerElement: "#endPin"
})
.on("enter", function() {
    scene1.removePin();
})
.addTo(controller);
  • scene1 закрепляет элемент на 200px прокрутки.
  • scene2 снимает закрепление при достижении следующего триггерного элемента.
  • Такой подход позволяет управлять положением элементов на странице в зависимости от контекста.

Совместимость с анимациями

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

const tween = gsap.to("#pinElement", { y: 200, duration: 1 });

const scene = new ScrollMagic.Scene({
    triggerElement: "#section1",
    duration: 400
})
.setTween(tween)
.setPin("#pinElement")
.addTo(controller);
  • Анимация происходит во время закрепления.
  • После снятия pin элемент возвращается в исходное положение, если не указан параметр pushFollowers: false.

Учет размеров и layout

Закрепление элемента может повлиять на layout страницы:

  • Элемент, закреплённый без pushFollowers, может перекрывать контент.
  • Элемент с pushFollowers: true сохраняет пространство, но может требовать корректировки высоты контейнера для плавной прокрутки.
  • Важно учитывать margin, padding и абсолютное позиционирование закрепляемого элемента.

Особенности освобождения при динамическом контенте

Если контент страницы изменяется после создания сцены (например, добавляются изображения или блоки), важно обновлять сцены через controller.update():

controller.update(true);

Это позволяет ScrollMagic пересчитать размеры сцены и правильно управлять закреплением и освобождением элементов.

События, связанные с закреплением

ScrollMagic предоставляет события, которые помогают отслеживать состояние pin:

  • pin — вызывается при закреплении элемента.
  • unpin — вызывается при освобождении элемента.
  • Использование событий позволяет запускать дополнительные эффекты или синхронизировать другие анимации.
scene.on("pin", function() {
    console.log("Элемент закреплён");
});
scene.on("unpin", function() {
    console.log("Элемент освобождён");
});

Эти события особенно полезны при сложных интерфейсах с множественными закрепленными блоками, когда важно точно знать момент закрепления и освобождения для синхронизации анимаций и контента.