Медиа-запросы и ScrollMagic

Библиотека ScrollMagic предоставляет возможность управлять анимациями и поведением элементов на странице в зависимости от положения скролла. Для создания адаптивных интерфейсов критически важно учитывать размеры экрана и использовать медиа-запросы, чтобы сцены ScrollMagic работали корректно на разных устройствах.

Использование window.matchMedia

Классический подход — использование встроенного API браузера window.matchMedia. Он позволяет определить соответствие текущего размера окна определённому медиа-запросу.

const mq = window.matchMedia("(min-width: 768px)");

if (mq.matches) {
    // Запускаем анимации для экранов >= 768px
} else {
    // Альтернативная логика для мобильных
}

mq.addEventListener("change", (e) => {
    if (e.matches) {
        // Переконфигурируем сцены ScrollMagic для десктопа
    } else {
        // Переконфигурируем сцены для мобильного вида
    }
});

Метод addEventListener("change", …) обеспечивает динамическое реагирование на изменение размера окна без необходимости перезагрузки страницы.


Создание сцен с адаптивной высотой и триггерами

ScrollMagic.Scene позволяет задавать параметры triggerElement, duration и offset. Для адаптивного дизайна полезно изменять эти параметры в зависимости от медиа-запроса.

let scene;

function initScene() {
    const mq = window.matchMedia("(min-width: 1024px)");

    if (mq.matches) {
        scene = new ScrollMagic.Scene({
            triggerElement: "#section1",
            duration: "100%", // 100% высоты окна для десктопа
            offset: 0
        })
        .setPin("#section1")
        .addTo(controller);
    } else {
        scene = new ScrollMagic.Scene({
            triggerElement: "#section1",
            duration: 500, // фиксированная высота для мобильного
            offset: 0
        })
        .addTo(controller);
    }
}

initScene();

При изменении медиа-запроса старую сцену рекомендуется удалять методом scene.destroy() и пересоздавать заново с новыми параметрами, чтобы избежать конфликтов и дублирования эффектов.


Динамическая перестройка сцен

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

function setupScenes() {
    if (scene) {
        scene.destroy(true);
    }

    if (window.matchMedia("(min-width: 1200px)").matches) {
        scene = new ScrollMagic.Scene({
            triggerElement: "#hero",
            duration: window.innerHeight * 2,
        })
        .setPin("#hero")
        .addTo(controller);
    } else {
        scene = new ScrollMagic.Scene({
            triggerElement: "#hero",
            duration: window.innerHeight,
        })
        .addTo(controller);
    }
}

window.addEventListener("resize", setupScenes);
setupScenes();

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


Применение условных анимаций

С помощью медиа-запросов можно не только изменять длительность сцен, но и полностью менять логику анимации.

const mqDesktop = window.matchMedia("(min-width: 1024px)");

if (mqDesktop.matches) {
    new ScrollMagic.Scene({
        triggerElement: "#features",
        duration: 800
    })
    .setTween("#features .item", { x: 200, opacity: 1 })
    .addTo(controller);
} else {
    new ScrollMagic.Scene({
        triggerElement: "#features",
        duration: 400
    })
    .setTween("#features .item", { y: 100, opacity: 1 })
    .addTo(controller);
}

В данном примере для десктопной версии используется горизонтальное смещение, а для мобильной — вертикальное, что позволяет сохранять естественный пользовательский опыт на любых устройствах.


Интеграция с CSS медиа-запросами

Часто полезно сочетать ScrollMagic с CSS медиа-запросами для управления стилями одновременно с Jav * aScript:

/* Десктоп */
@media (min-width: 1024px) {
    #section2 {
        height: 100vh;
    }
}

/* Мобильные устройства */
@media (max-width: 1023px) {
    #section2 {
        height: 50vh;
    }
}

В ScrollMagic можно использовать проверку текущей высоты элемента через offsetHeight или getBoundingClientRect().height, чтобы динамически синхронизировать сцену с CSS-свойствами.


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

  1. Дестрой старых сцен — избегает утечек памяти при смене медиа-запроса.
  2. Throttle/ Debounce на resize — предотвращает чрезмерное создание сцен при динамическом изменении размера окна.
  3. Оптимизация длительности сцен — для мобильных устройств лучше использовать фиксированные короткие длительности, чтобы не перегружать анимацию.
  4. Комбинирование с GSAP — медиа-запросы позволяют подключать разные GSAP-твины для разных экранов через одну ScrollMagic сцену.

Практическая схема адаптивной ScrollMagic-сцены

  1. Создание контроллера:
const controller = new ScrollMagic.Controller();
  1. Определение функций и медиа-запросов:
const isDesktop = window.matchMedia("(min-width: 1024px)").matches;
  1. Создание и конфигурация сцен в зависимости от устройства:
const scene = isDesktop 
    ? createDesktopScene()
    : createMobileScene();
  1. Добавление событий на изменение окна:
window.addEventListener("resize", () => {
    updateScenes();
});

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