Прогресс-бары чтения

Принцип работы прогресс-бара чтения

Прогресс-бар чтения — это визуальный индикатор, который отражает текущую позицию пользователя на странице относительно общего объёма контента. Основная задача — динамически изменять ширину или положение элемента в зависимости от прокрутки страницы. При использовании библиотеки Smooth Scroll можно создавать более плавное и отзывчивое взаимодействие, синхронизируя скролл и прогресс.

Базовая формула для вычисления прогресса выглядит так:

[ = %]

  • scrollTop — текущая вертикальная позиция скролла.
  • scrollHeight — полная высота документа.
  • clientHeight — видимая высота окна браузера.

Эта формула позволяет получить процентное значение, на которое пользователь прошёл страницу, и использовать его для изменения ширины прогресс-бара.


Подключение и инициализация Smooth Scroll

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

Подключение через npm:

npm install smooth-scroll

Или через CDN:

<script src="https://cdn.jsdelivr.net/npm/smooth-scroll@16/dist/smooth-scroll.polyfills.min.js"></script>

Инициализация базового Smooth Scroll для якорных ссылок:

const scroll = new SmoothScroll('a[href*="#"]', {
    speed: 600,
    speedAsDuration: true,
    easing: 'easeInOutCubic',
});

Создание HTML и CSS прогресс-бара

HTML:

<div class="progress-container">
    <div class="progress-bar" id="readingProgress"></div>
</div>

CSS:

.progress-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 6px;
    background-color: rgba(0, 0, 0, 0.1);
    z-index: 9999;
}

.progress-bar {
    height: 100%;
    width: 0;
    background-color: #3498db;
    transition: width 0.2s ease-out;
}
  • position: fixed закрепляет прогресс-бар в верхней части окна.
  • transition обеспечивает плавное изменение ширины при обновлении.

Отслеживание скролла и обновление прогресс-бара

Используется событие scroll на объекте window. Для плавности и синхронизации с Smooth Scroll рекомендуется использовать requestAnimationFrame:

const progressBar = document.getElementById('readingProgress');

function updateProgress() {
    const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
    const scrollHeight = document.documentElement.scrollHeight;
    const clientHeight = document.documentElement.clientHeight;

    const progress = (scrollTop / (scrollHeight - clientHeight)) * 100;
    progressBar.style.width = `${progress}%`;

    requestAnimationFrame(updateProgress);
}

requestAnimationFrame(updateProgress);
  • requestAnimationFrame уменьшает нагрузку на рендеринг, обновляя прогресс-бар синхронно с частотой обновления экрана.
  • Вычисление процента происходит динамически при любом скролле, включая плавную прокрутку от Smooth Scroll.

Интеграция с плавной прокруткой

При использовании Smooth Scroll прогресс-бар автоматически реагирует на плавную прокрутку. Можно дополнительно использовать коллбэки:

const scroll = new SmoothScroll('a[href*="#"]', {
    speed: 600,
    easing: 'easeInOutCubic',
    after: () => updateProgress(),
});
  • Коллбэк after вызывается после завершения анимации скролла.
  • Позволяет обновить прогресс-бар точно в момент окончания прокрутки по якорю.

Продвинутые техники

  1. Анимация цвета по прогрессу:
progressBar.style.backgroundColor = `hsl(${progress * 1.2}, 70%, 50%)`;
  1. Прогресс для отдельных секций:

Если контент разделён на статьи или главы, можно вычислять прогресс для каждой секции:

const sections = document.querySelectorAll('section');

sections.forEach(section => {
    const rect = section.getBoundingClientRect();
    if(rect.top < window.innerHeight && rect.bottom > 0){
        // вычислить локальный прогресс
    }
});
  1. Дебаунс или троттлинг: Для улучшения производительности при больших страницах можно использовать троттлинг события scroll.

Советы по оптимизации

  • Использовать transform: scaleX() вместо изменения width для более плавной GPU-анимации:
.progress-bar {
    transform-origin: left center;
    transform: scaleX(0);
    transition: transform 0.2s ease-out;
}
  • При большом количестве DOM-элементов обновление через requestAnimationFrame предпочтительнее прямого события scroll.
  • Совмещать Smooth Scroll с Intersection Observer для отслеживания текущей секции и адаптивного изменения прогресс-бара.

Эти методы позволяют создавать профессиональные прогресс-бары чтения, которые плавно реагируют на прокрутку и синхронизируются с анимацией Smooth Scroll, улучшая UX и визуальную отдачу страницы.