Files
gong.gp/src/lib/motion/reveal.ts
T

32 lines
967 B
TypeScript
Raw Normal View History

import type { Action } from 'svelte/action';
import { syncopatedDelay } from './tokens';
// use:reveal={index} — révèle l'élément à l'entrée dans le viewport avec cascade gwoka.
// L'état caché est posé en CSS uniquement sous html.has-js + prefers-reduced-motion: no-preference,
// donc le contenu reste lisible sans JS et sans animation.
export const reveal: Action<HTMLElement, number | undefined> = (node, index = 0) => {
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (reduce) {
node.classList.add('is-visible');
return;
}
node.style.setProperty('--d', `${syncopatedDelay(index)}ms`);
const io = new IntersectionObserver(
(entries) => {
for (const e of entries) {
if (e.isIntersecting) {
node.classList.add('is-visible');
io.unobserve(node);
}
}
},
{ threshold: 0.12, rootMargin: '0px 0px -8% 0px' }
);
io.observe(node);
return {
destroy() {
io.disconnect();
}
};
};