40 lines
1.1 KiB
JavaScript
40 lines
1.1 KiB
JavaScript
/**
|
|
* reveal.js — apparition au scroll via IntersectionObserver.
|
|
*
|
|
* Budget de mouvement sobre : fade + translateY(12px), durée --dur-slow.
|
|
* Sous prefers-reduced-motion: reduce, tout est visible immédiatement.
|
|
* Progressif : sans JS, le CSS ne masque rien (garde html[data-js]).
|
|
*
|
|
* Usage : import { initReveal } from '@transformer/ui/reveal.js'; initReveal();
|
|
* (Reveal.astro l'appelle déjà pour ses instances.)
|
|
*/
|
|
|
|
let observer;
|
|
|
|
export function initReveal(selector = "[data-reveal]") {
|
|
document.documentElement.dataset.js = "";
|
|
|
|
const targets = document.querySelectorAll(selector);
|
|
|
|
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
|
|
targets.forEach((el) => el.classList.add("is-visible"));
|
|
return;
|
|
}
|
|
|
|
observer ??= new IntersectionObserver(
|
|
(entries) => {
|
|
for (const entry of entries) {
|
|
if (entry.isIntersecting) {
|
|
entry.target.classList.add("is-visible");
|
|
observer.unobserve(entry.target);
|
|
}
|
|
}
|
|
},
|
|
{ threshold: 0.15, rootMargin: "0px 0px -10% 0px" }
|
|
);
|
|
|
|
targets.forEach((el) => {
|
|
if (!el.classList.contains("is-visible")) observer.observe(el);
|
|
});
|
|
}
|