SVG Path Morph
Un tracé SVG vectoriel, rempli d'un dégradé violet-rose-cyan, qui se déforme à chaque clic de l'étoile au cœur puis au cercle en 0,8 s : les trois formes sont dessinées avec la même suite de commandes (un départ, dix courbes, une fermeture), donc chaque point glisse vers le sien. Net à toutes les tailles, vrai bouton au clavier, nom de la forme annoncé ; forme posée sans déformation si l'utilisateur réduit les animations.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Liquid comprend 31 effets, dont 6 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
Le bouton .svg-morph-btn contient un <svg> de 150 px (repère viewBox="0 0 100 100"), un dégradé linéaire en diagonale et un <path> dont l'attribut d est animé par un élément SMIL : <animate attributeName="d" dur="0.8s" fill="freeze" begin="indefinite">. Au clic, le script règle from sur la forme affichée, to sur la suivante, puis appelle beginElement() : le navigateur fait glisser chaque nombre du tracé de l'une à l'autre, à vitesse constante, et fill="freeze" garde la forme d'arrivée. Le libellé .svg-morph-label prend le nom suivant dans data-names (« Étoile,Cœur,Cercle »).
Pour que l'interpolation existe, les trois tracés ont exactement la même structure : un M, dix courbes C et un Z, en partant du haut et en tournant dans le même sens. Les côtés droits de l'étoile sont des courbes dont les points de contrôle sont posés sur le segment, au tiers et aux deux tiers ; le cœur est découpé en dix morceaux de courbe, ses sommets alignés sur ceux de l'étoile (le creux du haut sur la pointe du haut, la pointe du bas sur le creux du bas) ; le cercle est fait de dix arcs de 36°. Deux tracés de structures différentes, des lignes droites d'un côté et des courbes de l'autre, ne s'interpolent pas : la forme saute à mi-parcours.
Le script garde en mémoire la forme affichée (idx) au lieu de la relire dans l'attribut d : l'animation SMIL ne modifie pas cet attribut, elle le recouvre ; le relire ferait repartir chaque clic de la forme du chargement. L'attribut d est tout de même mis à jour à chaque clic, pour qu'un navigateur sans SMIL affiche la bonne forme. Pendant les 0,8 s de déformation, les clics sont ignorés : la valeur intermédiaire d'une animation SMIL ne se lit pas, et repartir d'une forme finie ferait sauter le tracé.
Accessibilité
- Clavier et lecteurs d'écran : le SVG est dans un vrai
<button>nommé « Forme suivante » (le SVG lui-même est masqué pararia-hidden). Mesuré dans Chromium 151 et Firefox 153 : Tab l'atteint, Entrée et Espace font passer à la forme suivante. Le libellé portearia-live="polite": « Cœur », « Cercle » sont annoncés. Dans Safari, Tab ne s'arrête sur les boutons que si le réglage clavier le demande (ou avec Option+Tab). - Mouvement réduit : sous
prefers-reduced-motion: reduce, le script donne la même valeur àfromet àto: la nouvelle forme s'affiche d'un coup. Mesuré dans les trois moteurs : aucune image intermédiaire. - La forme ne doit pas être la seule information : le libellé dit en texte ce que la forme signifie (« Cœur : 5e achat », « J'adore »), comme dans les exemples.
- Anneau de focus : 2 px rose, décalé de 4 px autour du bouton, visible au clavier seulement (
:focus-visible).
Compatibilité navigateur
SVG + SMIL (<animate> sur l'attribut d) + 2,7 Ko de JavaScript, dont l'essentiel est le texte des trois tracés ; aucune dépendance. Mesuré en temps réel dans Chromium 151, Firefox 153 et WebKit 26 : chaque clic repart de la forme affichée, le tracé change à chaque image pendant 0,8 s, aucun saut. L'animation SMIL de d fonctionne dans tous les navigateurs actuels. La propriété CSS d: path(), qui permettrait une transition CSS, n'existe que dans Chromium et Firefox (absente de WebKit, mesuré) : c'est pourquoi le code passe par SMIL.
Sans JavaScript, l'étoile reste affichée. Sans SMIL, le script écrit quand même la nouvelle forme dans l'attribut d : elle change d'un coup au lieu de se déformer.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0407-root">
<div class="svg-morph-container">
<button type="button" class="svg-morph-btn" aria-label="Forme suivante" data-names="Étoile,Cœur,Cercle">
<svg width="150" height="150" viewBox="0 0 100 100" aria-hidden="true" focusable="false">
<defs><linearGradient id="fx0407-grad">… 3 couleurs</linearGradient></defs>
<path fill="url(#fx0407-grad)" d="M50 5 C… (10 courbes) Z">
<animate attributeName="d" dur="0.8s" fill="freeze" begin="indefinite"></animate>
</path>
</svg>
</button>
<span class="svg-morph-label" aria-live="polite">Étoile</span>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Durée (HTML — dur de <animate>) |
0.8s | Le script lit cette valeur pour savoir combien de temps ignorer les clics : changez-la à un seul endroit. Au-delà de 1,2 s, le bouton paraît lent. |
Accélération (HTML — calcMode, keyTimes, keySplines de <animate>) |
vitesse constante | calcMode="spline" keyTimes="0;1" keySplines=".45 0 .2 1" fait démarrer et finir la déformation en douceur. |
Couleurs (HTML — les trois <stop> du dégradé) |
violet #a855f7, rose #ec4899, cyan #06b6d4 |
Changez aussi l'id du dégradé (fx0407-grad) et le url(#…) du tracé si vous posez plusieurs copies de l'effet sur la page : deux dégradés de même id se confondent. |
Taille (HTML — width / height du <svg>) |
150 × 150 px | Le tracé est vectoriel : 48 px pour une icône, 300 px pour un visuel, sans perte de netteté. Le repère viewBox reste à 0 0 100 100. |
Libellés (HTML — data-names du bouton) |
« Étoile,Cœur,Cercle » | Trois noms séparés par des virgules, dans l'ordre des formes. Le script relit l'attribut à chaque clic. |
Formes (JS — tableau shapes) |
étoile, cœur, cercle | Toute nouvelle forme doit avoir la même structure : M, dix C, Z, en partant du haut et dans le sens des aiguilles d'une montre. Mettez aussi la première forme dans l'attribut d du HTML. |
FAQ
M au point le plus haut, puis dix courbes C qui font le tour dans le sens des aiguilles d'une montre, puis Z. Un côté droit devient une courbe dont les deux points de contrôle sont sur le segment (au tiers et aux deux tiers). Faites correspondre les points remarquables : la n-ième courbe d'une forme doit se trouver à peu près au même endroit du tour que la n-ième courbe des autres, sinon le tracé se vrille pendant la déformation.dur.d: path(…), qui fonctionne dans Chromium et Firefox mais pas dans WebKit (mesuré : CSS.supports répond non), donc pas dans Safari. L'élément <animate> anime l'attribut d dans les trois moteurs. La règle de structure (mêmes commandes, même nombre) vaut pour les deux méthodes.