Прогресс заполнения

Механизм прогресса в ScrollMagic позволяет отслеживать, насколько далеко пользователь продвинулся внутри сцены (Scene). Это ключевая возможность для создания анимаций, синхронизированных со скроллом, где состояние элементов зависит не от факта попадания в область видимости, а от степени прокрутки.

Понятие прогресса

Каждая сцена в ScrollMagic имеет параметр progress, принимающий значения от 0 до 1:

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

Прогресс рассчитывается автоматически на основе:

  • позиции прокрутки
  • длительности сцены (duration)
  • положения триггера (triggerElement, triggerHook)

Получение прогресса сцены

Прогресс можно получить через API сцены:

scene.progress();

Этот метод возвращает текущее значение прогресса (число от 0 до 1).

Пример:

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

controller.addScene(scene);

window.addEventListener("scroll", function() {
  console.log(scene.progress());
});

Событие изменения прогресса

ScrollMagic предоставляет событие progress, которое срабатывает при каждом изменении значения:

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

Объект event содержит:

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

Связь с длительностью сцены

Прогресс имеет смысл только при наличии duration. Если duration не задан:

  • сцена считается мгновенной
  • прогресс скачет с 0 сразу на 1

Пример сцены с прогрессом:

var scene = new ScrollMagic.Scene({
  triggerElement: "#block",
  duration: 500
});

Здесь:

  • начало сцены — момент появления #block
  • конец — через 500 пикселей прокрутки
  • прогресс линейно изменяется от 0 до 1 на этом участке

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

Ручное управление стилями

Прогресс удобно использовать для управления CSS:

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

  var scale = 1 + progress;
  var opacity = progress;

  document.querySelector("#box").style.transform = "scale(" + scale + ")";
  document.querySelector("#box").style.opacity = opacity;
});

Результат:

  • при прокрутке элемент увеличивается
  • одновременно становится более видимым

Параллакс-эффект

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

  document.querySelector(".parallax").style.transform =
    "translateY(" + y + "px)";
});

Связка с GSAP

ScrollMagic часто используется вместе с GSAP. В этом случае прогресс сцены напрямую управляет таймлайном:

var tween = gsap.to("#box", {
  x: 500,
  rotation: 360,
  duration: 1
});

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

Особенности:

  • duration сцены управляет временем анимации
  • ScrollMagic синхронизирует прогресс сцены с прогрессом tween

Нелинейное преобразование прогресса

Иногда требуется изменить линейное поведение:

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

  var eased = Math.pow(p, 2); // ускорение

  document.querySelector("#box").style.transform =
    "translateX(" + (eased * 300) + "px)";
});

Варианты преобразования:

  • p * p — ускорение
  • Math.sqrt(p) — замедление
  • Math.sin(p * Math.PI) — плавная кривая

Ограничение диапазона

Можно использовать только часть прогресса:

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

  if (p < 0.3) return;

  var normalized = (p - 0.3) / 0.7;

  document.querySelector("#box").style.opacity = normalized;
});

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

Несколько сцен и единый прогресс

Для сложных интерфейсов используется объединение прогресса:

var totalProgress = 0;

scene1.on("progress", function(e) {
  totalProgress = e.progress * 0.5;
});

scene2.on("progress", function(e) {
  totalProgress = 0.5 + e.progress * 0.5;
});

Таким образом создаётся единая шкала от 0 до 1 для нескольких сцен.

Производительность

Частое обновление прогресса может нагружать браузер. Рекомендуется:

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

Пример оптимизации:

var ticking = false;

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

Прогресс и направление скролла

Иногда важно учитывать направление:

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

Это полезно для:

  • обратных анимаций
  • логики скрытия/показа элементов

Работа без duration

При отсутствии duration:

var scene = new ScrollMagic.Scene({
  triggerElement: "#trigger"
});

Прогресс:

  • всегда 0 до момента триггера
  • мгновенно становится 1

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

Прогресс и закрепление (pin)

При использовании setPin:

scene.setPin("#section");

Прогресс отражает время “закрепления” элемента:

  • 0 — начало фиксации
  • 1 — конец фиксации

Это удобно для:

  • storytelling
  • пошаговых анимаций
  • прокручиваемых презентаций

Отладка прогресса

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

scene.addIndicators();

Позволяет увидеть:

  • начало и конец сцены
  • текущую позицию
  • изменение прогресса в реальном времени

Частые ошибки

1. Отсутствие duration

  • прогресс не работает плавно

2. Избыточные вычисления

  • тормоза при скролле

3. Неправильная нормализация

  • скачки анимации

4. Работа с DOM внутри цикла

  • плохая производительность

Практическая модель использования

Стандартный шаблон:

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

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

  // логика
});

Эта конструкция лежит в основе большинства scroll-driven интерфейсов:

  • анимации
  • графики
  • интерактивные истории
  • эффекты параллакса

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