Фиксированное меню

Фиксированное меню является распространённым элементом интерфейса, который остаётся видимым при прокрутке страницы. С помощью ScrollMagic можно управлять поведением меню и создавать динамические эффекты появления, фиксации и скрытия при скролле.


Настройка окружения

Для работы с ScrollMagic необходимо подключить библиотеку и её зависимости:

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/ScrollMagic.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/animation.gsap.min.js"></script>
  • gsap.min.js — библиотека для анимаций, используется вместе с ScrollMagic.
  • ScrollMagic.min.js — основной скрипт библиотеки.
  • animation.gsap.min.js — плагин для интеграции с GSAP-анимациями.

Инициализация ScrollMagic Controller

Controller управляет всеми сценами на странице:

const controller = new ScrollMagic.Controller();

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


Создание сцены для фиксирования меню

Основная логика фиксации меню реализуется через ScrollMagic.Scene. Пример:

const menu = document.querySelector('.menu');

const scene = new ScrollMagic.Scene({
    triggerElement: '#trigger', // элемент, с которого начинается фиксация
    triggerHook: 0,             // верх страницы (0 — начало, 1 — конец)
    duration: 300               // длина действия сцены в пикселях
})
.setPin(menu)                   // фиксирование элемента
.addTo(controller);             // добавление сцены в контроллер
  • triggerElement определяет точку, при которой начинается сцена.
  • triggerHook управляет положением триггера на экране.
  • duration задаёт, на какой длине прокрутки меню остаётся закреплённым.
  • setPin фиксирует выбранный элемент.

Анимация появления и скрытия меню

Для более плавного поведения меню можно добавить GSAP-анимацию:

const tween = gsap.fromTo(menu, 
    { y: -100, opacity: 0 }, 
    { y: 0, opacity: 1, duration: 0.5 }
);

const sceneWithAnimation = new ScrollMagic.Scene({
    triggerElement: '#trigger',
    triggerHook: 0
})
.setTween(tween)
.addTo(controller);
  • gsap.fromTo позволяет задавать начальное и конечное состояние.
  • Анимация запускается автоматически при достижении триггера сцены.

Комбинирование фиксации и анимации

Можно объединить setPin и анимацию в одной сцене для комплексного эффекта:

const combinedScene = new ScrollMagic.Scene({
    triggerElement: '#trigger',
    triggerHook: 0,
    duration: 400
})
.setPin(menu)
.setTween(gsap.to(menu, { backgroundColor: '#333', duration: 0.5 }))
.addTo(controller);
  • Меню фиксируется и одновременно изменяет стиль (например, фон) при прокрутке.
  • Можно комбинировать несколько tween для последовательной анимации.

Адаптация под разные экраны

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

if (window.innerWidth < 768) {
    scene.destroy(); // отключение фиксации на маленьких экранах
}
  • Можно создавать отдельные сцены для мобильных и десктопных версий.
  • ScrollMagic учитывает высоту окна при расчётах триггеров.

Примеры расширенных эффектов

  1. Меню появляется после прокрутки вниз на N пикселей:
new ScrollMagic.Scene({
    triggerElement: 'body',
    offset: 200, // меню появится после 200px прокрутки
    triggerHook: 0
})
.setClassToggle(menu, 'visible') // добавление класса CSS
.addTo(controller);
  1. Меню исчезает при прокрутке вверх:
let lastScroll = 0;
window.addEventListener('scroll', () => {
    const current = window.scrollY;
    if (current > lastScroll) {
        menu.classList.add('hidden');
    } else {
        menu.classList.remove('hidden');
    }
    lastScroll = current;
});
  • Сочетание ScrollMagic и нативного JS позволяет создавать сложные интерактивные интерфейсы.

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

  • Использовать setPin только для важных элементов, так как это влияет на рендер страницы.
  • Минимизировать количество сцен на странице.
  • Для тяжелых анимаций предпочтительнее применять CSS-трансформации (transform, opacity) вместо изменения top, left и height.

Практические советы

  • Всегда задавать triggerElement даже при простом фиксировании, иначе сцена не сработает корректно.
  • Использовать классы CSS для изменения внешнего вида вместо постоянной анимации свойств.
  • Проверять поведение на разных разрешениях и учитывать вертикальные размеры контента, чтобы меню не “прыгало” при прокрутке.

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