1. Mechanisme — kopieer 1-op-1, geen styling-keuzes
// Mechanisme: form-success-burst-minimal
// Submit -> form fadet uit (autoAlpha 0, scale .95) -> success-state in (check + tekst).
// Single-pulse op check-icon. 6-dot radial burst, fade out 0.6s.
// AUTO-DEMO: na 2s init, daarna elke 5s een nieuwe submit-cycle.
import gsap from 'https://esm.sh/[email protected]';
(() => {
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const root = document.querySelector('.fsb-mn');
if (!root) return;
const form = root.querySelector('.fsb-mn-form');
const success = root.querySelector('.fsb-mn-success');
const check = root.querySelector('.fsb-mn-check');
const dots = root.querySelectorAll('.fsb-mn-dot');
const trigger = () => {
if (reduce) {
gsap.set(form, { autoAlpha: 0 });
gsap.set(success, { autoAlpha: 1 });
gsap.set(check, { scale: 1, opacity: 1 });
return;
}
const tl = gsap.timeline();
tl.to(form, { autoAlpha: 0, scale: 0.95, duration: 0.4, ease: 'power2.out' })
.set(success, { autoAlpha: 1 }, '-=0.05')
.fromTo(check, { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.5, ease: 'back.out(2)' })
.to(check, { scale: 1.08, duration: 0.18, yoyo: true, repeat: 1, ease: 'power2.inOut' });
dots.forEach((d, i) => {
const angle = (i / dots.length) * Math.PI * 2;
const dist = 56;
tl.fromTo(d,
{ x: 0, y: 0, opacity: 1, scale: 1 },
{ x: Math.cos(angle) * dist, y: Math.sin(angle) * dist, opacity: 0, scale: 0.4, duration: 0.6, ease: 'power2.out' },
'-=0.55'
);
});
};
const reset = () => {
gsap.set(form, { autoAlpha: 1, scale: 1 });
gsap.set(success, { autoAlpha: 0 });
gsap.set(check, { scale: 0, opacity: 0 });
gsap.set(dots, { x: 0, y: 0, opacity: 0, scale: 1 });
};
reset();
if (form) form.addEventListener('submit', e => { e.preventDefault(); trigger(); });
if (!reduce) {
setTimeout(() => {
trigger();
setInterval(() => { reset(); setTimeout(trigger, 250); }, 5000);
}, 2000);
}
})();