Lightning
Deux éclairs SVG en zigzag aléatoire, double-flash d'écran et lueur drop-shadow violette — boucle autonome par setTimeout, zéro canvas, zéro bibliothèque.
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
L'effet repose sur du DOM pur et des SVG inline, sans canvas. Deux div.lightning-bolt en position: absolute contiennent chacune un <svg viewBox="0 0 100 100"> avec deux <path> superposés : le premier trace le corps de l'éclair en violet (#a5b4fc, stroke-width 2), le second trace un filet blanc par-dessus (stroke-width 1) pour simuler un cœur lumineux. La classe CSS .active déclenche le filter: drop-shadow en deux couches — proche (violet clair 10 px) et lointaine (indigo 20 px).
generateLightningPath() construit un chemin SVG différent à chaque déclenchement : point de départ M(x, 0) avec x ∈ [20, 80], puis 6 à 10 segments L(x ± rand×40, y+step) où x est contraint dans [10, 90]. L'accumulation de déflexions aléatoires produit le zigzag caractéristique d'un éclair naturel — jamais le même tracé deux fois.
Le double-flash d'écran simule la réverbération atmosphérique : à t = 0, la div.lightning-flash (couvre toute la scène, inset: 0) passe à background: rgba(255,255,255,.3) via une transition CSS de 50 ms, puis redescend ; un second flash se produit à t = 100 ms pendant 30 ms supplémentaires. Ces deux impulsions courtes imitent le comportement réel des éclairs.
triggerLightning() se rappelle récursivement via setTimeout(triggerLightning, 1500 + Math.random() × 3000) — intervalle aléatoire entre 1,5 s et 4,5 s. Le second bolt n'apparaît qu'avec une probabilité de 50 % (Math.random() > 0.5). Aucun requestAnimationFrame n'est utilisé par l'éclair lui-même — la boucle setTimeout suffit.
Accessibilité
- prefers-reduced-motion absent : le code ne consulte pas
window.matchMedia('(prefers-reduced-motion: reduce)')— l'animation démarre inconditionnellement. À corriger pour WCAG 2.3.3 : danssetTimeout(triggerLightning, 1000), vérifier la media query et limiter à un seul tir non bouclé si elle est active. - Le conteneur
.lightning-containerne porte niroleniaria-labeldans le HTML fourni — ajouterrole="img" aria-label="Animation d'éclairs aléatoires"pour les lecteurs d'écran. - Les
div.lightning-boltetdiv.lightning-flashne sont pas marquéesaria-hidden="true"— le SVG inline généré dynamiquement pourrait être annoncé par les lecteurs. Ajouter cet attribut sur ces éléments. - La
.lightning-textest un<span>décoratif en bas de scène sans rôle sémantique — remplacer par<p>ou ajouteraria-hidden="true"si purement décoratif. - Pas de mécanisme de pause : l'animation boucle indéfiniment, ce qui contrevient à WCAG 2.2.2 pour toute animation auto-déclenchée de plus de 5 secondes. Ajouter un bouton pause qui coupe le timer (
clearTimeout).
Compatibilité navigateur
Utilise uniquement SVG inline, CSS transitions et setTimeout — pas de canvas, pas de WebGL. Compatibilité très large, y compris les navigateurs mobiles anciens.
Sans support SVG inline (navigateurs > 10 ans), les <code>div.lightning-bolt</code> restent vides — aucune erreur JS fatale, le fond dégradé bleu nuit reste visible.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="lightning-container" id="lightningContainer" role="img" aria-label="Animation d'éclairs aléatoires">
<div class="cloud" style="left: 20%; width: 80px; height: 30px;"></div>
<div class="cloud" style="left: 50%; width: 100px; height: 35px;"></div>
<div class="cloud" style="left: 75%; width: 70px; height: 25px;"></div>
<div class="lightning-flash" id="lightningFlash" aria-hidden="true"></div>
<div class="lightning-bolt" id="lightningBolt1" aria-hidden="true"></div>
<div class="lightning-bolt" id="lightningBolt2" aria-hidden="true"></div>
<!-- Texte ou overlay facultatif -->
<span class="lightning-text">Contenu ici</span>
</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 |
|---|---|---|
| filter: drop-shadow dans .lightning-bolt.active (CSS) | #a5b4fc 10 px / #6366f1 20 px | Couleur et rayon de la lueur. Changez les deux hex pour une autre teinte — ex. bleu électrique : drop-shadow(#38bdf8 0 0 10px) drop-shadow(#0284c7 0 0 20px). |
| background dans .lightning-flash.active (CSS) | rgba(255,255,255,.3) | Intensité du flash d'écran. Réduire à .08 pour un effet discret, monter à .5 pour un impact maximal en hero plein écran. |
| 1500 + Math.random() * 3000 dans triggerLightning() (JS) | 1 500–4 500 ms | Intervalle entre deux éclairs. 800 + Math.random() * 1200 = orage intense ; 5000 + Math.random() * 8000 = éclairs lointains et rares. |
| Math.random() > 0.5 dans triggerLightning() (JS) | probabilité 50 % | Condition d'apparition du second bolt. Remplacer par true pour deux bolts systématiques, par false pour un seul bolt à chaque frappe. |
| (Math.random() - 0.5) * 40 dans generateLightningPath() (JS) | ±20 unités viewBox | Amplitude de déflexion horizontale par segment. * 60 = éclair très tortueux ; * 15 = trait quasi-droit. |
| 6 + Math.floor(Math.random() * 4) dans generateLightningPath() (JS) | 6–9 segments | Nombre de segments du zigzag. 10 + Math.floor(Math.random() * 6) = éclair très détaillé ; 4 = forme simple à 4 breaks. |
| stroke="#a5b4fc" dans createLightningBolt() (JS) | #a5b4fc (violet clair) | Couleur du corps extérieur de l'éclair dans le SVG généré dynamiquement. Modifier aussi stroke="white" (cœur) pour un rendu cohérent. |
FAQ
IntersectionObserver, triggerLightning() continue via setTimeout même hors viewport. Pour économiser le CPU, ajoutez un IntersectionObserver sur .lightning-container qui stocke le timerId et appelle clearTimeout à la sortie, puis relance triggerLightning() à l'entrée.function triggerLightning() { … setTimeout(triggerLightning, …) }, retirez le setTimeout d'amorçage automatique, puis appelez triggerLightning() manuellement sur un événement métier (erreur réseau, validation de formulaire, alerte critique).lightningContainer, lightningBolt1, lightningBolt2 et lightningFlash en dur. Pour plusieurs instances, extrayez la logique dans une fonction createLightningEffect(containerId, flashId, bolt1Id, bolt2Id) et appelez-la une fois par scène avec des IDs distincts.