Atmosphère✨ Premium

Blob Morph

Un blob SVG organique à 8 sommets radiaux se déforme en temps réel sur un flux audio simulé — courbes cubiques Catmull-Rom et halo CSS drop-shadow, sans canvas ni dépendance.

SVGOrganic

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

Hero / Landing — Identité visuelle audio — Blob Morph exemple 1

① Hero / Landing — Identité visuelle audio

QuandSection héro d'une marque musicale, d'un podcast ou d'un outil d'analyse audio — le blob remplace une illustration statique.
PourquoiL'animation organique crée une présence vivante sans déclencher de mouvement brusque, laissant le CTA au premier plan.
RéglagesTaille 240×240 px via CSS (.blob-morph { width: 240px; height: 240px }), baseRadius = 35, data[i] * 20 pour une déformation expressive, dégradé violet-rose.
Composant produit — Widget d'analyse audio live — Blob Morph exemple 2

② Composant produit — Widget d'analyse audio live

QuandDans un dashboard ou une sidebar, pour visualiser l'état d'un flux audio, un niveau ou une métrique qui pulse.
PourquoiLe blob communique « activité en cours » sans chiffres — il complète un graphique ou une jauge sans dupliquer l'information.
RéglagesTaille 80×80 px (format badge), baseRadius = 28, data[i] * 12 (déformation discrète), dégradé teal-cyan, baseFreq = 0,5 pour une réactivité accrue.
Visualiseur vocal — Assistant IA & méditation guidée — Blob Morph exemple 3

③ Visualiseur vocal — Assistant IA & méditation guidée

QuandEn vue principale d'une app de méditation guidée, d'un assistant vocal ou d'un outil speech-to-text — le blob occupe 70 % de l'espace et pulse en rythme avec la voix.
PourquoiÀ grande taille, la déformation Catmull-Rom devient lisible et expressive : chaque sommet réagit à une fréquence audio simulée différente, produisant un effet de respiration spectrale immédiatement perçu.
RéglagesTaille 240×240 px (.blob-morph { width: 240px; height: 240px }), baseRadius = 32, data[i] * 18 (déformation expressive), baseFreq = 0,3 (rythme lent et organique), dégradé violet-indigo (#c084fc → #4f46e5).

Comment ça marche

L'effet anime un unique <path> SVG dont l'attribut d est recalculé à chaque tick requestAnimationFrame. Huit sommets sont répartis à angle égal autour du centre (50, 50) du viewBox 100×100. À chaque frame, chacun reçoit un rayon compris entre 30 et 45 unités SVG selon le signal audio simulé.

Le générateur getSimulatedAudio superpose deux sinusoïdes pour chaque sommet : sin(t × freq × 0,002) × 0,5 + sin(t × freq × 0,003 + i) × 0,3, plus un bruit aléatoire à 20 %. La fréquence propre de chaque sommet croît de 0,5 par indice (baseFreq + i × 0,5, avec baseFreq = 0,3) — les sommets oscillent à des rythmes légèrement différents, simulant une réponse spectrale multi-bande.

Les 8 points calculés sont reliés par des cubiques Bézier dont les points de contrôle sont dérivés d'une formule Catmull-Rom avec tension 0,2 : cp1 = p0 + (p1 − p_{i−1}) × 0,2, cp2 = p1 − (p_{i+2} − p0) × 0,2. La boucle se referme sur le premier sommet (Z), garantissant une silhouette continue sans rupture ni angle mort.

Le rendu visuel utilise fill: url(#blobGradient) (dégradé radial à définir dans les <defs> du SVG) et filter: drop-shadow(rgba(99, 102, 241, 0,5) 0 0 20px) en CSS — le halo suit exactement le contour recalculé à chaque frame sans coût de redraw canvas.

Accessibilité

  • prefers-reduced-motion absent — l'animation tourne en boucle perpétuelle même si l'OS signale une préférence de réduction de mouvement. Ajouter if (matchMedia('(prefers-reduced-motion: reduce)').matches) return; avant le premier requestAnimationFrame.
  • Le <svg> et son <path> n'ont ni aria-hidden ni rôle sémantique — les lecteurs d'écran exposent l'élément avec un très long attribut d. Ajouter aria-hidden="true" sur le SVG.
  • Aucune interaction clavier ni focus natif — l'effet réagit au RAF uniquement, aucun événement utilisateur n'est géré ni documenté.
  • Le dégradé indigo-violet sur fond sombre offre une luminosité perçue correcte pour un élément purement décoratif ; aucun texte n'est superposé dans la démo de base, WCAG 1.4.3 ne s'applique pas.
  • Le gradient #blobGradient est référencé par URL mais non défini dans le snippet fourni — sans bloc <defs> dans le SVG, le fill tombe à noir. Toujours déclarer le <radialGradient> avant usage.

Compatibilité navigateur

Nécessite SVG inline, CSS filter: drop-shadow et requestAnimationFrame — aucun canvas, aucune dépendance externe.

Chrome 104+✓ Complet
Firefox 109+✓ Complet
Safari 15.4+✓ Complet
Edge 104+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Si JavaScript est désactivé, le blob reste figé dans la forme initiale définie dans l'attribut <code>d</code> du HTML — aucune erreur JS, la silhouette SVG reste visible.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="blob-morph" id="blobMorph">
  <svg viewBox="0 0 100 100" aria-hidden="true">
    <defs>
      <radialGradient id="blobGradient" cx="38%" cy="35%">
        <stop offset="0%" stop-color="#a78bfa"/>
        <stop offset="100%" stop-color="#4f46e5"/>
      </radialGradient>
    </defs>
    <path id="blobPath" d="…"/>
  </svg>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

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éfautEffet
points = 8 8 Nombre de sommets radiaux (constante JS). 5–6 = blob très rond, 10–12 = silhouette plus complexe et détaillée.
baseRadius = 30 30 Rayon de repos en unités SVG (viewBox 100). 20 = compact, 40 = volumineux (risque de débordement hors viewBox).
data[i] * 15 15 Amplitude maximale de déformation en unités SVG. 8 = subtil, 25 = très expressif.
baseFreq = 0.3 0.3 3e argument de getSimulatedAudio — fréquence de base des oscillations. 0,1 = lent et organique, 0,8 = rapide et nerveux.
* 0.2 (tension Catmull-Rom) 0.2 Facteur de tension des points de contrôle Bézier. 0,1 = très lisse, 0,4 = courbes plus angulaires.
.blob-morph { width / height } 120px Taille de la boîte de rendu via CSS. Le SVG se met à l'échelle proportionnellement — aucune modification JS nécessaire.
fill: url(#blobGradient) gradient indigo Couleur du blob via <radialGradient> dans les <defs> SVG. Modifiez stop-color pour votre palette.
filter: drop-shadow(…) rgba(99,102,241,.5) 0 0 20px Couleur et rayon du halo CSS. Alignez la couleur RGBA sur votre dégradé de base pour un ensemble cohérent.

FAQ

Remplacez getSimulatedAudio par une lecture de l'AnalyserNode Web Audio API : analyser.getByteFrequencyData(dataArray), puis normalisez (dataArray[i] / 255). Passez ce tableau à la place des valeurs simulées — la mécanique Bézier reste identique.
Pas nativement — getElementById('blobPath') cible un unique élément. Pour plusieurs instances, donnez à chaque <path> un id distinct (blobPath2, blobPath3…) et refactorisez animateBlobMorph pour accepter l'élément en paramètre plutôt qu'en référence globale.
Le handle RAF n'est pas stocké dans une variable exposée. Ajoutez let rafId; rafId = requestAnimationFrame(animate); et appelez cancelAnimationFrame(rafId) pour stopper. Alternativement, la garde if (!blobPath) return; interrompt le cycle si vous supprimez l'élément #blobPath du DOM.