Texte qui se brouille
Les lettres se mélangent en symboles, en katakana ou en binaire, puis se posent une à une sur le bon mot. Le bon exercice pour piloter une animation lettre par lettre avec requestAnimationFrame.
- Animer chaque lettre avec son propre calendrier
- Construire le texte image par image avec un fragment
- Garder l'effet accessible et respecter prefers-reduced-motion
Pourquoi un texte qui se brouille ? C'est l'effet des génériques de films de hackers et de beaucoup de portfolios : un titre qui « se décode » sous les yeux. Il attire le regard sans demander de vidéo ni de bibliothèque.
Chaque lettre reçoit un moment de départ et un moment d'arrivée tirés au hasard, un peu plus tard pour les lettres de droite. Avant son départ, elle montre l'ancien texte. Entre les deux, elle change de symbole au hasard. Après son arrivée, elle se pose. requestAnimationFrame redessine le tout à chaque image.
Pour les lecteurs d'écran, le texte animé est caché, et une copie invisible annonce directement le mot final. Si le visiteur préfère moins d'animations, le mot s'affiche sans effet.
Pourquoi en JavaScript simple ? Un tableau de lettres, une horloge et un fragment de document. Choisissez votre jeu de caractères et votre durée.
LE PLAN DE CHAQUE LETTRE
Un départ et une arrivée au hasard, un peu plus tard vers la droite.
function plan(avant, apres, duree) { const n = Math.max(avant.length, apres.length); return Array.from({ length: n }, (_, i) => { const debut = Math.random() * duree * 0.4; return { de: avant[i] ?? '', vers: apres[i] ?? '', debut, fin: debut + duree * 0.3 + Math.random() * duree * 0.3 + i * (duree * 0.3 / n) }; }); }LES SYMBOLES
const SYMBOLES = '!<>-_\\/[]{}=+*^?#'; const hasard = () => SYMBOLES[Math.floor(Math.random() * SYMBOLES.length)];UNE IMAGE
Selon le temps écoulé, chaque lettre est l'ancienne, un symbole ou la nouvelle.
function brouiller(el, cible, duree = 900) { const lettres = plan(el.textContent, cible, duree), t0 = performance.now(); annonce.textContent = cible; // pour les lecteurs d'écran if (matchMedia('(prefers-reduced-motion: reduce)').matches) { el.textContent = cible; return; } (function image(t) { const e = t - t0; let poses = 0; el.textContent = lettres.map(l => { if (e >= l.fin) { poses++; return l.vers; } if (e >= l.debut) return l.vers === ' ' ? ' ' : hasard(); return l.de; }).join(''); if (poses < lettres.length) requestAnimationFrame(image); })(t0); }FAIRE DÉFILER DES MOTS
const MOTS = ['Développeur web', 'Bruxelles', 'Sites sur mesure']; let i = 0; setInterval(() => brouiller(titre, MOTS[i = (i + 1) % MOTS.length]), 2500);
PIÈGE 1 : Annoncer chaque image aux lecteurs d'écran
Mauvais : un aria-live sur le texte animé. Le lecteur d'écran lit des dizaines de symboles absurdes.
Correct : cacher le texte animé avec aria-hidden, et annoncer le mot final dans un élément invisible.
PIÈGE 2 : Lancer deux animations à la fois
Mauvais : relancer l'effet pendant qu'il tourne encore. Deux boucles écrivent dans le même élément et le texte clignote.
Correct : garder l'identifiant de requestAnimationFrame et l'annuler avant chaque nouveau départ.
PIÈGE 3 : Un titre qui saute
Mauvais : une police où chaque symbole a une largeur différente. Le titre change de taille à chaque image et pousse la page.
Correct : une hauteur minimale réservée, et si possible une police à chasse fixe ou des chiffres tabulaires.
- Lancer l'effet au survol d'un lien, ou quand le titre entre dans l'écran avec IntersectionObserver.
- Garder les espaces et la ponctuation fixes, pour un décodage plus lisible.
- Colorer les lettres déjà posées pour suivre l'avancée.
- Ne modifiez le DOM qu'une fois par image, avec un seul textContent ou un fragment.
- Changez de symbole une image sur trois plutôt qu'à chaque image : l'effet reste vivant, le navigateur respire.
L'animation écrit directement dans le DOM par un useRef, sans état React à chaque image.
Le useEffect lance l'effet quand le texte cible change et annule la boucle au démontage.
Un hook useScramble(texte) rend l'effet réutilisable sur tous les titres du site.
Chargement des commentaires…