Wave Form
Onde SVG animée en continu par double synthèse harmonique : deux sinusoïdes à fréquences décalées, recalculées frame par frame via requestAnimationFrame.
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 recalcule le tracé SVG à chaque frame : la fonction animateWaveForm(time) construit une chaîne de commandes L de x=0 à x=300 (pas de 5 px, soit 61 points) et écrit le résultat via wavePath.setAttribute('d', d). Contrairement à une animation CSS ou canvas, c'est de la manipulation DOM directe — le navigateur repeint le <path> sans recréer d'élément ni allouer de buffer.
La forme est la superposition de deux sinusoïdes : une principale (amplitude 30 px, fréquence spatiale 0,05 rad/px, vitesse temporelle 0,005 rad/ms) et une secondaire plus lente et plus large (amplitude 15 px, fréquence 0,02, vitesse 0,003). La phase de chaque onde progresse avec time × speed (time = horodatage rAF en ms), ce qui crée l'illusion d'un défilement continu vers la droite sans jamais boucler explicitement.
Le SVG utilise viewBox="0 0 300 100" et preserveAspectRatio="none" : l'onde s'étire pour remplir n'importe quelle largeur de conteneur sans JS supplémentaire. La couleur du trait est stroke: url(#waveGradient) dans le CSS — la définition du gradient est absente du HTML natif et doit être ajoutée manuellement dans un bloc <defs> à l'intérieur du <svg> pour que le tracé soit visible.
La boucle requestAnimationFrame est partagée avec d'autres effets de la page (audio visualizer, matrix rain…) : animateWaveForm est l'un des dix appels d'une fonction animate(time) centrale. Aucun IntersectionObserver ni mécanisme de pause n'est implémenté — le RAF tourne en continu même hors du viewport.
Accessibilité
- prefers-reduced-motion non supporté : l'animation tourne dans la boucle RAF principale sans vérification de la préférence système — à implémenter manuellement si nécessaire.
- Le
<svg>n'a pas d'attributaria-hidden: les lecteurs d'écran le traversent même si le contenu est purement décoratif. Ajouteraria-hidden="true"sur le<svg>pour un usage décoratif. - Le conteneur
.wave-formn'a nirole="img"niaria-label— à compléter si l'onde véhicule une information sémantique (ex. courbe de données). - Aucune interaction clavier ou pointeur : l'effet est passif, aucun
tabindexni handler d'événement n'est attaché. - La couleur de tracé référence
url(#waveGradient)absent du HTML : le trait peut être invisible sans ajout des<defs>, ce qui donne un fond vide mais ne génère pas d'erreur ni de problème d'accessibilité.
Compatibilité navigateur
Nécessite SVG 1.1 (path + linearGradient) et requestAnimationFrame — supportés nativement dans tous les navigateurs modernes. Zéro dépendance externe.
Si le SVG n'est pas rendu ou que le gradient n'est pas défini, le conteneur <code>.wave-form</code> reste vide sans 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="wave-form" id="waveForm">
<svg viewBox="0 0 300 100" preserveAspectRatio="none">
<!-- gradient absent du code natif : à ajouter pour que le trait soit visible -->
<defs>
<linearGradient id="waveGradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#6366f1"/>
<stop offset="50%" stop-color="#d946ef"/>
<stop offset="100%" stop-color="#06b6d4"/>
</linearGradient>
</defs>
<path id="wavePath"></path>
</svg>
</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 |
|---|---|---|
| url(#waveGradient) — defs SVG | non défini dans le HTML natif | Ajouter <defs><linearGradient id="waveGradient">…</linearGradient></defs> dans le <svg> avant le <path> — sans cela le trait est invisible. |
| stroke-width (CSS .wave-form path) | 3 | Épaisseur du trait en px du viewBox. 1 à 2 pour un filigrane discret ; 5 à 8 pour un aplat graphique. |
| stroke-linecap (CSS .wave-form path) | round | Style des extrémités : butt (carré affleurant), square (carré débordant), round (arrondi). Influe sur la fluidité visuelle aux extrémités. |
| Amplitude primaire : 30 (JS animateWaveForm) | 30 | Hauteur de la vague principale en unités viewBox (0–100). Réduire à 10–15 pour un fond discret ; augmenter à 40 pour une onde prononcée qui touche les bords. |
| Amplitude secondaire : 15 (JS animateWaveForm) | 15 | Hauteur de la vague d'ondulation lente superposée. Mettre à 0 pour une sinusoïde pure ; égaliser avec l'amplitude primaire pour un tracé plus complexe. |
| Vitesse temporelle primaire : 0.005 (JS time * 0.005) | 0.005 | Vitesse de défilement de la vague principale (rad/ms). 0,002 = lent et apaisant ; 0,01 = rapide et énergique. |
| Vitesse temporelle secondaire : 0.003 (JS time * 0.003) | 0.003 | Vitesse de dérive de la vague basse fréquence. Garder inférieure à la vitesse primaire pour un mouvement naturel. |
| Pas spatial : 5 (JS for x += 5) | 5 | Densité de points le long du tracé. Réduire à 2 pour une courbe plus lisse (plus de DOM) ; augmenter à 10 pour alléger les animations rapides. |
FAQ
stroke: url(#waveGradient) mais le <linearGradient id="waveGradient"> n'est pas inclus dans le HTML du JSON. Sans le bloc <defs> dans le SVG, le navigateur ne peut pas résoudre la couleur et n'affiche pas le trait. Ajoutez <defs><linearGradient id="waveGradient" x1="0%" x2="100%"><stop offset="0%" stop-color="#6366f1"/><stop offset="100%" stop-color="#06b6d4"/></linearGradient></defs> à l'intérieur du <svg> avant le <path>.animateWaveForm cible document.getElementById('wavePath') — un seul élément. Pour plusieurs courbes, dupliquez le <path> avec des IDs distincts (wavePath2, etc.), créez une variante de la fonction pour chaque ID, et appelez toutes les variantes depuis la boucle requestAnimationFrame existante. Variez les amplitudes et les vitesses pour différencier visuellement chaque canal.#1e3a8a → #7c3aed → #0f766e par exemple. Évitez les pastels proches du blanc — la transparence SVG ne fournit pas de fond propre. Ajoutez aussi stroke-width: 2 minimum pour conserver la lisibilité.