Accueil

Dessiner avec SVG - sommaire

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

Compléments sur la balise ANIMATE

La balise ANIMATE est riche en attributs possibles. Certains de ces attributs n'ont pas encore été évoqués.
Par ailleurs on peut enchainer des animations à condition de donner certaines valeurs à l'attribut "begin".

Enchaînement d'animations portant sur le même élément

Une boule se déplace horizontalement puis c'est sa taille qui change.

Le code correspondant

<svg width = "50%" height="auto" viewBox ="0 0 400 400" style ="background : yellow ;" > <circle cx = "20" cy = "200" r ="20" height="50" fill = 'red'> <animate attributeName ="cx" fill="freeze" values ="20;380;20" begin="0s" dur="8s" repeatDur ="18s" repeatCount="3" attributeType ="XML"/> <animate attributeName ="r" fill="freeze" values ="20;200;20" begin="18s" dur="6s" repeatCount ="indefinite" attributeType ="XML"/> </circle> ...

La boule rouge se déplace de gauche à droite puis de droite à gauche; ce cycle de 8 secondes est répété durant 18 secondes (donc 2fois et quart) car emploi de l'attribut repeatDur qui est prioritaire sur repeatCount !
Puis c'est la deuxième animation qui démarre et qui concerne l'attribut "r".

Les animations portant sur des éléments différents s'enchainent

Exemple

Le code SVG correspondant(extraits)

<svg width = "50%" height="auto" viewBox ="0 0 400 400" style ="background : lime ;" > <rect x = "0" y = "0" width ="0" height="50" fill = 'orange'> <animate ... ="width" fill="freeze" from="0" to="200" begin="0s" dur="5s" id="a1" ... ="XML"/> </rect> <rect x="50" y="100" width="0" height="50" fill ='purple'> <animate ... ="width" fill="freeze" from="0" to="200" begin="a1.end" dur="5s" id="a2" ... ="XML"/> </rect> <rect x="100" y="200" width="0" height="50" fill ='yellow'> <animate ... ="width" fill="freeze" from="0" to="200" begin="a2.end" dur="5s" id ="a3" ... ="XML"/> </rect> <rect x="150" y="300" width="0" height="50" fill ='silver'> <animate ... ="width" fill="freeze" from="0" to="200" begin="a3.end" dur="5s" id ="a4" ... ="XML"/> </rect> </svg>

Il y a quatre animations. Chaque animation consiste à dessiner progressivement (sur 5 secondes) un rectangle de 150 pixels de large et de 50 pixels de haut. Chaque animation n'est répétée qu'une fois ! En effet l'attribut repeatCount est absent !
Les animations s'enchaînent. La deuxième démarre lorsque la première est terminée. La troisième s'enclenche dès que la deuxième est achevée et ainsi de suite.

Notez que dans chaque balise animate on utilise l'attribut id.
Remarquez aussi la valeur de l'attribut begin à partir de la deuxième animation.
Ainsi la première animation est identifiée a1.
La deuxième animation est identifiée a2 et commence lorsque la première est terminée : begin="a1.end"
La troisième animation commence lorsque la deuxième est terminée : begin="a2.end"
Et ainsi de suite ...

Exemple3

La deuxième animation (celle portant sur le rond) démarre seulement lorsque la première animation (celle portant sur le carré) a été exécutée deux fois !

Le code correspondant

<svg width = "50%" height="auto" viewBox ="0 0 400 400" style ="background : lime ;" > <rect x = "0" y = "0" width ="50" height="50" fill = "orange" > <animate attributeName ="x" fill="freeze" values ="0;350;50" begin="0s" dur="5s" id="r1" attributeType ="XML" repeatCount ="indefinite" /> </rect> <circle cx = "20" cy = "200" r ="20" fill = "red" > <animate attributeName ="cx" fill="freeze" values ="20;380;20" begin="r1.repeat(2)" dur="8s" repeatCount="indefinite" attributeType ="XML"/> </circle> ...

la première animation est identifiée r1.
Notez bien la valeur de l'attribut begin dans la deuxième animation : r1.repeat(2) ce qui veut dire lorsque l'animation r1 a connu deux cycles, peut démarrer la suivante.

Attribut 'keytimes' de la balise ANIMATE

Jusqu'à présent la progression de l'animation est constante, linéaire.
Avec l'attribut "keytimes" combiné avec "values" on peut imaginer des accélérations et des ralentis.

Cliquez sur le rectangle pour démarrer l'animation.
N'hésitez pas à cliquer de nouveau sur le rectangle durant l'animation pour observer que l'animation reprend alors au début.

Le code SVG correspondant

<svg width="100%" height="auto" viewBox ="0 0 800 150"> <rect x ='0' y = '50' height ='50' width ='50' fill ="gray"> <animate attributeName ="width" values = "50;400;800" begin ="click" dur ="10s" keyTimes ="0;0.2;1" fill ='freeze' attributeType ="XML" /> </rect> </svg>

La largeur d'un rectangle gris passe de 50 à 800 pixels en 10 secondes. Mais la variation n'est plus linéaire (ou constante) par rapport au temps.
Il faut 2 secondes pour passer de 50 à 400 pixels puis 8 secondes pour passer de 400 à 800 pixels de large.

Vous connaissez déjà l'attribut values. La nouveauté est ici l'attribut keyTimes.
Si vous utilisez uniquement l'attribut values les différents phases de l'animation ont toutes la même durée. Par exemple si la durée totale de l'animation est de 12 secondes et qu'il y a trois phases alors chaque phase dure 4 secondes (le tiers de 12).
Avec l'attribut keyTimes on précise la durée relative de chaque phase par rapport à la durée totale (valeur de l'attribut dur).
L'attribut keyTimes doit comporter autant de valeurs que l'attribut values. La première valeur de cet attribut doit être 0 et la dernière 1. Entre ces deux valeurs indiquez des nombres décimaux compris entre 0 et 1.

Dans l'exemple les valeurs de values sont : "100;150;200" et les valeurs de keyTimes sont : "0;0.2;1"
et la valeur de dur est "10s"
Donc la première phase dure (10 *0.2) = 2 secondes.
la phase 2 dure (10 *(1-0.2)) = 8 secondes.

Attribut 'restart' de la balise ANIMATE

Jusqu'à présent toute animation déclenchée par l'utilisateur peut être stoppée puis redémarrée par un nouveau clic sur l'objet animé. En effet par défaut l'attribut restart a la valeur always !
Dans l'exemple ci-dessous dès que la boule de billard a été lancée l'utilisateur ne peut pas la suspendre.

Exemple

Cliquer sur l'une des deux boules et observez ...

Le code correspondant (à compléter)

A partir des valeurs vous devez retrouver les attributs correspondants.

<svg width="50%" height="auto" viewBox ="0 0 400 500" ... = 'background : green ; border: 10px solid maroon; box-shadow : 10px 10px 10px maroon'> <defs> <g ... ="rouge"> <circle r="10" fill ="gray" cx ="4" cy ="4"/> <circle r="10" ... ="red" ... ="0" ... ="0" /> </g> </defs> <use xlink:href ="#rouge" x ="380" y ="490"> <animate attributeName="y" dur="5s" values = "490;10;490" begin ='click' restart="whenNotActive" keyTimes ="0;0.4;1" attributeType ="XML"/> </use> <use xlink:href ="#rouge" x ="10" y ="10"> <animate ...="y" dur ="5s" ... = "10;490;10" ... ='click' restart="whenNotActive" ... ="0;0.4;1" ... ="XML" /> </use> </svg>

Commentaire du code

CSS : utilisation du CSS pour dessiner le billard avec un effet 3D (propriété "box-shadow").

SVG : on définit une boule rouge ombrée identifiée "rouge".
On clone deux feux fois ce modèle et on anime : balise animate dans conteneur use.

Ces animations ne peuvent pas être suspendues. En effet l'attribut restart à la valeur "whenNotActive".

Ces animations ne sont pas linéaires ; la boule est plus lente au retour qu'à l'aller : 2 secondes pour l'aller et 3 secondes pour le retour grâce à l'utilisation de l'attribut keytimes.
Ce qui correspond à la réalité ; une boule est plus lente en fin de course qu'au début.

Répétition à l'infini d'un enchainement d'animations

Le rendu

Le code SVG correspondant

<svg ... viewBox ="0 0 300 300"> <path d="M 0,150 C 100,0 200,300 300,150" > <animate attributeName="d" attributeType ="XML" from= "M 0,150 C 100,0 200,300 300,150" to = "M 0,150 C 100,100 200,100 300,150" begin="0s;a4.end" dur="5s" id = "a3"/> <animate attributeName="d" attributeType ="XML" from= "M 0,150 C 100,100 200,100 300,150" to = "M 0,150 C 100,0 200,300 300,150" begin="a3.end" dur="5s" id ="a4" /> </path> </svg>

On anime une courbe de Bézier cubique en modifiant les ordonnées des points d'inflexion.

Notez bien la valeur de l'attribut begin pour la première animation : "0s;a4.end" . Ce qui veut dire que cette animation va démarrer non seulement au chargement de la page mais aussi à la fin de l'animation "a4". Donc on crée un cycle : a3 au chargement puis a4 puis de nouveau a3 lorsque a4 est terminé ; donc un cycle est créé.