Files
site_internet/scripts/chapter-progress.js
Hatmos f3ce09ab0a add: Nouveaux assets + adaptation script
- Nouveau assets pour la page mood
- Adaptation du style css pour la page mood
- Debut d'adaptation du script de suivi d'avancement a la page de cour
2026-09-21 04:50:49 +02:00

74 lines
2.6 KiB
JavaScript

function progress_tracker(){
const sections = Array.from(document.querySelectorAll('section[chapter]'));
const fill = document.getElementById('progressFill');
const titleEl = document.getElementById('sectionTitle');
const countEl = document.getElementById('sectionCount');
let ticking = false;
let currentIndex = -1;
function updateProgress() {
const viewportH = window.innerHeight;
const scrollY = window.scrollY;
// 1. Trouver la section active : celle dont le haut est le plus proche
// au-dessus (ou sur) le haut du viewport, mais qui n'est pas encore
// entièrement passée.
let activeIndex = 0;
for (let i = 0; i < sections.length; i++) {
const rect = sections[i].getBoundingClientRect();
// Une section devient "active" dès que son haut passe sous ~35% du viewport
if (rect.top <= viewportH * 0.35) {
activeIndex = i;
}
}
// 2. Calculer la progression DANS cette section (0 à 100%)
const activeSection = sections[activeIndex];
const rect = activeSection.getBoundingClientRect();
const sectionHeight = activeSection.offsetHeight;
// distance défilée depuis le haut de la section
const scrolledIntoSection = -rect.top;
// on borne entre 0 et la hauteur totale de la section moins le viewport
// (pour atteindre 100% quand le bas de la section touche le bas de l'écran)
const scrollableDistance = Math.max(sectionHeight - viewportH, 1);
let progress = scrolledIntoSection / scrollableDistance;
progress = Math.min(Math.max(progress, 0), 1);
// Cas particulier : si la section est plus petite que le viewport,
// on considère 100% dès qu'elle est visible en haut.
if (sectionHeight <= viewportH) {
progress = scrolledIntoSection > 0 ? 1 : 0;
}
fill.style.width = (progress * 100).toFixed(1) + '%';
// 3. Mettre à jour le titre uniquement si la section a changé
// (évite de re-déclencher la transition CSS à chaque pixel)
if (activeIndex !== currentIndex) {
currentIndex = activeIndex;
titleEl.style.opacity = 0;
setTimeout(() => {
titleEl.textContent = activeSection.dataset.title;
countEl.textContent = (activeIndex + 1) + ' / ' + sections.length;
titleEl.style.opacity = 1;
}, 120);
}
}
function onScroll() {
if (!ticking) {
requestAnimationFrame(() => {
updateProgress();
ticking = false;
});
ticking = true;
}
}
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', onScroll);
updateProgress(); // init au chargement
})();