Vous êtes ici : Accueil Blog > Articles > SVG
Sommaire de l'article
  1. Le morphing SVG c'est quoi ?
  2. Exemple avec SMIL
  3. Exemple avec JavaScript
  4. Aller plus loin

Le morphing SVG c'est quoi ?

Tout comme avec CSS, le morphing SVG consiste à animer des formes afin d'obtenir une transformation en manipulant les coordonnées des points constituant des éléments graphique SVG.

Aussi pour que la transformation puisse s'effectuer de manière fluide, il faut que les deux formes possèdent le même nombre de points.

Il est possible de réaliser un morphing SVG en utilisant CSS, mais le support (hormis la propriété clip-path) ainsi que les possibilités sont limités. On préfèrera alors une solution en JavaScript ou en utilisant le langage SMIL.


Exemple avec SMIL

💡 Si vous ne connaissez pas ce langage, rendez-vous dans la rubrique SVG du blog.

Commençons par un exemple simple :

On obtient cette animation grâce à l'élément animate auquel on associe le nom de l'attribut que l'on souhaite animer, à savoir l'attribut d.

On indique la durée de l'animation avec l'attribut dur, ainsi que la répétition indéfinie de l'animation via l'attribut repeatCount.

L'attribut keyTimes va se révéler utile puisqu'il permet de préciser la durée de chaque phase par rapport à la durée totale de l'animation. La première valeur de cet attribut doit être 0 et la dernière 1. Entre les deux, il y a une succession de nombres définis par vous-même compris entre 0 et 1. Cet attribut doit comporter autant de valeurs que l'attribut values.



<svg viewbox="0 0 100 100" width="200" height="200">
<path fill="#7A5FFF">
<animate
attributeName="d" 
dur="3" 
repeatCount="indefinite"
keyTimes="0;0.3;0.5;0.8;1"
values="
M50,0 100,0 100,50 100,100 50,100, 0,100 0,50 0,0;
M50,0 100,0 100,50 100,100 50,100, 0,100 0,50 0,0;
M50,0 75,25 100,50 75,75 50,100, 25,75 0,50 25,25;
M50,0 75,25 100,50 75,75 50,100, 25,75 0,50 25,25;
M50,0 100,0 100,50 100,100 50,100, 0,100 0,50 0,0;"
/>
</path>
</svg>


Prenons maintenant un exemple assez connu, à savoir le bouton play/pause de Youtube qui est un excellent effet de morphing :



<svg width="64" height="64" viewBox="0 0 16 16">
<path fill="#D8D8D8" d="M0,0 L6,0 L6,16 L0,16 L0,0 Z" id="bar1">
<animate href="#bar1"
attributeName="d"
from="M0,0 L6,0 L6,16 L0,16 L0,0 Z"
to="M0,0 L6,3.20001221 L6,12.7999878 L0,16 L0,0 Z"
dur="0.3s"
fill="freeze" 
begin="startAnimation.begin"/>
<animate href="#bar1"
attributeName="d"
from="M0,0 L6,3.20001221 L6,12.7999878 L0,16 L0,0 Z"
to="M0,0 L6,0 L6,16 L0,16 L0,0 Z"
dur="0.3s"
fill="freeze" 
begin="reverseAnimation.begin"/>
</path>
<path fill="#D8D8D8" d="M10,0 L16,0 L16,16 L10,16 Z" id="bar2">
<animate attributeName="d"
from="M10,0 L16,0 L16,16 L10,16 Z"
to="M5.9944458,3.20001221 L15,8 L15,8 L5.9944458,12.7999878 Z"
dur="0.3s"
fill="freeze" 
begin="startAnimation.begin"/>
<animate attributeName="d"
from="M5.9944458,3.20001221 L15,8 L15,8 L5.9944458,12.7999878 Z"
to="M10,0 L16,0 L16,16 L10,16 Z"
dur="0.3s"
fill="freeze" 
begin="reverseAnimation.begin"/>
</path>
<circle cx="0" cy="0" r="32" fill-opacity="0">
<animate dur="0.01s" id="startAnimation" attributeName="r" values="32; 0" fill="freeze" begin="click"/>
<animate dur="0.01s" attributeName="r" values="0; 32" fill="freeze" begin="reverseAnimation.end"/>
</circle>
<circle cx="0" cy="0" r="0" fill-opacity="0">
<animate dur="0.001s" id="reverseAnimation" attributeName="r" values="32; 0" fill="freeze" begin="click"/>
<animate dur="0.001s" attributeName="r" values="0; 32" begin="startAnimation.end" fill="freeze"/>
</circle>
</svg>


Source originale🔗 de l'exemple.


Exemple avec JavaScript :

Dans cet exemple, nous allons utiliser conjointement la librairie graphique JavaScript D3 (on aurait pu aussi utiliser anime.js) ainsi que la librairie Flubber :

💡 L'avantage indéniable de cette solution est de pouvoir s'affranchir du nombre de points de chaque chemin comme il faut le faire avec le langage SMIL (ou en CSS). C'est donc beaucoup plus simple et rapide à mettre en place.



<svg width="100%" height="600" viewBox="0 0 800 600">
<g fill="#7A5FFF" transform="scale(20 20)">
<path class=path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/>
<path class=path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/>
<path class=path d="M23 5.5V20c0 2.2-1.8 4-4 4h-7.3c-1.08 0-2.1-.43-2.85-1.19L1 14.83s1.26-1.23 1.3-1.25c.22-.19.49-.29.79-.29.22 0 .42.06.6.16.04.01 4.31 2.46 4.31 2.46V4c0-.83.67-1.5 1.5-1.5S11 3.17 11 4v7h1V1.5c0-.83.67-1.5 1.5-1.5S15 .67 15 1.5V11h1V2.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5V11h1V5.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5z"/>
<path class=path d="M21 16v-2l-8-5V3.5c0-.83-.67-1.5-1.5-1.5S10 2.67 10 3.5V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/>
<path class=path d="M7 2v11h3v9l7-12h-4l4-8z"/>
<path class=path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
</g>
</svg>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/flubber@0.3.0/build/flubber.min.js"></script>




var pathStrings = Array.from(document.querySelectorAll(".path")).map(d => d.getAttribute("d"));


d3.selectAll(".path")
  .filter(function(d, i) { return i; })
  .remove();

d3.select(".path")
  .style("display", "block")
  .call(animate);

function animate(sel) {
  var start = pathStrings.shift(),
      end = pathStrings[0];

  pathStrings.push(start);

  sel
    .datum({ start, end })
    .transition()
    .duration(1500)
    .attrTween("d", function(d){
      return flubber.interpolate(d.start, d.end, { maxSegmentLength: 0.1 })
    })
    .on("end", function() {
      sel.call(animate);
    });
}


Source, inspiration, ressources :

Article (FR) sur le sujet

Article sur les différentes possibilités pur réaliser du morphing

Plus d'informations sur la librairie Flubber (EN)🔗.

Petit article sur l'animation SMIL(EN)🔗.

Exemple modal morphing🔗 avec JavaScript (Jquery + velocity).

Morphing SVG vs morphing canvas🔗.

Exemple de morphing🔗 original.

Simulation de morphing SVG🔗 avec CSS.

Menu effet wave (vague)🔗 avec JavaScript.

Exemple CSS/SVG Lines morphing🔗.

Un joli bouton de download🔗 effet morphing avec GSAP.

Votre navigateur est trop ancien pour afficher le contenu de ce site.