Les animations SVG
Il existe plusieurs façons d'animer du SVG. Nous allons voir ensemble comment réaliser de superbes animations en utilisant divers langages conjointement à SVG.
Il existe plusieurs façons d'animer du SVG. Nous allons voir ensemble comment réaliser de superbes animations en utilisant divers langages conjointement à SVG.
Il est possible d'animer du SVG à partir d'éléments du langage SMIL. Pour faire simple, SMIL (qui repose sur XML) permet de réaliser ce que ne peut faire CSS, à savoir contrôler les animations, créer des intéractions... Et c'est là tout son intérêt.
Mais avant de nous pencher plus en détails sur ce langage, il est important de préciser que la compatibilité des navigateurs est assez bonne. Sachez également que tous les attributs SVG ne peuvent pas être animés.
Enfin, ce langage a été déprécié sur Chrome et Opera et n'est pas à l'étude pour Edge. Il y a fort à parier que l'avenir de l'animation SVG soit le JavaScript (WAAPI), plus probable que CSS.
Parmi les éléments pouvant être animés, on trouve notamment : svg
, g
, a
, path
, image
...
La liste complète des éléments pouvant être animés
Il existe 4 éléments (il en existait cinq, mais animatecolor
a été déprécié depuis. On utilisera alors animate
) pour créer une animation SMIL :
animate
set
animateTransform
animateMotion
Détaillons ci-dessous chacun de ces quatre éléments :
animate
:Pour créer une animation, nous aurons besoin de spécifier les attributs suivants :
attributName
: spécifie l'attribut ou la propriété CSS à animerattributType
: spécifie le type de noeud à traiterfill
: permet de geler l'animation arrivée à sa finfrom
: la valeur de départ de l'animationto
: la valeur finale à atteindrebegin
: l'instant de départ de notre animationdur
: la durée de notre animationCliquez sur le carré ci-dessous :
<svg width="100%" height="100">
<rect id="anim-carre" width="50" height="50" x="25" y="0" fill="#7A5FFF" />
<animate
href="#anim-carre"
attributeName="x"
from="0"
to="450"
dur="1s"
begin="click"
fill="freeze"/>
</svg>
Vous pouvez remarquer que le carré se déplace de gauche à droite, puis s'arrête. Pour ce faire, on utilise l'attribut fill
auquel on ajoute la valeur freeze
.
<svg width="100%" height="100">
<rect id="votreid" width="50" height="50" x="25" y="0" fill="#0099cc" />
<animate
href="#votreid"
attributeName="x"
from="0"
to="450"
dur="1s"
begin="click"
fill="freeze"/>
</svg>
Cliquez sur le carré ci-dessous :
Vous pouvez remarquer que le carré se déplace de gauche à droite puis revient à son état initial. Ici, nous avons utilisé la valeur remove
.
<svg>
<circle id="votreid" r="30" cx="50" cy="50" fill="orange" />
<animate
href="#votreid"
attributeName="cx"
from="0"
to="450"
dur="1s"
begin="click"
fill="remove" />
</svg>
L'exemple ci-dessous vous montre l'utilisation de l’attribut repeatCount
sur un dégradé lineaire :
<svg>
<circle r="256" cy="256" cx="256" fill="url(#lgrad3)"/>
<defs>
<linearGradient id="lgrad3" x1="0%" y1="100%" x2="100%" y2="0%">
<stop offset="0%"
style="stop-color:hsl(136,70%,41%)">
<animate
attributeName="stop-color"
values="hsl(136,70%,41%);
hsl(60,100%,50%);hsl(136,70%,41%)"
dur="6s"
repeatCount="indefinite"></animate>
</stop>
<stop offset="100%"
style="stop-color:hsl(60,100%,50%)">
<animate attributeName="stop-color"
values="hsl(60,100%,50%);
hsl(136,70%,41%);
hsl(60,100%,50%)"
dur="6s"
repeatCount="indefinite"></animate>
</stop>
</linearGradient>
</defs>
</svg>
Cet attribut peut se définir soit avec un nombre entier supérieur à zéro (qui va indiquer le nombre de fois où l'animation va se répéter), soit avec la valeur indefinite
(indéfiniment).
set
:Il s'agit d'un raccourci de l'élément <animate>
. Il définit simplement un attribut sur une certaine valeur après qu'un intervalle de temps spécifique est passé. On utilisera cet élément lorsque l'on souhaite indiquer des attributs et ou des propriétés qui ne soient pas numériques.
Cliquez sur le carré ci-dessous :
<svg width="200" height="120" viewBox="0 0 200 120">
<rect style="cursor:pointer" id="anim" x="10" y="10" width="80" height="80" fill="#01FF89" >
<set begin="click" attributeName="fill" to="#7A5FFF" />
</rect>
<set begin="reset.click" attributeName="fill" to="#01FF89" href="#anim" />
<text style="cursor:pointer" id="reset" x="80%" y="90%" text-anchor="middle">Reset</text>
</svg>
animateTransform
:Cet élément permet d’animer des objets grâce à l’attribut de transformation SVG <transform>
. Les types pour cet élément sont :
translate
rotate
scale
skewX
skewY
/* Exemple transform rotate */
<svg>
<rect id="carre" width="50" height="50" x="50" y="50" fill="#7A5FFF" />
<animateTransform href="#carre" attributeName="transform" type="rotate" from="0 75 75" to="360 75 75" dur="2s" begin="0" repeatCount="indefinite" fill="freeze" />
</svg>
/* Exemple transform translate */
<svg>
<rect width="200" height="100" fill="#7A5FFF"/>
<animateTransform attributeName="transform" type="translate" from="0" to="-20" dur="2s" repeatCount="indefinite" />
</svg>
/* Exemple transform scale */
<svg>
<rect width="200" height="100" fill="#7A5FFF">
<animateTransform attributeName="transform" type="scale" from="0 0" to="2 2" dur="2s" repeatCount="indefinite" />
</rect>
</svg>
/* Exemple transform skewX */
<svg>
<rect width="200" height="100" fill="#7A5FFF">
<animateTransform attributeName="transform" type="skewX" from="0" to="20" dur="2s" repeatCount="indefinite" />
</rect>
</svg>
/* Exemple transform skewY */
<svg>
<rect width="200" height="100" fill="#7A5FFF">
<animateTransform attributeName="transform" type="skewY" from="0" to="10" dur="2s" repeatCount="indefinite" />
</rect>
</svg>
animateMotion
:L'élément animateMotion
permet de faire se déplacer un objet le long d'un chemin (attribut path
). Il existe deux façons pour dessiner un chemin avec cet attribut.
Soit on renseigne les coordonnées dans l'attribut path
comme dans l'exemple ci-dessous :
<svg width="600" height="300" viewBox="0 0 600 300">
<circle r="20" fill="">
<animateMotion begin="0" dur="5s" repeatCount="indefinite" path="M 0,0 S 100,500 500,0"/>
</circle>
</svg>
Soit on renseigne les coordonnées dans l'attribut mpath
comme dans l'exemple ci-dessous :
<svg width="600" height="300" viewBox="0 0 600 300">
<path id="exemple" d="M 0,0 S 100,500 500,0" style="fill:none"/>
<g>
<circle r="20" fill="var(--theme-couleur)"/>
<animateMotion begin="0" dur="5s" repeatCount="indefinite">
<mpath href="#exemple"/>
</animateMotion>
</g>
</svg>
Tout comme avec des éléments HTML, il est possible d'animer des éléments SVG avec CSS.
Hormis quelques différences, notamment sur le fait que le langage SVG ne repose pas sur le modèle de boîte CSS, vous pouvez appliquer une animation CSS ou une transition à un élément SVG comme vous le feriez avec un élément HTML.
Il faut juste avoir en tête que le point d'origine d'une transformation en SVG se situe en haut à gauche de l'aire de dessin.
Un exemple ci-dessous qui devrait vous éclairer. Dans le premier exemple, vous pouvez constater que le cercle a son point d'origine en haut à gauche. Dans le second exemple, nous avons défini le point d'origine au centre (50% 50%
).
<svg height="128" width="128" viewBox="0 0 112 112">
<style>
circle{
animation: anim-cercle 1s infinite;
transform: scale(0)
}
@keyframes anim-cercle{
to{
transform:scale(1)
}
}
</style>
<circle cx="56" cy="56" r="52" fill="#55ACEE"/>
<path d="M90.46 40.316c-2.403 1.066-4.99 1.787-7.7 2.11 2.768-1.66 4.893-4.285 5.896-7.418-2.59 1.537-5.462 2.652-8.515 3.253-2.445-2.604-5.93-4.232-9.79-4.232-7.403 0-13.408 6.005-13.408 13.41 0 1.05.12 2.073.35 3.055-11.145-.56-21.026-5.897-27.64-14.012-1.154 1.98-1.816 4.286-1.816 6.743 0 4.65 2.37 8.757 5.965 11.16-2.196-.068-4.265-.67-6.072-1.678v.17c0 6.497 4.623 11.916 10.756 13.147-1.124.308-2.31.47-3.532.47-.866 0-1.705-.082-2.523-.238 1.705 5.326 6.656 9.203 12.525 9.312-4.59 3.597-10.37 5.74-16.655 5.74-1.08 0-2.15-.063-3.197-.188 5.93 3.806 12.98 6.025 20.553 6.025 24.664 0 38.152-20.432 38.152-38.153 0-.58-.013-1.16-.04-1.734 2.623-1.89 4.896-4.25 6.693-6.94z" fill="#fff"/>
</svg>
<svg style="border:1px solid red" height="128" width="128" viewBox="0 0 112 112">
<style>
circle{
animation: anim-cercle 1s infinite;
transform: scale(0);
transform-origin: 50% 50%
}
</style>
<circle cx="56" cy="56" r="52" fill="#55ACEE"/>
<path d="M90.46 40.316c-2.403 1.066-4.99 1.787-7.7 2.11 2.768-1.66 4.893-4.285 5.896-7.418-2.59 1.537-5.462 2.652-8.515 3.253-2.445-2.604-5.93-4.232-9.79-4.232-7.403 0-13.408 6.005-13.408 13.41 0 1.05.12 2.073.35 3.055-11.145-.56-21.026-5.897-27.64-14.012-1.154 1.98-1.816 4.286-1.816 6.743 0 4.65 2.37 8.757 5.965 11.16-2.196-.068-4.265-.67-6.072-1.678v.17c0 6.497 4.623 11.916 10.756 13.147-1.124.308-2.31.47-3.532.47-.866 0-1.705-.082-2.523-.238 1.705 5.326 6.656 9.203 12.525 9.312-4.59 3.597-10.37 5.74-16.655 5.74-1.08 0-2.15-.063-3.197-.188 5.93 3.806 12.98 6.025 20.553 6.025 24.664 0 38.152-20.432 38.152-38.153 0-.58-.013-1.16-.04-1.734 2.623-1.89 4.896-4.25 6.693-6.94z" fill="#fff"/>
</svg>
Exemple de transition (passez votre souris) :
<svg class=trans-svg height="128" width="128" viewBox="0 0 112 112">
<style>
.trans-svg path{transition:fill 1s}
.trans-svg:hover path{fill:#55ACEE}
.trans-svg circle{transition:opacity 1s}
.trans-svg:hover circle{opacity:0}
</style>
<circle cx="56" cy="56" r="52" fill="#55ACEE"/>
<path d="M90.46 40.316c-2.403 1.066-4.99 1.787-7.7 2.11 2.768-1.66 4.893-4.285 5.896-7.418-2.59 1.537-5.462 2.652-8.515 3.253-2.445-2.604-5.93-4.232-9.79-4.232-7.403 0-13.408 6.005-13.408 13.41 0 1.05.12 2.073.35 3.055-11.145-.56-21.026-5.897-27.64-14.012-1.154 1.98-1.816 4.286-1.816 6.743 0 4.65 2.37 8.757 5.965 11.16-2.196-.068-4.265-.67-6.072-1.678v.17c0 6.497 4.623 11.916 10.756 13.147-1.124.308-2.31.47-3.532.47-.866 0-1.705-.082-2.523-.238 1.705 5.326 6.656 9.203 12.525 9.312-4.59 3.597-10.37 5.74-16.655 5.74-1.08 0-2.15-.063-3.197-.188 5.93 3.806 12.98 6.025 20.553 6.025 24.664 0 38.152-20.432 38.152-38.153 0-.58-.013-1.16-.04-1.734 2.623-1.89 4.896-4.25 6.693-6.94z" fill="#fff"/>
</svg>
Tout comme il est possible d'animer du SVG avec CSS ou SMIL, il en va de même avec JavaScript.
Parmi les bibliothèques existantes, on peut noter (liste non exhautive) :
Gardez bien en tête que le recours à des bibliothèques peut avoir de lourdes conséquences sur les performances de votre site.