Particle Burst
Un burst de 30 particules colorées explose radialement depuis n'importe quel bouton au clic — Web Animations API pure, zéro dépendance, plusieurs instances sur la même page.
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
Le HTML pré-positionne un .particle-burst centré sur un .particle-center (gradient radial #6366f1 → #8b5cf6, glow violet) et 30 .particle (disques de 6 px en position:absolute). Cet ensemble forme l'état d'attente décoratif : sans animation CSS ni RAF, les particules ne bougent pas. Le CSS ne définit aucune @keyframes — tout le mouvement est délégué à la Web Animations API au moment du clic.
Au clic sur #explosionBtn, l'IIFE calcule la position du bouton relative au conteneur #explosionContainer via getBoundingClientRect(). Elle crée 30 <div class="explosion-particle"> positionnés sur ce point d'origine (position:absolute, left/top en px), colorés en piochant dans le tableau colors (à déclarer par l'intégrateur), puis appendés dans #explosionContainer.
Les trajectoires utilisent une répartition angulaire uniforme : 2π / 30 × index, rayon aléatoire 80 + 80 × Math.random() (entre 80 et 160 px). Chaque particule est animée de translate(0,0) scale(1) vers translate(cx,cy) scale(0) avec l'easing cubic-bezier(0, 0.5, 0.5, 1) — décélération organique qui simule un ralentissement balistique. La durée varie de 600 à 1000 ms par particule (600 + 400 × Math.random()) pour éviter un aspect synchrone. Le callback onfinish supprime chaque div du DOM, sans fuite mémoire.
L'effet ne maintient aucun RAF ni état global : chaque clic est indépendant et plusieurs bursts simultanés sont possibles depuis plusieurs boutons. Le guard t && e && protège silencieusement si les IDs sont absents. Pour instancier plusieurs fois sur la même page, il faut extraire la logique de l'IIFE dans une fonction réutilisable (voir FAQ).
Accessibilité
- prefers-reduced-motion : absent du code — l'IIFE ne vérifie pas
matchMedia('(prefers-reduced-motion: reduce)'). À ajouter manuellement en tête du listener :if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; - Le bouton déclencheur (
#explosionBtn) n'est pas fourni par l'effet — l'intégrateur doit lui ajouter unaria-labelexplicite et s'assurer qu'il est focusable au clavier. - Les 30
.explosion-particlecréés dynamiquement ne portent pasaria-hidden="true"par défaut — les ajouter via JS pour éviter le bruit dans l'arbre d'accessibilité. - Le
#explosionContainern'a niroleniaria-live: l'explosion n'est pas annoncée aux lecteurs d'écran — unaria-live="polite"hors-viewport peut servir si le burst valide une action métier. - Contraste : le
.particle-center(violet #6366f1) sur fond sombre #0a0a0f dépasse le seuil WCAG AA pour les éléments non-textuels (ratio > 3:1).
Compatibilité navigateur
Repose exclusivement sur la Web Animations API (element.animate()) — supportée nativement depuis Chrome 36, Firefox 48, Safari 13.1, Edge 79.
Si <code>element.animate</code> est absent, aucune explosion ne se produit mais la page reste fonctionnelle — le guard <code>t && e &&</code> absorbe silencieusement l'absence des éléments. Pour IE11, un polyfill Web Animations (ex. <code>web-animations-js</code>) est nécessaire.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div id="explosionContainer" style="position:relative;overflow:hidden">
<!-- Visuel décoratif centré (état d'attente) -->
<div class="particle-burst">
<div class="particle-center"></div>
<div class="particle"></div>
<!-- Répéter ×30 .particle -->
</div>
<!-- Contenu overlay + bouton déclencheur -->
<div class="burst-content">
<button id="explosionBtn" aria-label="Déclencher le burst">CTA</button>
</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 |
|---|---|---|
| colors (variable JS globale) | non définie — obligatoire | Tableau hex des couleurs des particules dynamiques. Ex. : const colors = ['#6366f1','#8b5cf6','#ec4899','#f97316']. Sans cette déclaration, le script lève une ReferenceError au premier clic. |
| .particle background | #d946ef | Couleur des 30 disques statiques (état d'attente). Modifier via CSS ou style inline sur chaque .particle pour adapter à la palette de la page. |
| .particle width / height | 6px / 6px | Taille des disques statiques. Augmenter à 10–14 px pour un burst plus dense visuellement (impacte aussi les .explosion-particle si la règle est partagée). |
| .particle-center gradient + box-shadow | #6366f1, #8b5cf6 / glow violet | Couleurs et lueur du point central. Remplacez les valeurs dans la règle .particle-center pour aligner sur la palette brand. |
| rayon d'explosion (ligne JS) | 80 + 80 * Math.random() | Distance min/max des particules en px. Modifier les deux constantes : ex. 40 + 40 * Math.random() pour un burst serré, 120 + 100 * Math.random() pour un burst large. |
| nombre de particules (ligne JS) | 30 | Nombre de .explosion-particle par burst. Ligne : for (let t = 0; t < 30; t++). Réduire à 12–16 pour un effet plus léger sur mobile. |
| durée d'animation (ligne JS) | 600 + 400 * Math.random() | Plage de durée en ms par particule (600–1000 ms). Réduire à 300 + 200 * Math.random() pour un burst plus vif ; augmenter à 900 + 600 * Math.random() pour un effet slow-motion. |
| easing (ligne JS) | cubic-bezier(0, 0.5, 0.5, 1) | Courbe de décélération des particules. ease-out pour un arrêt plus brusque, linear pour une vitesse constante jusqu'à la disparition. |
FAQ
colors est attendu dans la portée globale mais n'est pas inclus dans l'effet — c'est intentionnel pour laisser l'intégrateur définir sa palette. Ajoutez const colors = ['#6366f1','#8b5cf6','#ec4899','#f97316','#22c55e']; dans un <script> placé avant le bundle de l'effet. En module ES, déclarez-le dans le scope global via window.colors = [...] avant l'import.getElementById. Pour plusieurs instances, extrayez la logique dans une fonction : function initBurst(btnId, cntId, palette) { const b = document.getElementById(btnId), c = document.getElementById(cntId); if (!b || !c) return; b.addEventListener('click', () => { /* ...logique burst avec palette... */ }); } et appelez-la pour chaque paire bouton/conteneur avec sa propre palette.click est déclenché par le tap sur iOS et Android Chrome. Le calcul de position via getBoundingClientRect() est fiable sur mobile. La Web Animations API est supportée depuis iOS Safari 13.4 et Android Chrome 36. Aucune gestion spécifique du touch n'est requise.