Прогресс-бар чтения — это визуальный индикатор, который отражает текущую позицию пользователя на странице относительно общего объёма контента. Основная задача — динамически изменять ширину или положение элемента в зависимости от прокрутки страницы. При использовании библиотеки Smooth Scroll можно создавать более плавное и отзывчивое взаимодействие, синхронизируя скролл и прогресс.
Базовая формула для вычисления прогресса выглядит так:
[ = %]
scrollTop — текущая вертикальная позиция скролла.scrollHeight — полная высота документа.clientHeight — видимая высота окна браузера.Эта формула позволяет получить процентное значение, на которое пользователь прошёл страницу, и использовать его для изменения ширины прогресс-бара.
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:
<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 прогресс-бар автоматически реагирует на плавную прокрутку. Можно дополнительно использовать коллбэки:
const scroll = new SmoothScroll('a[href*="#"]', {
speed: 600,
easing: 'easeInOutCubic',
after: () => updateProgress(),
});
after вызывается после завершения анимации
скролла.progressBar.style.backgroundColor = `hsl(${progress * 1.2}, 70%, 50%)`;
Если контент разделён на статьи или главы, можно вычислять прогресс для каждой секции:
const sections = document.querySelectorAll('section');
sections.forEach(section => {
const rect = section.getBoundingClientRect();
if(rect.top < window.innerHeight && rect.bottom > 0){
// вычислить локальный прогресс
}
});
scroll.transform: scaleX() вместо изменения
width для более плавной GPU-анимации:.progress-bar {
transform-origin: left center;
transform: scaleX(0);
transition: transform 0.2s ease-out;
}
requestAnimationFrame предпочтительнее прямого события
scroll.Эти методы позволяют создавать профессиональные прогресс-бары чтения, которые плавно реагируют на прокрутку и синхронизируются с анимацией Smooth Scroll, улучшая UX и визуальную отдачу страницы.