Accueil

Dessiner avec SVG - sommaire

Vous pouvez me contacter via Facebook (questions, critiques constructives) : page Facebook relative à mon site

SVG & SMIL : balise ANIMATE

Nous allons maintenant réaliser des images SVG animées.

Le SMIL propose plusieurs balises d'animation. La plus important est ANIMATE.

Exemple 1

Le rond grossit progressivement pour atteindre un rayon maximum puis diminue pour atteindre un diamètre minimum et le cycle recommence mais ne se répète que 10 fois.
Dans le même temps il est de plus opaque puis de plus en plus transparent et le cycle reprend mais ne se répète lui aussi de que 10 fois.

Actualisez la page pour redémarrer l'animation !

Le code SVG correspondant

<svg width="50%" height="auto" viewBox ="0 0 400 400" style ="background : yellow" > <circle cx="200" cy="200" fill = 'red' style ="fill-opacity : 0.1;"> <animate attributeName="r" attributeType ="XML" values = "1;200;1" begin ="0s" dur="30s" repeatCount="10" /> <animate attributeName="fill-opacity" attributeType ="CSS" values = "0.1;1;0.1" begin ="0s" dur="30s" repeatCount="10" /> </circle> </svg>

Commentaire du code

La balise circle inclut deux fois la balises animate.
La balise animate est le "couteau suisse" de l'animation en SMIL et comprend de nombreux attributs.

Si il n'y a que deux valeurs pour l'attribut values on peut remplacer ce dernier par les attributs from et to.

Concernant la deuxième balise animate vous constatez que la valeur de l'attribut attributType est "CSS". En effet l'opacité de la forme a été passée en propriété CSS (via l'attribut style) et non pas en attribut.

La balise animate comprend d'autres attributs que nous aborderons par la suite.

Exemple 2

L'animation est ici déclenchée automatiquement, le cycle dure 10 secondes, se répète un nombre indéfini de fois mais la durée globale de l'animation dure 25 secondes !

Le code SVG correspondant

La boule se déplace de gauche à droite et de bas en haut durant 10 secondes puis le cycle reprend.
Mais la durée totale de l'animation est de 25 seondes !
Actualisez la page pour relancer cette animation.

<svg width="100%" height="auto" viewBox ="0 0 900 120" style ="background : lime ;margin :10px auto 10px auto ; box-shadow : 5px 5px 5px gray ;" > <circle r= '10' fill = 'red'> <animate attributeName="cx" values = "10;100;300;500;700;890" begin ="0s" dur="10s" repeatCount="indefinite" repeatDur ="25" attributeType ="XML"/> <animate attributeName="cy" values = "60;10;110;10;110;60" begin = '0s' dur ="10s" repeatCount="indefinite" repeatDur ="25" attributeType ="XML"/> </circle> </svg>

Commentaire

Vous pouvez constater que CSS est sollicité pour dessiner le décor de l'animation (règle de style dans la balise SVG).
Ici j'ai introduit un nouvel attribut : repeatDur (durée globale de l'animation).
Ne confondez pas l'attribut repeatDur avec l'attribut dur (durée d'un cycle). L'attribut repeatDur est prioritaire sur l'attribut repeatCount ! Donc ici malgré repeatCount ="indefinite" l'animation va s'arrêter au bout de 25 secondes.

Remarquez après la fin de l'animation la boule retournent à la position de départ.
Il aurait été préférable que la boule reste à la position atteinte après deux cycles et demi d'animation. Nous verrons la solution plus tard.

Atelier

Le carré s'agrandit puis se rétrécit et le cycle recommence à l'infini.

Le carré est toujours centré dans la zone de dessin dont le viewBox est : "0 0 400 400"

Il faut donc "animer" non seulement les attributs width, height du rectangle mais aussi les attributs x, y (coordonnées du coin supérieur gauche).
Pour chaque balise animate l'attribut values doit contenir 5 valeurs. Par exemple pour l'animation de width la valeur de l'attribut values sera "0;200;400;200;0".

Je ne vous communique pas le code SVG de cette page. A vous de le trouver en vous aidant des deux premières animations avec le SMIL.
Je vous mets un peu sur la voie. le cycle dure 30 secondes. Le conteneur rect doit comprendre quatre fois la balise animate.
Lorsque les dimensions du carré augmentent les valeurs des coordonnées du coin supérieur gauche doivent diminuer et vice-versa.
Ainsi lorsque le côté du carré fait 200 les coordonnées x et y doivent être égales à 100 :(400-200)/2 ! Lorsque le côté du carré est égal à 400 les coordonnées x et y doivent être égales à 0 : (400-400)/2 !

Exemple 3 : animation 3D de clones

Deux boules ombrées se déplacent selon les deux axes en 10 secondes.
Pour la boule blanche l'animation est perpétuelle mais démarre deux secondes après le chargement de la page.
Quant à la boule rouge, l'animation ne dure que 25 secondes et la boule reste à l'emplacement atteint au bout de cette durée. On dit qu'il y a "gel" de l'animation.

Le code SVG : définition de modèles

<svg width="100%" height="auto" viewBox ="0 0 900 120" style ="background : lime ;margin :10px auto 10px auto ; box-shadow : 5px 5px 5px grey ;" > <defs> <g id ="blanche"> <circle r="10" fill ="gray" cx ="4" cy ="4"/> <circle r="10" fill ="white" cx ="0" cy ="0" /> </g> <g id ="rouge"> <circle r="10" fill ="gray" cx ="4" cy ="4"/> <circle r="10" fill ="red" cx ="0" cy ="0" /> </g> </defs>

On définit deux modèles identifiés rouge et blanche.
Notez l'astuce pour créer un effet d'ombre. Chaque objet comprend deux cercles dont un gris (l'ombre).
Il faut bien sur dessiner d'abord l'ombre (cercle gris) puis le rond rouge (ou blanc) afin qu'il soit en premier plan.
Le rond rouge ou blanc devant être décalé de 4 pixels vers le haut et vers la gauche par rapport au rond gris.

Le code SVG (suite) : clonage et animation des clones (extraits)

<use xlink:href ="#rouge"> <animate attributeName="x" values = "-20;100;300;500;700;920" begin ="0s" dur="10s" attributeType ="XML" repeatCount="indefinite" repeatDur ="25s" fill ="freeze" /> <animate attributeName="y" values = "60;0;110;0;110;60" begin = '0s' dur ="10s" attributeType ="XML" repeatCount="indefinite" repeatDur ="25s" fill ="freeze" /> </use> <use xlink:href ="#blanche"> <animate ... begin ="2s" dur="10s" /> <animate ... begin = '2s' dur ="10s" /> </use> </svg>

On clone et on anime chaque modèle avec changement des coordonnées X et Y.

Donc ici la grande nouveauté syntaxique est la balise animate contenue dans la balise use.

Notez l'emploi dans la balise animate de l'attribut fill avec la valeur "freeze" (on parle de "gel de l'animation").

L’attribut fill de animate (ne doit pas être confondu avec l’attribut fill (définissant la couleur de remplissage d’une forme).

Remarque : pour l'animation de la boule blanche (clone du modèle "blanche") je vous communique seulement des bribes de code.
Comme l'animation est perpétuelle (pas de repeatDur et repeatCount à indefinite) l'attribut fill sera ici inutile !

Animations contrôlées par le visiteur

Dans les exemples précédents les animations se déclenchent automatiquement et ne cessent jamais.
Maintenant je vais vous montrer que le visiteur peut contrôler les animations.

Animation déclenchée par le visiteur

Cliquez sur le carré de couleur orange pour démarrer l'animation de ce dernier !

Le code SVG correspondant à cette animation

<svg width="50%" height="auto" viewBox ="0 0 400 400"> <rect x="0" y="0" width ="50" height ="50" fill ="orange"> <animate attributeType ="XML" attributeName="width" values = "50;400;50" begin="click" dur="20s" repeatCount="indefinite"/> <animate attributeType ="XML" attributeName="height" values = "50;400;50" begin="click" dur="20s" repeatCount="indefinite"/> </rect> </svg>

La conteneur rect contient deux fois la balise animate car il y a animation de l'attribut width et de l'attribut height pour le même objet SVG.
Remarquez que dans chaque balise animate l'attribut begin a la valeur click !
Il s'agit donc d'un animation déclenchée (par le visiteur) et non pas d'une animation automatique comme dans la page précédente.
L'attribut repeatCount a la valeur indefinite. Donc dès que l'animation est déclenchée elle se répète de façon infinie.

Animation arrêtée par le visiteur

Cliquez sur le carré de couleur verte pour stopper l'animation de celui-ci !

Le code SVG correspondant

<svg width="50%" height="auto" viewBox ="0 0 400 400"> <rect x="0" y="0" width ="50" height ="50" fill ="green"> <animate attributeType ="XML" attributeName="width" values = "50;400;50" begin="0s" dur="20s" repeatCount="indefinite" end ="click"/> <animate attributeType ="XML" attributeName="height" values = "50;400;50" begin="0s" dur="20s" repeatCount="indefinite" end ="click"/> </rect> </svg>

L'animation sur le carré vert est déclenchée automatiquement (lors du chargement de la page) mais le visiteur peut la stopper à tout moment en cliquant sur l'objet car emploi de l'attribut end avec la valeur click.

Nous avons donc introduit ici un nouvel attribut pour la balise animate : l'attribut end qui est prioritaire sur l'attribut repeatCount : l'animation se répète à l'infini tant qu'on ne clique pas le carré.

Notez qu'après avoir cliqué sur le carré vert ce dernier reprend sa taille initiale car je n'ai pas utilisé l'attribut fill ="freeze" (gel de l'animation).

Animation démarrée et stoppée par le visiteur

Pour démarrer l'animation cliquez sur le bouton vert légendé "go".
Pour arrêter l'animation, cliquez sur le bouton rouge légendé "stop".

L'animation se répète à l'infini : ellipse est de plus en plus large et de plus opaque puis c'est l'inverse.
L'objet garde la taille et l'opacité atteinte lors de l'arrêt de l'animation.

Le code correspondant

Attention ici il s'agit d'une image vectorielle SVG animée qui est insérée dans la page via la balise object

Le code du fichier SVG ci-dessous :

... <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox = "0 0 400 200" width = "100%" height = "auto" > <title>Ellipse animee</title> <desc>Ellipse qui change de rayon horizontal et d'opacite</desc> <ellipse cx="150" cy="75" rx="10" ry="40" fill="olive"> <animate attributeName="rx" begin="go.click" end="stop.click" dur="8s" values="10;110;10" repeatCount="indefinite" fill ="freeze"/> <animate attributeName="fill-opacity" begin="go.click" end="stop.click" dur="8s" values="0.2;1;0.2" repeatCount="indefinite" fill ="freeze"/> </ellipse> <desc>Boutons de commande</desc> <g id="go"> <rect x="85" y="130" height="20" width="60" fill="green"/> <text x="90" y="148" font-size="20" fill="white">GO</text> </g> <g id="stop"> <rect x="150" y="130" height="20" width="60" fill="red"/> <text x="155" y="148" font-size="20" fill="white">STOP</text> </g> </svg>

Il faut dessiner une ellipse et en dessous deux boutons de commande avec texte.
Les boutons de commande sont identifiés "go" et "stop".

La balise ellipse contient donc deux balises animate.
Remarquez la valeur des attributs begin et end dans ces balises : "go.click" "stop.click".

Animer un texte

On peut animer du texte SVG. Par exemple, le faire défiler dans une direction. Animer SVG avec le SMIL !

Le code correspondant

... <style> text{font-family : arial ; font-weight : bold ; font-size : 60px ; text-shadow : 5px 5px 5px grey ; fill : aqua; } ... <h1>SVG : animation d'un texte avec balise animate</h1> <svg width="100%" height="auto" viewBox ="0 0 900 100" style = 'background : linear-gradient( 75deg, navy, aqua,white );'> <text y ='60' width = '600' height = '60'>Animer SVG avec le SMIL ! <animate attributeName="x" values = "-900;900;-900" begin ="0s" dur="20s" repeatCount="indefinite" attributeType ="XML"/> </text> </svg> ...

Commentaire du code CSS et du HTML

CSS : la balise SVG est un élémént HTML a qui on peut appliquer un dégradé linéaire CSS.

SVG : l'animation de texte est un jeu d'enfant: le conteneur text contient la balise animate.
L'animation porte sur l'attribut "x" (position horizontale du texte).
L'attribut values a trois valeurs afin que texte se déplace alternativement de gauche à droite puis de droite à gauche.
Notez que les valeurs de l'attribut values peuvent être négatives afin que le texte disparaisse complètement.

Déplacer des "sprites"

On désigne par "sprites" les personnages d'une animation. Il s'agit souvent de GIF animés.
Dans un canevas SVG on insère deux gifs animés. Ces deux gifs sont déplacés sur l'axe horizontal.

Le code du fichier SVG inséré dans la page

... <svg width="100%" height="auto" viewBox ="0 0 850 240" style = "background : lightgrey ; " ... > <desc>Le décor de l'animation</desc> <rect x = "0" y ="160" width = "850" height = "100" fill = "white" /> <defs> <filter id="flou"> <feGaussianBlur stdDeviation="1" /> </filter> <g id = "sapin" filter = 'url(#flou)'> <polygon points ="55,5 25,75 85,75" fill = "gray"/> <rect x ='50' y = '65' width = '10' height ='40' fill ='gray' /> <polygon points ="50,0 20,70 80,70" fill = "green"/> <rect x ='45' y = '60' width = '10' height ='40' fill ='maroon' /> </g> </defs> <use xlink:href="#sapin" x="0" y="100" /> <use xlink:href="#sapin" x="100" y="120" /> ... <use xlink:href="#sapin" x="700" y="120" /> <desc>Insertion de GIF animés</desc> <image y="175" width = "80" height="60" xlink:href="../images/fondeur.gif"> <animate attributeName="x" values ="0;1000" attributeType ="XML" begin = "0s" dur="20s" repeatCount="indefinite" /> </image> <image y="175" width = "80" height="60" xlink:href="../images/fondeur2.gif"> <animate attributeName="x" values ="0;1000" attributeType ="XML" begin = "0s" dur="18s" repeatCount="indefinite" /> </image> </svg>

Le canevas est d'abord rempli de gris clair via le CSS puis on dessine la neige (rectangle rempli de blanc) et le pâle soleil d'hiver (un cercle jaune flouté).
On clone le groupe "sapin" plusieurs fois (balise use)
Le décor de l'animation est alors réalisé !

On insère ensuite avec la balise image deux gifs animés.
On déplace ces deux images selon un axe horizontal grâce à la balise animate.

Insertion du fichier SVG dans la page

Comme chaque fichier SVG contient des liens vers d'autres images, l'insertion de ces fichiers ne peut se faire qu'avec la balise object.
J'ai donc écrit dans la page web le code suivant :

<object type="image/svg+xml" data="fondeurs.svg" width ="80%"></object>