Un logo qui tourne en boucle sur un écran de chargement, un badge qui grossit légèrement pour attirer l’oeil, une icône qui glisse doucement pour révéler un menu : ces trois effets s’obtiennent avec le même élément SVG natif, <animateTransform>, qui anime une transformation géométrique complète plutôt qu’un simple attribut de couleur ou de taille.
Contrairement à ce que son nom pourrait laisser croire, <animateTransform> ne fait pas tout en même temps. Chaque élément <animateTransform> ne sait animer qu’un seul type de transformation à la fois, une rotation, une mise à l’échelle, une translation ou une inclinaison, jamais plusieurs combinées dans le même élément. C’est un détail qui surprend souvent les développeurs venus du CSS, où une seule propriété transform accepte volontiers plusieurs fonctions à la suite.
Définition
<animateTransform> est un élément d’animation SMIL spécialisé dans l’attribut transform. Il exige un attribut type, qui précise la nature exacte de la transformation animée : rotate, scale, translate, skewX ou skewY. Cette contrainte existe parce qu’une transformation n’est pas une simple valeur numérique interpolable comme une largeur ou une opacité : une rotation se décrit par un angle et un centre, une translation par un déplacement en x et en y, une mise à l’échelle par un facteur, autant de structures de données différentes que le navigateur doit savoir interpoler correctement selon le type déclaré.
Attributs principaux
| Attribut | Rôle |
|---|---|
type | Type de transformation animée : rotate, scale, translate, skewX ou skewY. Obligatoire. |
from / to | Valeurs de départ et d’arrivée, dans le format propre au type choisi, par exemple angle centre-x centre-y pour rotate. |
dur | Durée totale de l’animation. |
repeatCount | Nombre de répétitions, ou indefinite pour une boucle infinie. |
additive | sum permet de cumuler l’effet avec une transformation déjà présente sur l’élément, au lieu de la remplacer. |
Exemple de rendu concret
Voici un <rect> qui tourne indéfiniment autour de son centre, un motif classique pour un indicateur de chargement discret.
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<rect x="40" y="40" width="20" height="20" fill="#2563eb">
<animateTransform
attributeName="transform"
type="rotate"
from="0 50 50"
to="360 50 50"
dur="1s"
repeatCount="indefinite"
/>
</rect>
</svg>Différence avec <animate> et <animateMotion>
On pourrait se demander pourquoi ne pas simplement utiliser <animate> avec attributeName="transform". Historiquement, ce n’était pas possible : <animate> sait interpoler des nombres, des couleurs ou des listes de nombres, mais pas une matrice de transformation qui combine rotation, translation et échelle dans une seule valeur. <animateTransform> a été introduit précisément pour combler ce manque, avec une logique d’interpolation propre à chaque type déclaré via l’attribut type. Depuis SVG2, certains navigateurs acceptent d’animer transform directement avec <animate>, mais <animateTransform> reste le choix le plus fiable et le plus largement compatible. Autre distinction utile : contrairement à <animateMotion>, qui fait suivre un tracé courbe à un élément, <animateTransform> se limite à des transformations géométriques simples appliquées autour d’un point fixe, sans notion de trajectoire.
Piège classique
Le piège le plus fréquent consiste à vouloir combiner plusieurs transformations dans un seul élément, en écrivant par exemple type="rotate scale", une syntaxe qui n’existe tout simplement pas dans la spécification. Pour faire tourner ET grossir un élément en même temps, il faut écrire deux éléments <animateTransform> distincts sur la même cible, l’un avec type="rotate", l’autre avec type="scale", et ajouter additive="sum" sur chacun pour que les deux effets se cumulent au lieu de s’écraser l’un l’autre.
<animateTransform> ne peut animer qu’un type de transformation à la fois : pour combiner une rotation et une mise à l’échelle, il faut deux éléments distincts, chacun avec additive="sum".Cas d’usage réel
Un indicateur de chargement circulaire qui tourne indéfiniment pendant qu’une requête réseau est en cours. Un bouton d’action qui grossit très légèrement au survol pour donner une sensation de matière, un effet souvent recréé plus simplement en CSS mais tout à fait possible en SMIL pur pour un SVG isolé. Une icône de menu qui glisse latéralement pour révéler un panneau caché, sans dépendre d’aucun script externe.
<animateTransform> ?Pas avec un seul élément : chaque <animateTransform> est limité à un type de transformation déclaré dans son attribut type. Pour combiner deux effets, il faut ajouter un second élément avec un type différent et additive="sum" sur les deux, afin que leurs effets s’additionnent au lieu de s’annuler.
type est absent de <animateTransform> ?L’animation ne produit aucun effet visible : type est obligatoire pour que le navigateur sache comment interpréter les valeurs from et to, faute de quoi il ne peut pas déterminer s’il doit calculer une rotation, une translation ou une mise à l’échelle.
C’est souvent une solution plus simple quand le SVG est inline dans une page où le CSS est déjà chargé. Mais <animateTransform> garde un avantage réel : il continue de fonctionner même quand le SVG est isolé, utilisé comme icône autonome, ou intégré dans un contexte où aucune feuille de style externe n’est disponible.