Функция scroll

Функция scroll в Motion One предназначена для создания анимаций, зависящих от положения прокрутки страницы или конкретного контейнера. Она связывает значение скролла с вычисляемыми прогрессами, позволяя строить интерфейсы, реагирующие на движение документа без ручной работы с событиями scroll и без постоянного перерасчёта координат.

В основе лежит идея реактивного отслеживания прокрутки: библиотека преобразует текущее положение скролла в нормализованное значение, обычно в диапазоне от 0 до 1, и передаёт его в пользовательский обработчик или систему анимаций.


Базовый принцип работы

Функция scroll подписывается на изменения прокрутки и вычисляет прогресс движения относительно заданного диапазона.

import { scroll } from "motion";

scroll((progress) => {
  // progress: значение от 0 до 1
});

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


Подписка на объект состояния прокрутки

Помимо простого прогресса, scroll может предоставлять объект состояния, содержащий несколько координатных значений:

scroll(({ y, x }) => {
  // y — вертикальная прокрутка
  // x — горизонтальная прокрутка
});

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


Работа с осью прокрутки

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

scroll(({ y }) => {
  const progress = y.progress;
});

Типичная структура данных оси включает:

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

Это позволяет отделить физическое движение страницы от логики анимации.


Контейнерная прокрутка

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

const container = document.querySelector(".scroll-container");

scroll((progress) => {
  // обработка прогресса
}, {
  container
});

В этом режиме расчёты выполняются относительно границ указанного элемента, а не документа.

Контейнерный режим используется в:

  • модальных окнах с прокруткой
  • карточных интерфейсах
  • вложенных списках
  • кастомных скролл-зонах

Привязка к элементу

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

const element = document.querySelector(".section");

scroll((progress) => {
  // прогресс появления элемента
}, {
  target: element
});

В этом режиме прогресс обычно интерпретируется как:

  • начало входа элемента в viewport
  • полное появление
  • выход за пределы экрана

Настройка диапазона через offset

Одной из ключевых возможностей является управление диапазоном вычисления прогресса с помощью offset.

scroll((progress) => {
  // прогресс ограничен заданными границами
}, {
  target: element,
  offset: ["start end", "end start"]
});

Offset определяет, какие точки элемента и viewport считаются началом и концом анимации.

Распространённые логики:

  • запуск при появлении верхней границы элемента
  • завершение при выходе нижней границы
  • ранний старт анимации до попадания в экран

Интеграция с animate

Главная ценность scroll проявляется при связке с функцией animate, где прокрутка напрямую управляет параметрами анимации.

import { scroll, animate } from "motion";

scroll((progress) => {
  animate(".box", {
    opacity: progress,
    transform: `scale(${0.5 + progress * 0.5})`
  });
});

В реальных сценариях такая связка заменяется более оптимизированными паттернами, где анимация создаётся один раз, а скролл лишь обновляет её прогресс.


Скролл как источник временной шкалы

Прокрутка может рассматриваться как аналог временной шкалы анимации. Вместо времени используется позиция пользователя на странице.

scroll((progress) => {
  // прогресс фактически заменяет time
});

Такой подход позволяет создавать:

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

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

Одно из наиболее частых применений scroll — параллакс.

scroll((progress) => {
  const y = progress * 200;

  document.querySelector(".background").style.transform =
    `translateY(${y}px)`;
});

При этом фон движется медленнее или быстрее основного контента, создавая ощущение глубины.


Управление несколькими слоями

При сложных интерфейсах несколько элементов могут реагировать на один и тот же прогресс.

scroll((progress) => {
  const offset1 = progress * 100;
  const offset2 = progress * 300;

  layer1.style.transform = `translateY(${offset1}px)`;
  layer2.style.transform = `translateY(${offset2}px)`;
});

Каждый слой получает собственную функцию преобразования прогресса, что позволяет строить многослойные сцены.


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

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

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

  • батчинг обновлений
  • минимизация перерасчётов
  • синхронизация с кадрами рендера
  • отсутствие лишних вызовов при отсутствии изменений

Управление жизненным циклом

Подписка, создаваемая scroll, возвращает функцию остановки наблюдения.

const stop = scroll((progress) => {
  // логика
});

stop();

Это позволяет:

  • отключать анимации при смене страницы
  • освобождать ресурсы при удалении компонентов
  • управлять динамическими интерфейсами

Горизонтальные сценарии прокрутки

При работе с горизонтальными интерфейсами scroll адаптируется к оси X.

scroll(({ x }) => {
  const progress = x.progress;
});

Применения:

  • горизонтальные слайдеры
  • timeline-интерфейсы
  • карусели изображений
  • интерактивные галереи

Комбинированные сценарии X и Y

В сложных интерфейсах может использоваться одновременное отслеживание обеих осей.

scroll(({ x, y }) => {
  const px = x.progress;
  const py = y.progress;
});

Такой подход используется в:

  • 3D-псевдоинтерфейсах
  • интерактивных картах
  • гибридных дашбордах

Привязка анимации к видимости элемента

Сценарий появления элементов при прокрутке реализуется через отслеживание прогресса входа в viewport.

scroll((progress) => {
  element.style.opacity = progress;
  element.style.transform = `translateY(${(1 - progress) * 50}px)`;
}, {
  target: element
});

Элемент постепенно появляется при приближении к зоне видимости.


Использование в интерфейсных паттернах

На основе scroll строятся типовые архитектуры интерфейсов:

  • лендинги с поэтапной анимацией
  • фиксация секций при прокрутке
  • динамические заголовки
  • прогресс-индикаторы чтения
  • визуальные таймлайны

Скролл как система координат

Внутри Motion One прокрутка фактически превращается в координатную систему, где:

  • 0 соответствует начальному состоянию
  • 1 соответствует завершению диапазона
  • промежуточные значения описывают позицию в сцене

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


Синхронизация с другими анимациями

scroll может выступать центральным управляющим механизмом для нескольких независимых анимаций.

scroll((progress) => {
  animate(".title", { opacity: progress });
  animate(".image", { scale: 0.8 + progress * 0.2 });
  animate(".text", { y: (1 - progress) * 20 });
});

Каждый элемент получает свою интерпретацию одного и того же значения прогресса, что обеспечивает согласованность поведения интерфейса.


Обработка инерции и плавности

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


Архитектурная роль scroll в Motion One

Функция scroll выступает связующим звеном между:

  • пользовательским вводом
  • системой координат страницы
  • анимационным движком
  • DOM-элементами

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