ScrollMagic — это библиотека для создания эффектов прокрутки,
позволяющая привязывать анимации к положению скролла. Центральным
элементом являются сцены (Scene) и
контроллеры (Controller). Контроллер
управляет всеми сценами на странице, обеспечивая синхронизацию их
поведения с прокруткой.
const controller = new ScrollMagic.Controller();
const scene = new ScrollMagic.Scene({
triggerElement: "#section1", // элемент, при котором сцена активируется
duration: 300, // длина сцены в пикселях
triggerHook: 0.5 // точка срабатывания на экране (0 — верх, 1 — низ)
})
.setClassToggle("#section1", "active") // добавление класса при активации сцены
.addTo(controller);
Ключевые моменты:
triggerElement — элемент, с которого начинается
сцена.duration — длина действия сцены.triggerHook — положение на экране, где сцена считается
активной.setClassToggle и setTween позволяют
запускать анимации и менять стили.При работе с большим числом сцен важно минимизировать дублирование кода. Часто встречается ситуация, когда несколько элементов получают одинаковое поведение. Вместо создания множества сцен вручную, применяют итерацию по элементам:
document.querySelectorAll(".animate").forEach(el => {
new ScrollMagic.Scene({
triggerElement: el,
triggerHook: 0.8
})
.setClassToggle(el, "visible")
.addTo(controller);
});
Преимущества такого подхода:
ScrollMagic тесно интегрируется с библиотекой GSAP, что позволяет задавать сложные анимации. Основная схема:
const tween = gsap.to("#box", { x: 500, rotation: 360, duration: 2 });
const scene = new ScrollMagic.Scene({
triggerElement: "#trigger",
duration: 400
})
.setTween(tween)
.addTo(controller);
Принципы рефакторинга при использовании Tween:
const animations = [
{ el: "#box1", x: 300, rotation: 180 },
{ el: "#box2", x: 500, rotation: 360 },
];
animations.forEach(anim => {
const tween = gsap.to(anim.el, { x: anim.x, rotation: anim.rotation });
new ScrollMagic.Scene({
triggerElement: anim.el,
duration: 300
})
.setTween(tween)
.addTo(controller);
});
Такой подход упрощает управление анимациями и делает код более читабельным.
Обычно на странице создают один контроллер ScrollMagic. Несколько контроллеров создают лишнюю нагрузку и могут приводить к конфликтам. Рекомендуется:
refreshInterval контроллера при динамическом
изменении DOM:const controller = new ScrollMagic.Controller({ refreshInterval: 100 });
scene.destroy() для удаления сцен,
которые больше не нужны.Часто сцены имеют одинаковый triggerHook. Чтобы избежать
повторов:
const defaultHook = 0.7;
document.querySelectorAll(".section").forEach(el => {
new ScrollMagic.Scene({
triggerElement: el,
triggerHook: defaultHook
})
.setClassToggle(el, "active")
.addTo(controller);
});
Использование переменной defaultHook облегчает изменение
логики прокрутки для всей страницы.
Примеры повторяющихся паттернов:
Решение:
function createScene(el, duration = 300, hook = 0.8, className = "visible") {
return new ScrollMagic.Scene({
triggerElement: el,
duration: duration,
triggerHook: hook
})
.setClassToggle(el, className)
.addTo(controller);
}
document.querySelectorAll(".animate").forEach(el => createScene(el));
const defaultSceneSettings = {
duration: 300,
triggerHook: 0.8,
className: "visible"
};
function createScene(el, settings = defaultSceneSettings) {
return new ScrollMagic.Scene({
triggerElement: el,
duration: settings.duration,
triggerHook: settings.triggerHook
})
.setClassToggle(el, settings.className)
.addTo(controller);
}
Такой подход делает код масштабируемым и легко поддерживаемым.
Если элементы добавляются после загрузки страницы, нужно инициализировать сцены динамически:
function initScenesForNewElements(selector) {
document.querySelectorAll(selector).forEach(el => {
if (!el.dataset.sceneInitialized) {
createScene(el);
el.dataset.sceneInitialized = true;
}
});
}
// Например, после AJAX-загрузки
initScenesForNewElements(".dynamic-animate");
Использование data-атрибутов предотвращает дублирование
сцен для одних и тех же элементов.
Иногда элементу нужно несколько эффектов при прокрутке:
const tl = gsap.timeline();
tl.to("#box", { x: 200, duration: 1 })
.to("#box", { rotation: 180, duration: 1 });
new ScrollMagic.Scene({
triggerElement: "#box",
duration: 400
})
.setTween(tl)
.addTo(controller);
Рефакторинг:
ScrollMagic предоставляет методы для отладки:
.addIndicators() показывает на странице точки триггера
и duration сцены.scene.on("enter", () => console.log("scene entered")).Рефакторинг кода с большим числом сцен требует:
duration,
triggerHook) в объекты или константы.data-атрибуты.Такой подход делает работу с ScrollMagic чистой, модульной и легко поддерживаемой даже на больших проектах.