Паттерны организации кода

ScrollMagic — библиотека для создания анимаций при скролле, которая требует аккуратной организации кода для поддерживаемости и расширяемости. Ключевой принцип — разделение логики и конфигурации сцен. Любая сцена в ScrollMagic строится вокруг трех элементов: контроллера (ScrollMagic.Controller), сцены (ScrollMagic.Scene) и триггерных элементов (triggerElement).

Пример базовой структуры сцены:

// Создание контроллера
const controller = new ScrollMagic.Controller();

// Настройка сцены
const scene = new ScrollMagic.Scene({
    triggerElement: "#section1",
    duration: 500,
    triggerHook: 0.5
})
.setClassToggle("#section1", "active")
.addTo(controller);

В этом примере видны три ключевых параметра сцены: triggerElement (элемент, который запускает сцену), duration (продолжительность действия сцены) и triggerHook (позиция триггера относительно окна просмотра).


Использование модульного подхода

При работе с большим проектом рекомендуется разбивать код на модули по типу анимаций или по страницам. Для этого можно использовать ES6-модули:

// scrollController.js
export const controller = new ScrollMagic.Controller();

// scenes/scene1.js
import { controller } from '../scrollController.js';

export function initScene1() {
    new ScrollMagic.Scene({
        triggerElement: "#section1",
        duration: 400
    })
    .setTween("#section1", {opacity: 1, y: -50})
    .addTo(controller);
}

Такой подход упрощает поддержку, особенно если анимаций становится десятки.


Паттерн фабрики сцен

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

function createScene({trigger, target, duration, className}) {
    return new ScrollMagic.Scene({
        triggerElement: trigger,
        duration: duration
    })
    .setClassToggle(target, className)
    .addTo(controller);
}

// Применение
const scenes = [
    {trigger: "#sec1", target: "#sec1", duration: 300, className: "visible"},
    {trigger: "#sec2", target: "#sec2", duration: 400, className: "visible"}
];

scenes.forEach(cfg => createScene(cfg));

Такой паттерн уменьшает дублирование кода и позволяет централизованно управлять параметрами анимации.


Управление анимациями через GSAP

ScrollMagic тесно интегрируется с GSAP, что позволяет создавать сложные временные анимации. Для чистой архитектуры стоит отделять определение анимаций от создания сцен:

import { gsap } from "gsap";

// Определение анимации
function animateSection(target) {
    return gsap.fromTo(target, {opacity: 0, y: 50}, {opacity: 1, y: 0, duration: 1});
}

// Создание сцены
new ScrollMagic.Scene({
    triggerElement: "#section3",
    duration: 500
})
.setTween(animateSection("#section3"))
.addTo(controller);

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


Паттерн событий и обратных вызовов

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

  • enter — когда сцена активируется
  • leave — когда сцена деактивируется
  • update — при каждом обновлении позиции скролла
scene.on("enter", () => {
    console.log("Сцена активирована");
})
.on("leave", () => {
    console.log("Сцена покинута");
});

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


Централизация контроллера

Для проектов с множеством страниц часто создают один глобальный контроллер, который импортируется во все модули. Это упрощает синхронизацию сцен и позволяет использовать общий refresh() при изменении DOM:

// main.js
import { controller } from './scrollController.js';
import { initScene1 } from './scenes/scene1.js';
import { initScene2 } from './scenes/scene2.js';

initScene1();
initScene2();

// Обновление контроллера после динамической загрузки контента
window.addEventListener('resize', () => controller.update());

Рекомендации по организации файлов

  • scrollController.js — создание и экспорт одного контроллера
  • scenes/ — отдельные файлы для каждой сцены или группы связанных сцен
  • animations/ — функции анимаций, которые возвращают GSAP-твины
  • utils/scrollHelpers.js — вспомогательные функции для триггеров, проверок видимости и debounce

Использование JSON-конфигураций

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

const sceneConfigs = [
    {trigger: "#sec1", target: "#sec1", duration: 300, animation: {opacity: 1, y: -50}},
    {trigger: "#sec2", target: "#sec2", duration: 400, animation: {opacity: 1, scale: 1}}
];

sceneConfigs.forEach(cfg => {
    const tween = gsap.to(cfg.target, cfg.animation);
    new ScrollMagic.Scene({
        triggerElement: cfg.trigger,
        duration: cfg.duration
    })
    .setTween(tween)
    .addTo(controller);
});

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


Итоговые принципы

  • Модульность — каждая сцена и анимация в отдельном файле
  • Фабрики и конфигурации — генерация сцен из JSON или объектов
  • Разделение логики и анимаций — GSAP-анимации отдельно от ScrollMagic сцен
  • События и подписки — управление сложными интерактивными эффектами
  • Централизованный контроллер — единая точка управления скроллом

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