Событие progress

Событие progress является одним из ключевых механизмов отслеживания состояния сцены в библиотеке ScrollMagic. Оно позволяет получать информацию о том, насколько далеко пользователь продвинулся внутри конкретной сцены, выраженную в виде числа от 0 до 1.


Общая концепция

Каждая сцена (Scene) в ScrollMagic имеет определённую продолжительность (duration). Пока пользователь прокручивает страницу и находится в пределах этой сцены, происходит вычисление текущего прогресса:

  • 0 — начало сцены (вход в область действия)
  • 1 — конец сцены (выход из области действия)
  • промежуточные значения — текущее положение внутри сцены

Событие progress срабатывает каждый раз, когда изменяется это значение.


Подключение обработчика события

Обработчик события регистрируется с помощью метода .on():

scene.on("progress", function (event) {
    console.log(event.progress);
});

Объект event содержит несколько полезных свойств:

  • progress — текущее значение прогресса (от 0 до 1)
  • state — текущее состояние сцены (BEFORE, DURING, AFTER)
  • scrollDirection — направление прокрутки (FORWARD, REVERSE)

Пример базового использования

var controller = new ScrollMagic.Controller();

var scene = new ScrollMagic.Scene({
    triggerElement: "#trigger",
    duration: 300
})
.addTo(controller);

scene.on("progress", function (event) {
    console.log("Прогресс:", event.progress.toFixed(2));
});

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


Практическое применение

1. Анимация на основе прогресса

Событие progress часто используется для создания плавных анимаций:

scene.on("progress", function (event) {
    var scale = 1 + event.progress;
    document.querySelector("#box").style.transform = "scale(" + scale + ")";
});

Элемент будет увеличиваться по мере прокрутки сцены.


2. Управление прозрачностью

scene.on("progress", function (event) {
    document.querySelector("#fade").style.opacity = event.progress;
});

Элемент постепенно появляется при прокрутке.


3. Параллакс-эффекты

scene.on("progress", function (event) {
    var offset = event.progress * 100;
    document.querySelector(".parallax").style.transform =
        "translateY(" + offset + "px)";
});

Создаётся эффект смещения элемента с разной скоростью.


Особенности работы

Частота срабатывания

Событие progress может вызываться очень часто — практически на каждом кадре прокрутки. Это накладывает требования к производительности:

  • избегать тяжёлых вычислений
  • минимизировать работу с DOM
  • по возможности использовать requestAnimationFrame

Зависимость от duration

Если duration равен 0, сцена становится “моментальной”. В этом случае:

  • прогресс будет либо 0, либо 1
  • промежуточных значений не будет
  • событие progress теряет смысл для плавных анимаций

Связь с состояниями сцены

Событие progress тесно связано с состоянием сцены:

Состояние Прогресс
BEFORE 0
DURING 0 → 1
AFTER 1

Комбинирование с другими событиями

Событие progress часто используется вместе с:

  • enter — вход в сцену
  • leave — выход из сцены
  • update — обновление сцены

Пример:

scene
.on("enter", function () {
    console.log("Начало сцены");
})
.on("progress", function (event) {
    console.log("Идёт анимация:", event.progress);
})
.on("leave", function () {
    console.log("Конец сцены");
});

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

При активном использовании progress важно учитывать:

Кэширование DOM-элементов

var element = document.querySelector("#box");

scene.on("progress", function (event) {
    element.style.transform = "translateX(" + (event.progress * 200) + "px)";
});

Ограничение вычислений

scene.on("progress", function (event) {
    var progress = Math.round(event.progress * 100) / 100;
    // Использование округлённого значения снижает нагрузку
});

Использование requestAnimationFrame

var ticking = false;

scene.on("progress", function (event) {
    if (!ticking) {
        requestAnimationFrame(function () {
            updateAnimation(event.progress);
            ticking = false;
        });
        ticking = true;
    }
});

Типичные ошибки

1. Работа с тяжёлыми операциями внутри обработчика

// Плохо
scene.on("progress", function () {
    heavyFunction();
});

2. Множественные запросы к DOM

// Плохо
scene.on("progress", function () {
    document.querySelector("#a").style.opacity = event.progress;
});

3. Игнорирование направления прокрутки

Иногда логика должна зависеть от направления:

scene.on("progress", function (event) {
    if (event.scrollDirection === "FORWARD") {
        // движение вниз
    } else {
        // движение вверх
    }
});

Расширенные сценарии

Синхронизация нескольких элементов

scene.on("progress", function (event) {
    var progress = event.progress;

    document.querySelector("#el1").style.transform =
        "translateX(" + progress * 100 + "px)";

    document.querySelector("#el2").style.transform =
        "translateY(" + progress * 200 + "px)";
});

Управление видео или аудио

scene.on("progress", function (event) {
    var video = document.querySelector("video");
    video.currentTime = video.duration * event.progress;
});

Позволяет “привязать” воспроизведение к прокрутке.


Индикация прогресса

scene.on("progress", function (event) {
    document.querySelector("#progress-bar").style.width =
        (event.progress * 100) + "%";
});

Создаётся визуальный индикатор прокрутки внутри сцены.


Взаимодействие с tween-анимациями

При использовании GSAP (через TweenMax или gsap) событие progress может дублировать или дополнять встроенные механизмы синхронизации:

var tween = gsap.to("#box", { x: 300 });

new ScrollMagic.Scene({
    triggerElement: "#trigger",
    duration: 400
})
.setTween(tween)
.on("progress", function (event) {
    console.log("ScrollMagic progress:", event.progress);
});

Отладка

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

scene.addIndicators();

Это позволяет визуально видеть:

  • начало сцены
  • конец сцены
  • текущую позицию

Ключевые особенности

  • непрерывное отслеживание положения внутри сцены
  • высокая частота обновления
  • тесная интеграция с анимациями
  • универсальность применения (от простых эффектов до сложных взаимодействий)
  • зависимость от duration и положения триггера

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