Trail Effect
Traînée de particules colorées suivant le curseur — chaque particule pivote, rétrécit et s'estompe en fondu sur un canvas 2D.
Vous aurez accès à la démo interactive avec un compte gratuit.
Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Atmosphère comprend 57 effets, dont 10 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
À chaque événement mousemove, l'IIFE émet 3 particules depuis la position du curseur : vélocité aléatoire dans ±2 px/frame, taille initiale 2–6 px, couleur tirée dans une palette de 5 et durée de vie normalisée à 1. La boucle requestAnimationFrame met à jour et redessine en continu toutes les particules actives.
L'effet de traînée repose sur un effacement partiel du canvas : au lieu d'un clearRect complet, chaque frame commence par ctx.fillStyle = 'rgba(10,10,15,0.12)'. Les 88 % de persistance résiduelle accumulent les frames précédentes et forment naturellement la queue lumineuse sans stockage de positions historiques.
Chaque particule perd decay de vie (0,015–0,035 par frame, tiré aléatoirement), rétrécit d'un facteur 0,98 par frame et pivote selon un rotSpeed dans ±4 °/frame. Le globalAlpha est calé sur la valeur courante de life : la disparition est progressive, sans table d'interpolation externe.
Le canvas est dimensionné une seule fois à l'initialisation via getBoundingClientRect() sur le parentElement. Aucun IntersectionObserver : le RAF tourne en continu même hors viewport. L'effet est lié à l'id fixe psTrail — une seule instance par page dans le code livré.
Accessibilité
- Pas de prefers-reduced-motion : le code ne vérifie pas
window.matchMedia('(prefers-reduced-motion:reduce)')— l'animation tourne même si l'OS la désactive. Ajoutez la vérification avant le premierrequestAnimationFramepour couper l'effet. - Le
<canvas>ne porte pasaria-hidden="true"dans le code livré — à ajouter sur l'élément pour masquer ce nœud sans sémantique aux lecteurs d'écran. - Le texte
.ps-hint(« Bougez la souris ») est un nœud texte réel, accessible aux lecteurs d'écran — mais son contenu n'est pertinent que pour les utilisateurs souris. - L'interaction est exclusivement
mousemove: aucun événementtouchmoveni clavier — les utilisateurs mobiles et clavier ne peuvent pas déclencher les particules. - Le texte
.ps-hints'affiche àrgba(255,255,255,0.3)sur fond#0a0a0f, soit un ratio de contraste ≈ 1,8:1 — bien en dessous du seuil WCAG AA (4,5:1). À opacifier si le texte est fonctionnel.
Compatibilité navigateur
Requiert Canvas 2D Context et requestAnimationFrame — disponibles dans tous les navigateurs modernes depuis 2013. Zéro dépendance externe.
Si <code>canvas</code> n'est pas supporté, <code>setupCanvas()</code> retourne <code>null</code> et l'IIFE sort immédiatement (<code>if (!t) return</code>) — aucune erreur JS, la page reste fonctionnelle.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="demo-preview">
<div class="ps-canvas-wrap">
<canvas class="ps-canvas" id="psTrail"
aria-hidden="true"
width="392" height="280"></canvas>
<span class="ps-hint">Bougez la souris</span>
</div>
</div>
HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
| o = [...] | ['#8b5cf6','#ec4899','#06b6d4','#f59e0b','#10b981'] | Palette de couleurs des particules. Tableau de chaînes hex ou rgba — remplacez par vos couleurs brand. |
| for (let t=0;t<3;t++) | 3 particules/event | Densité de la traînée : nombre de particules émises à chaque déplacement souris. Augmentez pour une traînée dense, réduisez pour un effet discret. |
| vx: 2*(Math.random()-.5) | ±2 px/frame | Multiplicateur de la vélocité initiale (identique sur vx et vy). 1 = particules groupées près du curseur, 4 = large dispersion. |
| size: 4*Math.random()+2 | 2–6 px | Plage de taille initiale. Changez l'amplitude (4) et le minimum (2) — ex. 8*Math.random()+4 pour des particules plus grandes. |
| decay: .02*Math.random()+.015 | 0,015–0,035/frame | Vitesse de disparition. Montez vers 0,04 pour des particules éphémères, descendez à 0,008 pour une traînée longue. |
| n.size *= .98 | 0,98 × par frame | Facteur de rétrécissement. 0,99 = réduction douce (particule visible plus longtemps), 0,94 = disparition rapide. |
| 'rgba(10,10,15,0.12)' | alpha 0,12 | Opacité du fond de masquage partiel — contrôle la longueur de la traînée. 0,06 = queue très longue, 0,25 = particules courtes et nettes. |
FAQ
psTrail via document.getElementById. Pour plusieurs zones, copiez le bloc JS et remplacez "psTrail" par un id différent dans chaque copie — la fonction setupCanvas() reste globale et réutilisable.ctx.fillStyle = 'rgba(10,10,15,0.12)' remplace le clearRect habituel. Baisser ce coefficient alpha (ex. 0.06) allonge la traînée en conservant les frames précédentes plus longtemps ; le monter (ex. 0.25) la raccourcit pour des particules nettes.mousemove est écouté. Pour le tactile, ajoutez un listener touchmove qui lit e.touches[0].clientX/Y et appelle la même logique d'émission de particules.