Частые проблемы и решения

Ошибка: сцена не запускается, а события не срабатывают. Причины:

  • Скрипт подключён до загрузки DOM. ScrollMagic требует, чтобы элементы, к которым привязываются сцены, были уже в DOM.
  • Неправильный селектор элемента триггера (triggerElement).

Решения:

document.addEventListener('DOMContentLoaded', function() {
    var controller = new ScrollMagic.Controller();
    new ScrollMagic.Scene({
        triggerElement: '#section1'
    })
    .setClassToggle('#section1', 'visible')
    .addTo(controller);
});
  • Проверка селектора через document.querySelector('#section1') перед созданием сцены помогает убедиться, что элемент существует.

Несрабатывание анимаций с GSAP

Ошибка: анимация не запускается или запускается некорректно.

Причины:

  • Не подключена библиотека GSAP.
  • Анимация создаётся до того, как элемент стал видимым или добавлен в DOM.
  • Конфликт нескольких анимаций на одном элементе.

Решения:

  • Всегда проверять наличие GSAP перед использованием:
if (typeof gsap !== 'undefined') {
    gsap.to("#box", { duration: 1, x: 100 });
}
  • Использовать метод setTween внутри сцены:
var controller = new ScrollMagic.Controller();
var tween = gsap.to("#box", { x: 200, duration: 2 });

new ScrollMagic.Scene({
    triggerElement: "#trigger",
    duration: 300
})
.setTween(tween)
.addTo(controller);
  • Для одновременной работы нескольких анимаций использовать Timeline:
var timeline = gsap.timeline();
timeline.to("#box1", { x: 100 })
        .to("#box2", { y: 50 }, "-=1"); // запускается на 1 секунду раньше

Сцены не реагируют на прокрутку

Ошибка: события enter, leave или update не срабатывают при скролле.

Причины:

  • Прокрутка происходит не по window, а по контейнеру с overflow: scroll.
  • Высота сцены (duration) равна нулю, и событие enter мгновенно срабатывает и уходит.

Решения:

  • Использовать кастомный контейнер для прокрутки:
var controller = new ScrollMagic.Controller({
    vertical: true,
    container: "#scrollContainer"
});
  • Задавать ненулевую длительность сцены, чтобы событие имело эффект:
new ScrollMagic.Scene({
    triggerElement: "#trigger",
    duration: 500
});

Проблемы с responsive-дизайном

Ошибка: сцены работают на одном разрешении, но ломаются при изменении размера окна.

Причины:

  • Сценарии создаются один раз при загрузке, а размеры элементов изменяются при ресайзе.

Решения:

  • Использовать событие resize для пересоздания или обновления сцен:
window.addEventListener('resize', function() {
    controller.update(true); // пересчитывает позиции сцен
});
  • Пересчитать triggerHook и duration при изменении ширины:
scene.duration(window.innerHeight / 2);
scene.triggerHook(0.5);

Конфликты с другими библиотеками

Ошибка: анимации или события ScrollMagic не работают вместе с jQuery или другими скриптами.

Причины:

  • Несовпадение версий GSAP, ScrollMagic и плагинов.
  • Конфликты при одновременном использовании transform CSS в GSAP и сторонних библиотек.

Решения:

  • Проверять совместимые версии: ScrollMagic 2.0.x с GSAP 3.x.
  • Использовать addIndicators для отладки:
scene.addIndicators({name: "Debug Scene"});
  • При работе с jQuery использовать document.ready:
$(document).ready(function() {
    // создание контроллера и сцен
});

Проблемы с производительностью

Симптомы: лаги при скролле, высокая нагрузка на CPU.

Причины:

  • Слишком много сцен одновременно.
  • Анимации с тяжелыми трансформациями.
  • Постоянный вызов событий при прокрутке без throttling/debouncing.

Решения:

  • Минимизировать количество сцен: объединять элементы в одну сцену через timeline.
  • Использовать will-change и GPU-ускорение для CSS-анимаций:
.element {
    will-change: transform, opacity;
}
  • Ограничить частоту обновлений через requestAnimationFrame:
var ticking = false;
window.addEventListener('scroll', function() {
    if (!ticking) {
        requestAnimationFrame(function() {
            controller.update(true);
            ticking = false;
        });
        ticking = true;
    }
});

Проблемы с .setPin()

Ошибка: элемент фиксируется, но ломает поток документа или перекрывает другие элементы.

Причины:

  • Родительский контейнер не имеет position: relative.
  • Высота сцены не совпадает с реальной высотой фиксируемого блока.

Решения:

  • Добавлять position: relative родительскому контейнеру:
.container {
    position: relative;
}
  • Настраивать duration сцены по высоте элемента:
scene.duration(document.querySelector("#pinned").offsetHeight);
  • Для динамического контента использовать пересчет:
scene.refresh();

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