« Tutoriel SVG dynamique avec SMIL » : différence entre les versions

De EduTech Wiki
Aller à la navigation Aller à la recherche
 
(51 versions intermédiaires par 15 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
<pageby nominor="false" comments="false"/>
<!-- <pageby nominor="false" comments="false"/> -->
{{ebauche}}
{{incomplet}}


== Introduction ==
== Introduction ==


Introduction à SVG dynamique. On introduira quelques éléments du langage SMIL incorporé dans la spécification SVG
Ce petit tutoriel offre une introduction à [[SVG]] dynamique, c-a-d. les animations. On introduira quelques éléments du langage [[:en:SMIL|SMIL]] ("Synchronized Multimedia Integration Language") incorporé dans la spécification SVG.


Objectifs:
Objectifs:
Ligne 12 : Ligne 12 :


Voir aussi:  
Voir aussi:  
* [[SVG]] (Survol, liens, etc.)
* [[Tutoriel SVG statique]] (prérequis)
* [[Tutoriel SVG statique]] (prérequis)
Suite:
* [[Tutoriel SVG/SMIL animations interactives]]
* [[Tutoriel SVG dynamique avec DOM]] (SVG dynamique avec EcmaScript et DOM)
* [[Tutoriel SVG dynamique avec DOM]] (SVG dynamique avec EcmaScript et DOM)


Attention:
Attention:
* Il faut utiliser le navigateur Opera ou encore des navigateurs de dernière génération suivantes: En Mars 2011, Firefox 4, Chrome 10 béta. IE explorer 9 béta ne fait pas du SVG/SML.
* Il faut utiliser le navigateur récent. IE 9 n'implémente pas SVG dynamique.
 
* Les temps associés à l'attribut "dur" ne peuvent être mis en ms (millisecondes) car certains navigateurs n'arriveront pas à le lire, ce qui fera "bugger" votre animation.
Remerciements: J.J.Solari (le traducteur de la recommandation SVG1 du W3C en version française). J’ai "pompé" pas mal de ce texte.
 
== Animation SVG==


Le principe de l'animation et assez simple: Animer veut dire changer un attribut d’un élément SVG dans le temps
Le principe de l'animation est assez simple: animer veut dire changer un attribut d’un élément SVG dans le temps.


Il existe deux méthodes:
Il existe deux méthodes:


(1) Animation de type "XML/SMIL" avec des balises SVG spéciales de type [[:en:SMIL|SMIL]]
(1) Animation de type "XML/SMIL" avec des balises SVG spéciales de type [[:en:SMIL|SMIL]]
* Il faut installer un navigateur de la génération Firefox 4, IE9, Chrome 10 (en béta en hiver 2011), n'importe quelle version de Opéra, ou encore l'ancien plugin ''Adobe SVG Viewer''.
* On peut animer pratiquement chaque attribut avec les éléments d’animation SVG/SMIL (un peu comme en [[VRML]]/[[X3D]]).
* on peut animer pratiquement chaque attribut avec les éléments d’animation SVG/SMIL (un peu comme en [[VRML]]/[[X3D]].
* L’animation SVG/SMIL étend celle de SMIL avec quelques extensions.
* L’animation SVG/SMIL étend celle de SMIL avec quelques extensions.


(2) Animation via le DOM de SVG avec un script
(2) Animation via le DOM de SVG avec un script
* marche avec Firefox 1.5, Opera, et tous les navigateurs récents en 2011.
* Chaque attribut et "style sheet setting" est accessible selon la norme DOM 1 & 2. En plus, il existe un jeu d’interfaces DOM additionnelles.
* Chaque attribut et "style sheet setting" est accessible selon DOM1 & 2. En plus, il existe un jeu d’interfaces DOM additionnelles.
* En gros, on écrit un petit programme ECMAScript (JavaScript) qui modifie les attributs d’éléments ou qui ajoute/enlève des éléments/attributs du DOM.
* En gros, on écrit un petit programme ECMAScript (JavaScript) qui modifie les attributs d’éléments ou qui ajoute/enlève des éléments/attributs du DOM.
Voir: [[Tutoriel SVG dynamique avec DOM]]
Voir: [[Tutoriel SVG dynamique avec DOM]]
Ligne 39 : Ligne 38 :
'''Le principe du "time-based":'''
'''Le principe du "time-based":'''


* L’animation est "time-based" (vs. le "frame-based" de Flash): on indique le départ et la durée d’une animation
* L’animation est "time-based" (vs. le "frame-based" de Flash): on indique le départ et la durée d’une animation.
* On peut animer des attributs de façon indépendante (animations en parallèle)
* On peut animer des attributs de façon indépendante (animations en parallèle).
* Une animation peut se déclencher suite à un geste de l’utilisateur (event) ou encore au temps voulu après le chargement du SVG.
* Une animation peut se déclencher suite à un geste de l’utilisateur (event) ou encore au temps voulu après le chargement du SVG.


=== Les balises pour l’animation SMIL" ===
== Les bases de l'animation ==
 
Les éléments de cette section, sur les principes de l'animation, ont été largement copiés de la traduction [http://www.yoyodesign.org/doc/w3c/smil-animation/ SMIL Animation Recommandation du W3C du 4 septembre 2001]. J'ai juste simplifié quelques passages - [[Utilisateur:Daniel K. Schneider|Daniel K. Schneider]] 27 mars 2012 à 18:23 (CEST).
 
On définit l'animation comme la manipulation en fonction du temps d'un '''attribut''' d'un '''élément cible'''.
 
Les animations définissent '''un début''' et une '''durée simple''' qui peut être répétée. Chaque animation définit une fonction d'animation qui produit une valeur de l'attribut cible à chaque instant dans la durée simple. L'auteur peut définir pendant combien de temps et combien de fois la fonction d'animation devrait se répéter. La durée simple combinée à un comportement de répétition définit la durée active.
 
L´'''attribut cible''' est le nom d'une caractéristique d'un élément cible, soit un '''attribut XML''' contenu dans l'élément, soit une '''propriété CSS''' appliquée à l'élément. Par défaut, l´'''élément cible''' d'une animation sera le '''parent''' de l'élément d'animation.
 
Comme exemple simple, voici la définition d'une animation de forme rectangulaire SVG. Le rectangle variera d'une forme allongée mince à une forme aplatie large.
Le rectangle débute par une largeur de 10 pixels augmentant jusqu'à 100 pixels pendant 10 secondes. Au cours de ces mêmes dix secondes, la hauteur du rectangle varie de 100 pixels à 10 pixels.
 
<source lang="XML">
<rect x="50" y="50" width="10" height="100" style="fill:#CCCCFF;stroke:#000099">
  <animate attributeName="width"  from="10px"  to="100px"
            begin="0s" dur="10s" />
  <animate attributeName="height" from="100px" to="10px"
            begin="0s" dur="10s" />
</rect>
</source>
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/animate-size.svg
 
La cible d'une animation peut être n'importe quel élément dans le document, identifié avec une référence de localisateur [[:en:XLink]].
  <rect id="TAG" .....>
  <animate xlink:href="#TAG"
 
L'exemple suivant montre le principe:
 
<source lang="XML">
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Simple animate example avec une référence xLink</title>
  <desc>Rectangle shape will change</desc>
  <rect id="monRect" x="50" y="50" width="10" height="100" style="fill:#CCCCFF;stroke:#000099"/>
  <animate xlink:href="#monRect" attributeName="width" 
  from="10px"  to="100px" begin="0s" dur="10s" />
  <animate xlink:href="#monRect" attributeName="height"
  from="100px" to="10px"  begin="0s" dur="10s" />
  <text x="50" y="170" style="stroke:#000099;fill:#000099;font-size:14;">
  Hello. Admire the dynamic rectangle. Animation defined with targetElement.</text>
</svg>
</source>
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/animate-size2.svg
Cet exemple montre aussi que l'on peut définir un DocType. Cela facilite l'édition avec un éditeur XML. Notez également qu'il faut définir un espace de nommage ("namespace") pour l'attribut ''href'' qui fait partie du langage ''xlink''.
 
Lorsque l'animation se déroule, elle ne devrait pas changer réellement les valeurs d'attributs dans le modèle objet du [http://www.w3.org/TR/smil-animation/#ref-DOM-Level-2 DOM] ou du CSS Object model. Les animations manipulent donc '''seulement''' la valeur de présentation et ne devraient pas affecter ce qu'on appelle '''la valeur de base''' définie par le DOM ou encore le CSS OM.
 
Lorsqu'une animation se termine, l'effet de l'animation cesse de s'appliquer et la valeur de présentation revient par défaut à la valeur de base. Ceci dit, on peut "prolonger" l'effet d'animation et figer la dernière valeur pour le restant de la durée du document.
 
Dans une animation, on peut soit '''remplacer une valeur''' soit '''ajouter à la valeur''' de base de l'attribut. Dans ce contexte, la valeur de base peut être la valeur du DOM ou le résultat d'autres animations visant aussi le même attribut. Ce concept plus général de valeur de base est appelé valeur ''sous-jacente''. Les animations qui ajoutent à la valeur sous-jacente sont dites '''additives'''. Les animations qui remplacent la valeur sous-jacente sont dites '''non additives'''.
 
== Survol des balises pour l’animation SMIL ==


Il existe 5 balises (éléments XML) pour l’animation.  
Il existe 5 balises (éléments XML) pour l’animation.  


# '''animate''': utilisé pour animer dans le temps un seul attribut ou une seule propriété
# '''animate''': utilisé pour animer dans le temps un seul attribut ou une seule propriété
# '''set''': offre un moyen simple pour le paramétrage de une seule valeur d’attribut pour une durée spécifiée.
# '''set''': offre un moyen simple pour le paramétrage d'une seule valeur d’attribut pour une durée spécifiée.
# '''animateMotion''': entraîne le déplacement d’un élément le long d’un tracé de mouvement.
# '''animateMotion''': entraîne le déplacement d’un élément le long d’un tracé de mouvement.
# '''animateColor''': spécifie une transformation de couleur au cours du temps.
# '''animateColor''': spécifie une transformation de couleur au cours du temps. '''Attention''' ! La balise animateColor est dépréciée ! Il est possible de transformer la couleur en utilisant simplement '''animate '''à l'aide de l'attribut''' fill.'''
# '''animateTransform''': anime un attribut de transformation sur un élément cible, permettant de ce fait aux animations de contrôler translation, changement d’échelle, rotation et/ou inclinaison.
# '''animateTransform''': anime un attribut de transformation sur un élément cible, permettant de ce fait aux animations de contrôler translation, changement d’échelle, rotation et/ou inclinaison.
Pour chacune de ces balises on peut utiliser certains types d'attributs/valeurs que nous introduisons d'abord avec des exemples. Pour ceux qui savent lire une [[Tutoriel DTD|DTD]] nous avons inclus une définition partielle et formelle provenant essentiellement de la [http://www.w3.org/TR/smil-animation/ SMIL Animation W3C Recommendation 04-September-2001]
Une discussion plus systématique des attributs communs se trouve à la fin.


'''Exemple de sensibilisation avec animate'''
'''Exemple de sensibilisation avec animate'''
Ligne 61 : Ligne 119 :
<svg xmlns="http://www.w3.org/2000/svg">
<svg xmlns="http://www.w3.org/2000/svg">


  <rect x="50" y="50" width="200" height="100"
  <rect x="50" y="50" width="200" height="100" style="fill:#CCCCFF;stroke:#000099">
  style="fill:#CCCCFF;stroke:#000099">
   <animate attributeName="x" attributeType="XML"  
   <animate attributeName="x" attributeType="XML"  
           begin="0s" dur="5s" from="50" to="300" fill="freeze"/>
           begin="0s" dur="5s" from="50" to="300" fill="freeze"/>
Ligne 73 : Ligne 130 :
* L’élément <animate /> est simplement placé à l’intérieur de l’élément que l'on veut animer
* L’élément <animate /> est simplement placé à l’intérieur de l’élément que l'on veut animer
* On anime la position horizontale ("x" du rect)
* On anime la position horizontale ("x" du rect)
** ''attributeName'' = "x" indique qu’on anime l’élément "x" du parent
** ''attributeName'' = "x" indique qu’on anime l’attribut "x" du parent "rect"
** ''begin = "0s"'' indique que l’animation commence après 0 secondes
** ''begin = "0s"'' indique que l’animation commence après 0 seconde
** ''dur="5s"'' indique que la durée est de 5 secondes
** ''dur="5s"'' indique que la durée est de 5 secondes
** ''from="50"'' point de départ de X
** ''from="50"'' point de départ de X
Ligne 80 : Ligne 137 :
** ''fill="freeze"'' : l’animation gèle (c.a.d. le rectangle reste où il est)
** ''fill="freeze"'' : l’animation gèle (c.a.d. le rectangle reste où il est)


=== Les attributs communs aux balises d’animation ===
== Animation d'un attribut avec l'élément animate ==


Voici un petit résumé des attributs les plus communs, sans rentrer dans les détails, à utiliser à titre indicatif et ensuite regarder un manuel si nécessaire
L'élément animate permet d'animer un seul attribut.


{{XMLelement|xlink:href &#x3d; "uri"}}
L'exemple suivant montre d'abord comment créer une définition pour un gradient de circle: jaune à l'intérieur (255,255,0) et vert à l'extérieur (0,256,0). Ce gradient est ensuite utilisé dans le ''fill'' de l'ellipse.


SVG utilise le langage XLink pour designer la cible d'animation. Autrement dit, il s’agit d’une référence URI (lien externe ou interne) vers l’élément qui est la cible de cette animation et dont un attribut sera donc modifié au moment voulu. Dit plus simplement:
Ensuite on crée une animation pour agrandir/rapetisser une ellipse. Pour cela, on anime les attributs ''rx'' et ''ry'' (radius en x et y) avec une série de valeurs qui expriment: min, max, min.
* On crée un lien vers l’attribut '''id''' de l’élément à animer
<source lang="XML">
On a pas toujours besoin de se référer à un id pour animer. Si on place des balises d’animation à l’intérieur d’un élément, on se réfère aux attributs de cet élément.
attributeName="rx" values="0%;50%;0%" dur="2s"
 
attributeName="ry" values="0%;50%;0%" dur="2s"
Lorsqu'on utilise xlink, il faut absolument déclarer le namespace "xlink" dans un élément parent. On conseill de le faire dans l'élément racine (&lt;svg&gt;). Certain code SVG que vous pouvez trouver sur Internet et même dans des ouvrages publiés ne le font pas et il faut l'ajouter pour le faire fonctionner dans un navigateur moderne.
 
<source lang="xml">
<svg width="8cm" height="3cm" xmlns="http://www.w3.org/2000/svg">
</source>
</source>


{{XMLelement|attributeName &#x3d; "nom"}}
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/ellipse-growth.svg


Indique le nom de l’attribut qu’il faut animer, par exemple ''x''
<source lang="XML">
<svg version="1.1"
  width="320" height="320"
  xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient id="circleGrad">
      <stop offset="0%"  stop-color="rgb(255, 255, 0)" />
      <stop offset="100%" stop-color="rgb(  0, 255, 0)" />
    </radialGradient>
  </defs>


<source lang="xml">
  <ellipse fill="url(#circleGrad)" stroke="#000"
  <animate attributeName="x" attributeType="XML"  
          cx="50%" cy="50%" rx="50%" ry="50%">
          begin="0s" dur="5s" from="50" to="300" fill="freeze"/>
    <animate attributeName="rx" values="0%;50%;0%" dur="2s"  
      repeatCount="indefinite" />
    <animate attributeName="ry" values="0%;50%;0%" dur="2s"  
      repeatCount="indefinite" />
  </ellipse>
</svg>
</source>
</source>


{{XMLelement|attributType &#x3d; "type"}}
* Original: [http://dev.opera.com/articles/view/svg-or-canvas-choosing-between-the-two/ SVG or Canvas? Сhoosing between the two] (Feb 2010).


Indique le type d’attribut qu’il faut animer, exemple:
'''Définition partielle formelle'''
<source lang="xml">
attributeType = "CSS | XML | auto"
</source>


Ci-dessous, on anime l’attribut "x" (la position x) d’un rectangle et c’est du type XML (SMIL):
* [http://www.w3.org/TR/smil-animation/#animateElement The animate element] (SMIL Animation, W3C Recommendation 04-September-2001)


<source lang="xml">
<source lang="XML">
<rect x="300">
<!ELEMENT animate EMPTY>
<animate attributeName="x" attributeType="XML"
<!ATTLIST animate
  begin="0s" dur="9s" fill="freeze" from="300" to="100" />
  calcMode      (discrete | linear | paced | spline ) "linear"
</rect>
  values        CDATA  #IMPLIED
</source>
  keyTimes      CDATA  #IMPLIED
  keySplines    CDATA  #IMPLIED
  from           CDATA  #IMPLIED
  to             CDATA  #IMPLIED
  by            CDATA  #IMPLIED


{{XMLelement|begin &#x3d; ''begin-value-list''}}
  <!-- Timing attributes -->
  begin          CDATA  #IMPLIED
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED
  repeatDur      CDATA  #IMPLIED
  fill          (remove | freeze) "remove"


Définit quand l’élément devrait commencer (i.e. devenir actif).
  <!-- Common animation attributes -->


La définition de ''begin-value-list'' est compliquée, on peut définir des multiples débuts et fins selon les besoins de synchronisation (cf. la spécification). Dans les cas simples on indique juste un début. L’exemple suivant dit "après 10 secondes" (voir ci-dessous pour d’autres "clock-value" simples:
  attributeName  CDATA  #REQUIRED
  attributeType  CDATA  (CSS | XML | auto) "auto"
  additive      (replace | sum) "replace"
  accumulate    (none | sum) "none"


<source lang="xml">
  <!-- Common event attributes -->
<animate attributeName="x" attributeType="XML"
  onbegin        CDATA  #IMPLIED
         begin="10s" dur="9s" fill="freeze" from="300" to="100" />
  onend         CDATA  #IMPLIED
  onrepeat      CDATA  #IMPLIED
>
</source>
</source>


Plus tard, on verra qu’on peut aussi utiliser l'interaction d'un utilisateur avec un événement (ex. cliquer dessus) pour déclencher un animation.
== Attribut transform ==


{{XMLelement|dur &#x3d;  ''Clock-value'' | "media" | "indefinite"}}
Il est utile de se [[Tutoriel_SVG_statique#Transformations_avec_l.E2.80.99attribut_.22transform.22|rappeler l'attribut transform]], car animer veut souvent dire appliquer une transformation. L'attribut transform définit une liste de définitions de transformations qui sont appliqués à un élément et aux enfants de l'élément. Il peut y avoir plusieurs éléments éléments dans l'attribut transform :


définit la durée de l’animation
* Exemple avec translate et rotate
* ''Clock-value'' spécifie la longueur d’une durée de présentation. La valeur doit être supérieure à 0.
* ''"indefinite"'' spécifie la durée simple comme indéfinie (c’est le défaut si vous ne précisez ni durée ni "média")
* Typiquement on indique des seconds, par ex. 10s = 10 secondes


<source lang="xml">
<source lang="XML" enclose="div">
<animate attributeName="x" attributeType="XML"
<svg width="180" height="200"
        begin="0s" dur="9s" fill="freeze" from="300" to="100" />
  xmlns="http://www.w3.org/2000/svg"  
</source>
  xmlns:xlink="http://www.w3.org/1999/xlink">


Il y a plusieurs façons de définir une "clock-value". Voici qqs. exemples qui marchent:
  <!-- Elément avant la translation et la rotation-->
<path id="etoile_1" d="m81.270004,88.242004l47.042999,0l14.535995,-44.689804l14.535004,44.689804l47.042999,
0l-38.057999,27.619995l14.537994,44.690002l-38.057999,-27.619995l-38.059006,27.619995l14.53801,
-44.690002l-38.057999,-27.619995l0,0z" stroke-width="5" stroke="#000000" fill="#56ffff"/>


* Valeurs d’horloge (''Clock-value'') complètes :
  <!-- Elément avec l'attribut transform -->
02:30:03    = 2 heures, 30 minutes et 3 secondes
50:00:10.25 = 50 heures, 10 secondes et 250 millisecondes


* Valeur d’horloge partielles :
<path id="etoile_1" d="m81.270004,88.242004l47.042999,0l14.535995,-44.689804l14.535004,44.689804l47.042999,
0l-38.057999,27.619995l14.537994,44.690002l-38.057999,-27.619995l-38.059006,27.619995l14.53801,-44.690002l-38.057999,
-27.619995l0,0z" stroke-width="5" stroke="#000000" fill="#56ffff"
transform="translate(30) rotate(45 50 50)"/>


02:33  = 2 minutes et 33 secondes
</svg>
00:10.5 = 10.5 secondes = 10 secondes et 500 millisecondes
 
* Les valeurs Timecount :
 
3.2h    = 3.2 heures = 3 heures et 12 minutes
45min  = 45 minutes
30s    = 30 secondes
5ms    = 5 millisecondes
12.467  = 12 secondes et 467 millisecondes
 
{{XMLelement|end &#x3d; ''end-value-list''}}
 
définit quand on animation se termine
 
{{XMLelement|min &#x3d; Clock-value | "media"}}
 
spéfifit la durée minimale d'animation
 
{{XMLelement|max &#x3d; Clock-value | "media"}}
 
Spécifie la valeur maximum de la durée active de l'animation.
 
Les trois attributs suivants sont moins souvent utilisés et peuvent contraindre la durée active. On peut indiquer une fin, un minimum ou encore un maximum de durée.
 
{{XMLelement|restart &#x3d; "always" | "whenNotActive" | "never"}}
 
* '' always:'' L’animation peut être relancée à tout instant. C’est la valeur par défaut.
* '' whenNotActive:'' L’animation ne peut être relancée que si elle n’est pas active
 
{{XMLelement|repeatCount : numeric value | "indefinite"}}
 
Spécifie le nombre d’itérations de la fonction d’animation. La valeur d’attribut peut être l’une des suivantes :
* '' numeric value '' = valeur numérique « décimale » qui spécifie le nombre d’itérations.
* '' "indefinite"'' = L’animation est définie comme se répétant indéfiniment (i.e. jusqu’à la fin du document).
 
{{XMLelement|repeatDur : Clock-value | "indefinite"}}
 
Spécifie la durée totale pour la répétition.
* '' Clock-value'' = spécifie la durée
* '' "indefinite"'' = l’animation est définie comme se répétant indéfiniment (i.e. jusqu’à la fin du document).
 
 
{{XMLelement|fill : "freeze" | "remove"}}
 
* ''freeze'' = l’effet d’animation F(t) est défini pour geler la valeur d’effet à la dernière valeur de la durée active. L’effet d’animation est « gelé » pour le restant de la durée du document (ou jusqu’à ce que l’animation soit relancée)
* ''remove'' = l’effet d’animation est stoppé (ne s’applique plus) quand la durée active de l’animation est terminée. (à moins que celle-ci ne soit relancée)
 
=== Attributs pour valeurs d’animation interpolés ===
 
Voici un petit résumé sans rentrer dans les détails, à utiliser à titre indicatif
* Le principe de base de ce type de langage (comme dans VRML) est de laisser la possibilité à l’utilisateur d’indiquer simplement au moins 2 valeurs (début/fin) et de laisser la machine gérer le passage entre ces valeurs (interpolation)
 
Définition de la notion d’interpolation
* En animation, calcul des images intermédiaires entre deux formes polynomiales ou encore entre 2 positions sur l’écran.
* Pour la couleur, calcul des couleurs intermédiaires entre deux couleurs
* Il existe ensuite plusieurs modes (cf. ci-dessus)
 
{{XMLelement|calcMode &#x3d; "discrete | linear | paced | spline"}}
 
Spécifie le mode d’interpolation pour l’animation.
* discrete = la fonction d’animation passera d’une valeur à l’autre sans aucune interpolation.
* linear = une interpolation linéaire simple entre les valeurs est utilisée pour le calcul de la fonction d’animation. Sauf pour l’élément ’animateMotion’, c’est la valeur par défaut pour calcMode.
* paced = interpolation qui produit une vitesse de transition égalisée au cours de l’animation.
* spline = [selon la traduction française de la spécification SVG:] interpole à partir d’une valeur de la liste de l’attribut values sur la suivante, selon une fonction temporelle définie par une courbe (spline) de Bézier cubique. Les points de la spline sont définis dans l’attribut keyTimes et les points de contrôle pour chaque intervalle sont définis dans l’attribut keySplines.
 
{{XMLelement|values &#x3d; "<liste>"}}
 
* Une liste d’une ou plusieurs valeurs, séparées par des points-virgules.
 
{{XMLelement|keyTimes &#x3d; "<liste>"}}
 
* Une liste de valeurs de temps, séparées par des points-virgules, utilisée pour le contrôle de la vitesse de défilement de l’animation. Chaque temps de la liste correspond à une valeur dans la liste de l’attribut values et définit quand la valeur est utilisée dans la fonction d’animation.
* Chaque valeur de temps, dans la liste de l’attribut keyTimes, est spécifié en valeur décimale comprise entre 0 et 1 (inclus), représentant un décalage proportionnel dans la durée simple de l’élément d’animation.
 
{{XMLelement|keySplines &#x3d; "<liste>"}}
 
* Un jeu de points de contrôle de Bézier, associé avec la liste de l’attribut keyTimes, définissant une fonction de Bézier cubique qui contrôle l’allure du défilement des intervalles.
 
=== Attributs qui contrôlent la succession des animations ===
 
{{XMLelement|additive &#x3d; replace | sum}}
 
* Cette balise est utilisée lorsqu’on effectue plus qu’une seule transformation en même temps.
* sum = l’animation va s’ajouter à la valeur sous-jacente de l’attribut et des autres animations de faible priorité.
* replace = l’animation va surclasser la valeur sous-jacente de l’attribut et des autres animations de faible priorité. C’est la valeur par défaut
* Si une simple animation « agrandir » peut accroître la largeur d’un objet de 10 pixels ....
 
<source lang="xml">
<rect width="20px" ...>
  <animate attributeName="width" from="0px" to="10px" dur="10s"
            additive="sum"/>
</rect>
</source>
</source>


... il est souvent pratique, pour des animations répétées, de la construire sur la base de résultats précédents qui s’accumulent avec chaque itération. L’exemple suivant fait que le rectangle continue à grandir au fur et à mesure de la répétition de l’animation :
Les éléments de la liste transform sont séparées par des blancs et / ou des virgules, et sont appliquées de droite à gauche.


<source lang="xml">
* translate : permet de faire une translation. Pour l'utilisation, il faut inscrire translate ( x, (y)). Le y n'est pas obligatoire, s'il n'est pas indiqué il prendra la valeur de 0.
<rect width="20px" ...>
* rotate : permet de faire une rotation. Il prend en paramètre l'angle ou les angles de rotation en degrés.
  <animate attributeName="width" from="0px" to="10px" dur="10s"
* scale : permet de changer d'échelle. Il prend deux paramètres : le changement d’échelle sur les abscisses en premier et en second sur les ordonnées.Il n'est pas obligatoire d'indiquer 2 paramètres, dans ce cas le second prendra la même valeur que le premier paramètre.
            additive="sum" accumulate="sum" repeatCount="5"/>
* ...
</rect>
</source>
 
À la fin de la première répétition, le rectangle a une largeur de 30 pixels, à la fin de la deuxième une largeur de 40 pixels et à la fin de la cinquième une largeur de 70 pixels.
 
{{XMLelement|accumulate &#x3d; "none | sum"}}
 
* C.f. la spécification
 
'''Exemple : Deltas d’une animation'''
 
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/inc-growth.svg
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/
 
* À la fin de la première répétition, le rectangle a une largeur de 40 pixels, à la fin de la deuxième une largeur de 60 pixels et à la fin de la cinquième une largeur de 120 pixels.
* L’animation totale dure 5 * 5 s = 25 secondes
* On construit sur des résultats précédents, qui s’accumulent avec chaque itération:
<source lang="xml">
 
<rect x="50" y="50" width="20px" height="20px"
  style="fill:yellow;stroke:black">
  <animate attributeName="width" dur="5s" repeatCount="5"
          fill="freeze"   
          from="0px" to="20px"
          additive="sum" accumulate="sum"/>
</rect>
 
<text x="55" y="90" style="stroke:#000099;fill:#000099;fontsize:24;">
  Hello. Let’s show a growing rectangle ! </text>
</source>
 
 
=== L'élément animate ===
 
Voici un autre exemple, pris de [http://dev.opera.com/articles/view/svg-or-canvas-choosing-between-the-two/ SVG or Canvas? Сhoosing between the two] (Feb 2010).
 
<source lang="XML">
<svg version="1.1"
  width="320" height="320"
  xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient id="circleGrad">
      <stop offset="0%"  stop-color="rgb(255, 255, 0)" />
      <stop offset="100%" stop-color="rgb(  0, 255, 0)" />
    </radialGradient>
  </defs>
 
  <ellipse fill="url(#circleGrad)" stroke="#000" cx="50%"
  cy="50%" rx="50%" ry="50%">
    <animate attributeName="rx" values="0%;50%;0%" dur="2s"
      repeatCount="indefinite" />
    <animate attributeName="ry" values="0%;50%;0%" dur="2s"
      repeatCount="indefinite" />
  </ellipse>
</svg>
</source>


=== L’élément set ===
== Transformer un dessin avec l'élément set ==


De la spécification: L'élément 'set' offre un moyen simple pour le paramétrage d’une seule valeur d'attribut pour une durée spécifiée. Il gère tous les types d'attributs, y compris ceux qui ne peuvent pas être raisonnablement interpolés, comme les chaînes et les valeurs booléennes.
De la spécification: L'élément 'set' offre un moyen simple pour le paramétrage d’une seule valeur d'attribut pour une durée spécifiée. Il gère tous les types d'attributs, y compris ceux qui ne peuvent pas être raisonnablement interpolés, comme les chaînes et les valeurs booléennes.
Ligne 318 : Ligne 251 :
* L'élément 'set' n'est pas additif. Donc les attributs qui contrôlent la succession des animations” ne marcheront pas.
* L'élément 'set' n'est pas additif. Donc les attributs qui contrôlent la succession des animations” ne marcheront pas.


'''Exemple: Simple animation avec set et animation''
'''Exemple: Simple animation avec set et animation'''


* http://tecfa.unige.ch/guides/svg/ex/anim-trans/simple-set.svg
Le premier rectangle (bleu) ci-dessous apparaît après 4 secondes. Sa propriété ''visibility est d'abord ''hidden'', ensuite ''visible''.
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/ (répertoire)


<source lang="xml">
<source lang="xml">
<rect x="50" y="50" width="200" height="100"               style="fill:#CCCCFF;stroke:#000099"
 
<rect x="50" y="50" width="200" height="100" style="fill:#CCCCFF;stroke:#000099"
     visibility ="hidden" >
     visibility ="hidden" >
     <set attributeName="visibility" attributeType="XML"  
     <set attributeName="visibility" attributeType="XML"  
Ligne 336 : Ligne 269 :
</source>
</source>


=== AnimateColor ===
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/simple-set.svg
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/ (répertoire)
 
'''Définition partielle formelle'''
 
<source lang="XML">
<!ELEMENT set EMPTY>
<!ATTLIST set
  attributeName  CDATA  #REQUIRED
  attributeType  CDATA  (CSS | XML | auto) "auto"
  to            CDATA  #IMPLIED
<!-- Timing attributes -->
  begin          CDATA  #IMPLIED
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED
  repeatDur      CDATA  #IMPLIED
  fill          (remove | freeze) "remove"
>
</source>
 
== Animation de couleur avec animate ==


'''Exemple: Animation d’une couleur'''
'''Exemple: Animation d’une couleur'''
Ligne 365 : Ligne 320 :
* la tige va d’abord de from="#CC9933" à to="#000000" (après 1s et pendan 4sec) <br /> et ensuite de #000000" à "#CC9933".
* la tige va d’abord de from="#CC9933" à to="#000000" (après 1s et pendan 4sec) <br /> et ensuite de #000000" à "#CC9933".


=== AnimateTransform===
'''Définition partielle formelle'''
 
<source lang="XML">
<!ELEMENT animate EMPTY>
<!ATTLIST animate
  <!-- Timing attributes -->
  begin          CDATA  #IMPLIED
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED
  repeatDur      CDATA  #IMPLIED
  fill          (remove | freeze) "remove"
 
  <!-- Common animation attributes -->
  attributeName  CDATA  #REQUIRED
  attributeType  CDATA  (CSS | XML | auto) "auto"
  additive      (replace | sum) "replace"
  accumulate    (none | sum) "none"
 
  calcMode      (discrete | linear | paced | spline ) "linear"
  values        CDATA  #IMPLIED
  from          CDATA  #IMPLIED
  to            CDATA  #IMPLIED
  by            CDATA  #IMPLIED
  keyTimes      CDATA  #IMPLIED
  keySplines    CDATA  #IMPLIED
>
</source>
 
== Interpolation de forme avec AnimateTransform ==


'''Exemple : Simple rotation'''
'''Exemple : Simple rotation'''
Ligne 391 : Ligne 376 :


Cet exemple moche fait une rotation
Cet exemple moche fait une rotation
* on anime l’attribut "rotate" du <g> (qui est au départ est à son défaut, c.à.d. sans rotation)
* on anime l’attribut "rotate" du <g> (qui au départ est à son défaut, c.à.d. sans rotation)
* on indique juste deux degrés pour la rotation (0 au départ et 360 à la fin). Le reste est interpolé par la machine.
* on indique juste deux degrés pour la rotation (0 au départ et 360 à la fin). Le reste est interpolé par la machine.


=== AnimateMotion ===
'''Définition partielle formelle'''


'''Exemple: Animation d’un mouvement le long d’un tracé'''
<source lang="XML">
<!ELEMENT animateTransform EMPTY>
<!ATTLIST animateTransform
  type          (translate | scale | rotate | skewX | skewY)
  <!-- qqs. attributs en plus -->
  values        CDATA  #IMPLIED
  from          CDATA  #IMPLIED
  to            CDATA  #IMPLIED
  by            CDATA  #IMPLIED
  begin          CDATA  #IMPLIED
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
>
</source>
 
== Interpolation de movement avec AnimateMotion ==
 
'''Exemple: Animation de mouvement simple'''
 
Le chemin était fait rapidement avec [http://svg-edit.googlecode.com/svn/trunk/editor/svg-editor.html SVG-Edit] avec l'outil "path". Dans le code SVG, on a juste ajouté un  "Z" a la fin pour fermer la boucle.
<source lang="XML">
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Simple Motion animation example</title>
 
<rect x="15" y="5" rx="5" ry="5" width="20" height="10" style="fill:#CCCCFF;stroke:#000099">
  <animateMotion dur="6s" repeatCount="indefinite" rotate="auto">
      <mpath xlink:href="#path1"/>
    </animateMotion>
  </rect>
<path id="path1" d="m21,39c0,0 46,-44 79,-1c33,43 62,58 97,26c35,-32 86,-30 86,
      -31c0,-1 61,-9 29,43c-32,52 -19,51 -87,51c-68,0 -158,-5 -158,-6c0,-1 -40,-11 -41,-12 Z"
      stroke-width="5" stroke="#000000" fill="none"/>
</svg>
</source>
 
* Fichier: http://tecfa.unige.ch/guides/svg/ex/html5/animation/simple-motion-auto-rotate.svg
 
 
'''Exemple: Animation d’un mouvement le long d’un tracé très précis'''


* http://www.yoyodesign.org/doc/w3c/svg1/animate.html (original)
* http://www.yoyodesign.org/doc/w3c/svg1/animate.html (original)
Ligne 402 : Ligne 427 :
* http://tecfa.unige.ch/guides/svg/ex/svg-w3c/
* http://tecfa.unige.ch/guides/svg/ex/svg-w3c/
* L’élément ’animateMotion’ entraîne le déplacement d’un élément appelé le long d’un tracé de mouvement.
* L’élément ’animateMotion’ entraîne le déplacement d’un élément appelé le long d’un tracé de mouvement.
* A ne pas confondre avec des simples translations, rotations etc. qu’on fait avec ''animate'' ou ''animateTransform''.
* A ne pas confondre avec de simples translations, rotations etc. qu’on fait avec ''animate'' ou ''animateTransform''.


[[Image:svg-dyn-1.png|Copie d'écran]]
[[Image:svg-dyn-1.png|Copie d'écran]]
Voici la définition d’un triangle et de son animation le long d’un chemin
Voici la définition d’un triangle et de son animation le long d’un chemin


Ligne 425 : Ligne 451 :
   <circle cx="400" cy="250" r="17.64" fill="blue"  />
   <circle cx="400" cy="250" r="17.64" fill="blue"  />


   <!-- Voici un triangle qui se deplacera sur le trace de mouvement.
   <!-- Voici un triangle qui se déplacera sur le trace de mouvement.
       Il est defini avec une orientation verticale, la base du triangle etant
       Il est defini avec une orientation verticale, la base du triangle etant
       centree horizontalement juste au-dessus de l'origine. -->
       centree horizontalement juste au-dessus de l'origine. -->
Ligne 442 : Ligne 468 :
   <circle cx="100" cy="250" r="17.64" fill="blue"  />
   <circle cx="100" cy="250" r="17.64" fill="blue"  />
</source>
</source>
Alors il faut définir '''tous''' les points du chemin en fonction de la '''position initiale''' de l'objet ! Ici le cercle est à ''x=100'' et ''y=250''. Si vous voulez le déplacer le cercle de 100 vers la droite et de 100 vers le haut, vous devez indiquez comme point de chemin ''100,100'', c'est-à-dire '''juste le déplacement''', il ne faut pas faire l'addition! Pour les points suivants, c'est toujours la même chose : c'est par rapport à la position initiale (et non pas par rapport à la position précédente)!  
Alors il faut définir '''tous''' les points du chemin en fonction de la '''position initiale''' de l'objet ! Ici le cercle est à ''x=100'' et ''y=250''. Si vous voulez déplacer le cercle de 100 vers la droite et de 100 vers le haut, vous devez indiquer comme point de chemin ''100,100'', c'est-à-dire '''juste le déplacement''', il ne faut pas faire l'addition! Pour les points suivants, c'est toujours la même chose : c'est par rapport à la position initiale (et non pas par rapport à la position précédente)!  
   
   
La représentation d'un chemin
La représentation d'un chemin
Ligne 458 : Ligne 484 :
* Z : terminaison du chemin ou path.
* Z : terminaison du chemin ou path.


=== Animations combinées ===
'''Définition partielle formelle'''
 
<source lang="XML">
<!ELEMENT animateMotion EMPTY>
<!ATTLIST animateMotion


* Il est assez difficile de synchroniser un script compliqué, par contre faire des animations en parallèle est simple (il suffit de regarder les secondes ...)
  <!-- Timing attributes -->
  begin          CDATA  #IMPLIED
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED
  repeatDur      CDATA  #IMPLIED
  fill          (remove | freeze) "remove"
 
  additive      (replace | sum) "replace"
  accumulate    (none | sum) "none"
  calcMode      (discrete | linear | paced | spline) "paced"
  values        CDATA  #IMPLIED
  from          CDATA  #IMPLIED
  to            CDATA  #IMPLIED
  by            CDATA  #IMPLIED
  keyTimes      CDATA  #IMPLIED
  keySplines    CDATA  #IMPLIED
  path          CDATA  #IMPLIED
  origin        (default) "default"
/>
</source>
 
== Animations combinées ==
 
Il est assez difficile de synchroniser un script compliqué. Par contre, créer des suites d'animations ou des animations en parallèle est assez simple.  


'''Exemple: animation combinée'''
'''Exemple: animation combinée'''


A la place de définir l'animation selon des temps en secondes:
A la place de définir l'animation selon des temps en secondes, il est possible de définir des séquences d'événements, en faisant démarrer un événement à la fin de l'événement précédent avec la construction suivante.
 
<source lang="xml">begin="événementprécédent.end"</source>
 
L'exemple suivant utilise des secondes (pas très pratique pour créer des suites compliquées)
<source lang="xml">
<source lang="xml">
                <rect id="carre" height="67" width="67" stroke-width="5" stroke="#000000" fill="#ffffff">
<rect id="carre" height="67" width="67" stroke-width="5" stroke="#000000" fill="#ffffff">
                    <animate attributeName="x" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="300" to="0"/>  
<animate attributeName="x" attributeType="XML" begin="0s" dur="6s"  
                    <animate attributeName="y" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="100" to="0"/>
          fill="freeze" from="300" to="0"/>  
                    <animateColor attributeName="fill" attributeType="CSS" from="#ffffff" to="red" begin="2s" dur="4s" fill="freeze" />
<animate attributeName="y" attributeType="XML" begin="0s" dur="6s"  
                </rect>
          fill="freeze" from="100" to="0"/>
<animateColor attributeName="fill" attributeType="CSS" from="#ffffff" to="red"
          begin="2s" dur="4s" fill="freeze" />
</rect>
</source>
</source>


il est possible de définir des séquences d'événements, en faisant démarrer un événement à la fin de l'événement précédent avec <source lang="xml">begin="événementprécédent.end"</source>
L'exemple implémente une vraie suite où la 2ème animation démarre lorsque la première est terminée.
 
Exemple:
<source lang="xml">
<source lang="xml">
                <rect id="carre" height="67" width="67" stroke-width="5" stroke="#000000" fill="#ffffff">
<rect id="carre" height="67" width="67" stroke-width="5" stroke="#000000" fill="#ffffff">
                    <animate attributeName="x" attributeType="XML" begin="0s" dur="6s" fill="freeze" from="300" to="0"/>  
  <animate attributeName="x" attributeType="XML" begin="0s" dur="6s"  
                </rect>
          fill="freeze" from="300" to="0"/>  
</rect>


                <rect id="carre2" height="80" width="23" stroke-width="5" stroke="#000000" fill="#ffffff">
<rect id="carre2" height="80" width="23" stroke-width="5" stroke="#000000" fill="#ffffff">
                    <animate attributeName="x" attributeType="XML" begin="carre.end" dur="6s" fill="freeze" from="300" to="0"/>  
  <animate attributeName="x" attributeType="XML" begin="carre.end"  
                </rect>
          dur="6s" fill="freeze" from="300" to="0"/>  
</rect>
</source>
</source>


Ligne 491 : Ligne 553 :
'''Exemple: animation combinée'''
'''Exemple: animation combinée'''


* http://www.yoyodesign.org/doc/w3c/svg1/animate.html (original, home de la traduction française de la spécification SVG 1.0)
Cet exemple est tiré de [http://www.yoyodesign.org/doc/w3c/svg1/animate.html traduction française de la spécification SVG 1.0]
* http://tecfa.unige.ch/guides/svg/ex/svg-w3c/anim01.svg
 
* http://tecfa.unige.ch/guides/svg/ex/svg-w3c/
Il contient plusieurs animations:
* Plusieurs animations:
* largeur/hauteur du rectangle jaune
** largeur/hauteur du rectangle jaune
* déplacement de l’origine du rectangle jaune (vers le haut à gauche)
** déplacement de l’origine du rectangle jaune (vers le haut à gauche)
* animation de couleur pour le texte
** animation de couleur pour le texte
* déplacement le long d’un chemin du texte
** déplacement le long d’un chemin du texte
* rotation du texte
** rotation du texte
* agrandissement du texte
** agrandissement du texte


<source lang="xml">
<source lang="xml">
Ligne 557 : Ligne 618 :
   </text>
   </text>
  </g>
  </g>
</svg>
</source>
Exemple en ligne:
* http://tecfa.unige.ch/guides/svg/ex/svg-w3c/anim01.svg
* http://tecfa.unige.ch/guides/svg/ex/svg-w3c/ (répétoire)
'''Exemple: animation combinée (étudiant R2D2 et D.K.Schneider)'''
Voici un autre exemple assez complexe qui combine quelques techniques et balises différentes.
L'idée était de partir sur l'affichage de carré pour l'affichage d'un "tube" de temps. Le problème était le suivant. L'animation ne semblait pas vouloir repartir.
*chaque carré est égal à 5 secondes, il faut regarder la minute au complet pour voir le problème.
[http://tecfa.unige.ch/guides/svg/ex/anim-trans/chain-animation.svg chain-animation.svg] (montre le problème)


Ainsi, pour résoudre le problème, deux solutions se sont profilées:
* [http://tecfa.unige.ch/guides/svg/ex/anim-trans/chain-animation1.svg chain-animation1.svg] (solution simple. utilisant des values, sans chaine)
* [http://tecfa.unige.ch/guides/svg/ex/anim-trans/chain-animation2.svg chain-animation2.svg] (solution avec chaine, il faut en plus utiliser un set)
*Dans la première, la solution provient de l'usage des [[Tutoriel_SVG_dynamique_avec_SMIL#Animation_d.27un_attribut_avec_l.27.C3.A9l.C3.A9ment_animate|values]] :
<source lang="xml">
<?xml version="1.0"?>
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
 
  <title>Slow LEDs</title>
     
  <description>Let's turn the biest</description>
  <g transform="translate(0,100)">
    <g transform="rotate(-90)">
      <rect x="0" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="0" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
     
      <rect x="10" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;1;1;1;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="10" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;1;1;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="20" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;1;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="20" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="30" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="30" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="40" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;0;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="40" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="50" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="50" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="60" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;0;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
      <rect x="60" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;0;0;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
     
    </g>
  </g>
</svg>
</svg>
</source>
</source>


== Interactivité avec SVG ==
*Dans la deuxième solution, qui semble fonctionner '''uniquement sur firefox''', c'est la combinaison de ma solution avec l'ajout de la balise "[[Tutoriel_SVG_dynamique_avec_SMIL#Transformer_un_dessin_avec_l.27.C3.A9l.C3.A9ment_set|set]]" qui permet le redémarrage.


=== Principe et gestion des événements ===
<source lang="xml">
<?xml version="1.0"?>
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
 
  <title>Slow LEDs</title>
  <desc></desc>
     
  <g transform="translate(0,100) rotate(-90)">
      <rect x="0" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="0" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
     


L’interactivité et donc la gestion des événements ressemble au principe des GUI modernes (par exemple en JavaScript ou ActionScript) et elle est conforme à la spécification DOM2.
      <g stroke="black">


Types d’interactivité:
<rect x="10" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim1" attributeName="opacity" from="0" to="1" attributeType="XML" begin="0s; anim12.end+1s" dur="2s" fill="freeze"/>   
</rect>
<rect x="10" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim2" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim1.end" dur="2s" fill="freeze"/>   
</rect>
<rect  x="20" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim3" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim2.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="20" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim4" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim3.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="30" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim5" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim4.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="30" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim6" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim5.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="40" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim7" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim6.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="40" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim8" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim7.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="50" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim9" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim8.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="50" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim10" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim9.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="60" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim11" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim10.end" dur="2s" fill="freeze"/>   
</rect>
<rect x="60" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
  <animateTransform id="anim12" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim11.end" dur="2s" fill="freeze"/>   
</rect>
      </g>
  </g>
</svg>
</source>


* Des actions initiées par l'utilisateur, telle que presser le bouton d'une souris, peuvent causer l'exécution d'animations ou de scripts;
On peut noter pour cette deuxième solution l'idée de démarrage pour la combinaison d'animation. En effet, le premier carré doit démarrer à 0 seconde mais aussi une fois que la dernière animation est terminée avec une seconde de décalage.
* L'utilisateur peut initier des hyperliens vers de nouvelles pages Web par des actions (par ex. cliquer sur un élément)
* L'utilisateur peut zoomer dans un contenu SVG ou effectuer un panoramique autour de celui-ci (dépend du client).
* Les déplacements par l'utilisateur du dispositif de pointage peuvent modifier le curseur qui indique sa position


L’essentiel, SVG comprend
Voilà un petit aperçu du travail final : [http://tecfaetu.unige.ch/etu-maltt/R2D2/rocca6/stic-2/ex13/chrono.svg ébauche chrono]


* des ''attributs d'événements'' (ex. ''onclick="hello()"'' ) pour lancer des scripts
== Les attributs communs aux balises d’animation ==
* des ''noms d’ événements'' qu’on peut insérer dans certains attributs (par ex: ''begin="click"'' ) et qui définissent l’élément d’animation à déclencher quand un événement donné survient.


=== Evénements SVG/SMIL ===
Voici un petit résumé des attributs les plus communs, sans rentrer dans les détails, à utiliser à titre indicatif. Consultez ensuite un manuel si nécessaire, ou [http://www.yoyodesign.org/doc/w3c/smil-animation/ cette traduction des recommandations du W3C].


La spécification SVG1 définit plus de 20 événements. Les plus importants peuvent être capturés par des "attributs d’événements" qu’on insère dans les balises qu’on veut rendre interactives.
{{XMLelement|xlink:href &#x3d; "uri"}}
 
SVG utilise le langage XLink pour designer la cible d'animation. Autrement dit, il s’agit d’une référence URI (lien externe ou interne) vers l’élément qui est la cible de cette animation et dont un attribut sera donc modifié au moment voulu. Dit plus simplement:
* On crée un lien vers l’attribut '''id''' de l’élément à animer
On n'a pas toujours besoin de se référer à un id pour animer. Si on place des balises d’animation à l’intérieur d’un élément, on se réfère aux attributs de cet élément.
 
Lorsqu'on utilise xlink, il faut absolument déclarer le namespace "xlink" dans un élément parent. On conseille de le faire dans l'élément racine (&lt;svg&gt;). Certains codes SVG que vous pouvez trouver sur Internet et même dans des ouvrages publiés ne le font pas et il faut l'ajouter pour le faire fonctionner dans un navigateur moderne.
 
<source lang="xml">
<svg width="8cm" height="3cm" xmlns="http://www.w3.org/2000/svg">
</source>
 
{{XMLelement|attributeName &#x3d; "nom"}}
 
Indique le nom de l’attribut qu’il faut animer, par exemple ''x''
 
<source lang="xml">
  <animate attributeName="x" attributeType="XML"
          begin="0s" dur="5s" from="50" to="300" fill="freeze"/>
</source>


Il existe certains événements sans attributs qui concernent la modification de l’arbre DOM. En plus, à l'aide du Modèle Objet de Document (DOM) de SVG, un script peut enregistrer des guetteurs d'événements (event handlers) DOM2 de manière à ce qu'un script puisse être invoqué quand un événement donné survient.
{{XMLelement|attributType &#x3d; "type"}}


'''Un résumé des noms et attributs d’événement'''
Indique le type d’attribut qu’il faut animer, exemple:
<source lang="xml">
attributeType = "CSS | XML | auto"
</source>


Le nom de l’événement sera utilisé pour identifier un event dans des balises d’animation (comme "begin").
Ci-dessous, on anime l’attribut "x" (la position x) d’un rectangle et c’est du type XML (SMIL):


<source lang="xml">
<source lang="xml">
  <animateColor fill="freeze" dur="0.1s" to="blue" from="yellow"
<rect x="300">
              attributeName="fill" begin="mouseover"/>
  <animate attributeName="x" attributeType="XML"
  begin="0s" dur="9s" fill="freeze" from="300" to="100" />
</rect>
</source>
</source>


L’attribut d’événement permet de placer des "guetteurs d’événement"
{{XMLelement|begin &#x3d; ''begin-value-list''}}
 
Définit quand l’élément devrait commencer (i.e. devenir actif).
 
La définition de ''begin-value-list'' est compliquée, on peut définir des multiples débuts et fins selon les besoins de synchronisation (cf. la spécification). Dans les cas simples on indique juste un début. L’exemple suivant dit "après 10 secondes" (voir ci-dessous pour d’autres "clock-value" simples:


<source lang="xml">
<source lang="xml">
<circle onmouseover="circle_click(evt)" cx="300" cy="225" r="100" fill="red"/>
<animate attributeName="x" attributeType="XML"
        begin="10s" dur="9s" fill="freeze" from="300" to="100" />
</source>
</source>


Donc '' attention'' : Ne confondez pas nom d’événement à utiliser dans les attributs des éléments d’animation et attributs d’événements pour lancer des scripts !!
Plus tard, on verra qu’on peut aussi utiliser l'interaction d'un utilisateur avec un événement (ex. cliquer dessus) pour déclencher une animation.
 
{{XMLelement|dur &#x3d;  ''Clock-value'' &#124; "media" &#124; "indefinite"}}
 
définit la durée de l’animation
* ''Clock-value'' spécifie la longueur d’une durée de présentation. La valeur doit être supérieure à 0.
* ''"indefinite"'' spécifie la durée simple comme indéfinie (c’est le défaut si vous ne précisez ni durée ni "média")
* Typiquement on indique des secondes, par ex. 10s = 10 secondes
 
<source lang="xml">
<animate attributeName="x" attributeType="XML"
        begin="0s" dur="9s" fill="freeze" from="300" to="100" />
</source>


"mouseover" pas égal à "onmouseover" (.... ou vous perdrez qq. heures ...)
Il y a plusieurs façons de définir une "clock-value". Voici quelques exemples qui marchent:


La table suivante réunit la définition de quelques éléments et attributs associés
* Valeurs d’horloge (''Clock-value'') complètes :
02:30:03    = 2 heures, 30 minutes et 3 secondes
50:00:10.25 = 50 heures, 10 secondes et 250 millisecondes


{| border="1"
* Valeurs d’horloge partielles :
! rowspan="1" colspan="1" |
Nom de <br /> l'événement
! rowspan="1" colspan="1" |
Description: un événement survient quand ...
! rowspan="1" colspan="1" |
Attribut <br /> d'événement
|-
| rowspan="1" colspan="1" |
focusin
| rowspan="1" colspan="1" |
un élément reçoit l'attention (le focus), par ex. l’élément 'text' devient sélectionné.
| rowspan="1" colspan="1" |
onfocusin
|-
| rowspan="1" colspan="1" |
focusout
| rowspan="1" colspan="1" |
un élément perd l'attention, (désélection).
| rowspan="1" colspan="1" |
onfocusout
|-
| rowspan="1" colspan="1" |
activate
| rowspan="1" colspan="1" |
un élément est activé, par exemple, au travers d'un clic de souris ou l'appui d'une touche.


* Un argument numérique est fourni pour indiquer le type d'activation :<br /> 1 pour une activation simple (par ex. simple clic ou la touche Entrée), <br /> 2 pour une hyperactivation (par ex. un double-clic ou la combinaison de touches).
02:33  = 2 minutes et 33 secondes
| rowspan="1" colspan="1" |
00:10.5 = 10.5 secondes = 10 secondes et 500 millisecondes
onactivate
|-
| rowspan="1" colspan="1" |
click
| rowspan="1" colspan="1" |
le bouton du dispositif de pointage (souris, touchpad, stylo etc.) est cliqué au-dessus d'un élément.


* Un clic est l'appui et le relâchement du bouton de la souris au-dessus d'une même position sur l'écran. (mousedown/mouseup sont avant/après).
* Les valeurs Timecount :
| rowspan="1" colspan="1" |
onclick
|-
| rowspan="1" colspan="1" |
mousedown
| rowspan="1" colspan="1" |
le bouton de pointage est pressé au-dessus d'un élément.
| rowspan="1" colspan="1" |
onmousedown
|-
| rowspan="1" colspan="1" |
mouseup
| rowspan="1" colspan="1" |
le bouton de pointage est relâché au-dessus d'un élément.
| rowspan="1" colspan="1" |
onmouseup
|-
| rowspan="1" colspan="1" |
mouseover
| rowspan="1" colspan="1" |
le dispositif de pointage est déplacé sur un élément.
| rowspan="1" colspan="1" |
onmouseover
|-
| rowspan="1" colspan="1" |
mousemove
| rowspan="1" colspan="1" |
le dispositif de pointage est déplacé alors qu'il est au-dessus d'un élément..
| rowspan="1" colspan="1" |
onmousemove
|-
| rowspan="1" colspan="1" |
mouseout
| rowspan="1" colspan="1" |
le dispositif de pointage (souris) est écarté de l’élément.
| rowspan="1" colspan="1" |
onmouseout
|-
| rowspan="1" colspan="1" |
SVGLoad
| rowspan="1" colspan="1" |
le client a complètement interprété l'élément et ses descendants


* il est prêt à agir de manière appropriée sur cet élément (affichage par exemple). Les ressources externes appelées requises doivent être chargées, interprétées et prêtes aussi.
3.2h    = 3.2 heures = 3 heures et 12 minutes
| rowspan="1" colspan="1" |
45min  = 45 minutes
onload
30s    = 30 secondes
|-
5ms    = 5 millisecondes
| rowspan="1" colspan="1" |
12.467  = 12 secondes et 467 millisecondes
SVGUnload
| rowspan="1" colspan="1" |
le client enlève le document SVG (élément svg le plus externe)
| rowspan="1" colspan="1" |
onunload
|-
| rowspan="1" colspan="1" |
SVGAbort
| rowspan="1" colspan="1" |
le chargement de la page est interrompu avant qu'un élément ait pu être complètement chargé.
| rowspan="1" colspan="1" |
onabort
|-
| rowspan="1" colspan="1" |
SVGError
| rowspan="1" colspan="1" |
un élément ne se charge pas correctement ou quand une erreur survient lors de l'exécution d'un script.
| rowspan="1" colspan="1" |
onerror
|-
| rowspan="1" colspan="1" |
SVGResize
| rowspan="1" colspan="1" |
une vue de document (svg le plus externe) est redimensionnée.
| rowspan="1" colspan="1" |
onresize
|-
| rowspan="1" colspan="1" |
SVGScroll
| rowspan="1" colspan="1" |
une vue du document est glissée sur X, sur Y ou les deux.
| rowspan="1" colspan="1" |
onscroll
|-
| rowspan="1" colspan="1" |
SVGZoom
| rowspan="1" colspan="1" |
le document change de niveau de zoom lors d'une interaction avec l'utilisateur. (éléments 'svg' les plus externes).
| rowspan="1" colspan="1" |
onzoom
|-
| rowspan="1" colspan="1" |
beginEvent
| rowspan="1" colspan="1" |
un élément d'animation commence.


* voir la description de l'interface TimeEvent dans la spéci.SMIL
{{XMLelement|end &#x3d; ''end-value-list''}}
| rowspan="1" colspan="1" |
onbegin
|-
| rowspan="1" colspan="1" |
endEvent
| rowspan="1" colspan="1" |
un élément d'animation s'achève (voir TimeEvent)
| rowspan="1" colspan="1" |
onend
|-
| rowspan="1" colspan="1" |
repeatEvent
| rowspan="1" colspan="1" |
un élément d'animation se répète.


* Il est déclenché toutes les fois où l'élément se répète, après la première itération. (voir l'interface TimeEvent aussi)
définit quand une animation se termine
| rowspan="1" colspan="1" |
onrepeat
|}


Exemple '''Simple animation avec un événement mouseover'''
{{XMLelement|min &#x3d; Clock-value &#124; "media"}}


* http://tecfa.unige.ch/guides/svg/ex/mouse-over/mouse-over1.svg
spécifie la durée minimale d'animation


On va d'abord examiner quelques fragments du code avant de montrer le tout.
{{XMLelement|max &#x3d; Clock-value &#124; "media"}}


(1) Un lien vers un autre URL se met simplement autour de l'élément cliquable
Spécifie la valeur maximum de la durée active de l'animation.


<source lang="xml">
Les trois attributs suivants sont moins souvent utilisés et peuvent contraindre la durée active. On peut indiquer une fin, un minimum ou encore un maximum de durée.
  <a xlink:href="http://tecfa.unige.ch">
  <rect style="fill:#00FF00;stroke:#00FF00" width="200"
          height="26" ry="5" rx="5" y="100" x="100"/>
  </a>
</source>


(2) L’ellipse jaune qui contient un texte va activer une animation (changement de couleur) lorsqu’on glisse la souris dessus ou lorsqu’on la sort de nouveau (l’attribut "begin" va s’activer lorsqu’il y a un mouseover ou un mouseout).
{{XMLelement|restart &#x3d; "always" &#124; "whenNotActive" &#124; "never"}}


<source lang="xml">
* '' always:'' L’animation peut être relancée à tout instant. C’est la valeur par défaut.
<g transform="translate(100,100)">
* '' whenNotActive:'' L’animation ne peut être relancée que si elle n’est pas active.
    <ellipse stroke-width="2" stroke="black" fill="yellow" ry="1cm" rx="2cm"
* ''never:'' L'animation ne peut être relancée si elle l'a été une première fois, pour toute la "durée" du document (par exemple, jusqu'à que la page web soit réactualisée)
            id="hint_button">
      <animateColor fill="freeze" dur="0.1s" to="blue" from="yellow"
                    attributeName="fill" begin="mouseover"/>
      <animateColor fill="freeze" dur="0.1s" to="yellow" from="blue"
                    attributeName="fill" begin="mouseout"/>
    </ellipse>
    <text style="font-size:12;" alignment-baseline="middle" x="-1cm">Touch me !</text>
</g>
</source>


(3) Ensuite, on a un contenu caché et qui s’affiche lorsque l'élément qui a l'id "''hint_button'' " rencontre un évément mouseover. Autrement dit: l'attribut "begin" d'une animation ne peut pas seulement être un temps, un événement de l'élément parent comme ci-dessus, mais également un événement qui a lieu dans un autre élément (l'ellipse dans notre cas anime la propriété style du cercle caché)!!
{{XMLelement|repeatCount : numeric value &#124; "indefinite"}}


<source lang="xml">
Spécifie le nombre d’itérations de la fonction d’animation. La valeur d’attribut peut être l’une des suivantes :
<g transform="translate(100,200)" style="display:none">
* '' numeric value '' = valeur numérique « décimale » qui spécifie le nombre d’itérations.
<circle style="fill:yellow;" r="2cm" cy="1cm" cx="1cm"/>
* '' "indefinite"'' = L’animation est définie comme se répétant indéfiniment (i.e. jusqu’à la fin du document).
    <text style="font-size:12;" alignment-baseline="middle" x="-0.8cm" y="1cm">
    Find the scecret URL !</text>


    <animate fill="freeze" dur="0.1s" begin="hint_button.mouseover"
{{XMLelement|repeatDur : Clock-value &#124; "indefinite"}}
      from="none" to="block" attributeName="display"/>
    <animate fill="freeze" dur="0.1s" begin="hint_button.mouseout"
      from="block" to="none" attributeName="display"/>
</g>
</source>


Voici l'exemple complet:
Spécifie la durée totale pour la répétition.
<source lang="xml">
* '' Clock-value'' = spécifie la durée
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
* '' "indefinite"'' = l’animation est définie comme se répétant indéfiniment (i.e. jusqu’à la fin du document).
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"  
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg height="900" width="900"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns="http://www.w3.org/2000/svg">
 
  <desc>Un lien se me simplement autour de l'élément qui fait
  "hint_button"</desc>


  <a xlink:href="http://tecfa.unige.ch">
  <rect style="fill:#00FF00;stroke:#00FF00" width="200"
        height="26" ry="5" rx="5" y="100" x="100"/>
  </a>


  <desc>Ici on implémente un hint_button avec une ellipse qui contient
{{XMLelement|fill : "freeze" &#124; "remove"}}
  un texte. Les éléments d'animation sont placés à l'intérieur d'une
  éllipse. L'animation (un changement de couleur) va s'activer
  lorsqu'il y a un mouseover (l'attribut "begin" va s'activer). Note:
  un événement mouseover aura un deuxième effet. L'identificateur
  "hint_button" se retrouve dans les éléments d'animations ci-après
  (le circle) et va aussi déclencher une action</desc>


  <desc>This bouton will change color when mouseover, back to original
* ''freeze'' = l’effet d’animation F(t) est défini pour geler la valeur d’effet à la dernière valeur de la durée active. L’effet d’animation est « gelé » pour le restant de la durée du document (ou jusqu’à ce que l’animation soit relancée)
  when the mouse moves out. Notice the hint_button id which we will
* ''remove'' = l’effet d’animation est stoppé (ne s’applique plus) quand la durée active de l’animation est terminée. (à moins que celle-ci ne soit relancée)
  use later.</desc>


  <g transform="translate(100,100)">
    <ellipse stroke-width="2" stroke="black" fill="yellow"
            ry="1cm" rx="2cm" id="hint_button">
      <animateColor fill="freeze" dur="0.1s" to="blue" from="yellow"
                    attributeName="fill" begin="mouseover"/>
      <animateColor fill="freeze" dur="0.1s" to="yellow" from="blue"
                    attributeName="fill" begin="mouseout"/>
    </ellipse>
    <text style="font-size:12;" alignment-baseline="middle" x="-1cm">Touch me !</text>
  </g>


  <desc>Ici on a un contenu caché et qui se déclenche (affiche)
Le plus simple exemple pour appliquer ce qui était expliqué, est  une montre qui se compose seulement de quelques lignes qui tournent autour d'un cercle ... [[Fichier:montre.jpg]]
  lorsque l'élément qui a l'id "hint_button" a un mouseover. Autrement
  dit: l'attribut "begin" d'une animation ne peut pas seulement être
  un temps, un événement de l'élément parent comme ci-dessus, mais
  également un événement qui a lieu dans un autre élément (l'ellipse
  dans notre cas)!!  </desc> <desc> This is a hidden content that will
  appear on mouseover of the element that has id=hint_button that we
  defined above.</desc>


  <g transform="translate(100,200)" style="display:none">
                                    http://devfiles.myopera.com/articles/26/ex-c00.svg
    <circle style="fill:yellow;" r="2cm" cy="1cm" cx="1cm"/>
    <text style="font-size:12;" alignment-baseline="middle" x="-0.8cm" y="1cm">
    Find the scecret URL !</text>


    <animate fill="freeze" dur="0.1s" begin="hint_button.mouseover"
<source lang="XML">
      from="none" to="block" attributeName="display"/>
<?xml version="1.1"?>
     <animate fill="freeze" dur="0.1s" begin="hint_button.mouseout"
<svg xmlns="http://www.w3.org/2000/svg"
       from="block" to="none" attributeName="display"/>
    width="240px" height="240px" viewBox="0 0 240 240">
<g transform="translate(120,120) rotate(180)">
  <g>
     <line stroke-width="5" y2="80" stroke="black" opacity=".5" />
       <animateTransform attributeName="transform" type="rotate"
        repeatCount="indefinite" dur="12h" by="360" />
    <circle r="7" />
   </g>
   </g>
  <g>
    <line stroke-width="4" y2="95" stroke="red" opacity=".9" />
      <animateTransform attributeName="transform" type="rotate"
        repeatCount="indefinite" dur="60min" by="360" />
    <circle r="6" fill="red"/>
  </g>
  <g>
    <line stroke-width="2" y2="100" stroke="blue" />
    <animateTransform attributeName="transform" type="rotate"
        repeatCount="indefinite" dur="60s" by="360" />
    <circle r="4" fill="blue"/>
  </g>
</g>
</svg>
</svg>
</source>
</source>


'''Résumé'''
=== Attributs pour valeurs d’animation interpolés ===
 
Voici un petit résumé sans rentrer dans les détails, à utiliser à titre indicatif
* Le principe de base de ce type de langage (comme dans VRML) est de laisser la possibilité à l’utilisateur d’indiquer simplement au moins 2 valeurs (début/fin) et de laisser la machine gérer le passage entre ces valeurs (interpolation)
 
Définition de la notion d’interpolation
* En animation, calcul des images intermédiaires entre deux formes polynomiales ou encore entre 2 positions sur l’écran.
* Pour la couleur, calcul des couleurs intermédiaires entre deux couleurs
* Il existe ensuite plusieurs modes (cf. ci-dessus)
 
{{XMLelement|calcMode &#x3d; "discrete &#124; linear &#124; paced &#124; spline"}}
 
Spécifie le mode d’interpolation pour l’animation.
* discrete = la fonction d’animation passera d’une valeur à l’autre sans aucune interpolation.
* linear = une interpolation linéaire simple entre les valeurs est utilisée pour le calcul de la fonction d’animation. Sauf pour l’élément ’animateMotion’, c’est la valeur par défaut pour calcMode.
* paced = interpolation qui produit une vitesse de transition égalisée au cours de l’animation.
* spline = [selon la traduction française de la spécification SVG:] interpole à partir d’une valeur de la liste de l’attribut values sur la suivante, selon une fonction temporelle définie par une courbe (spline) de Bézier cubique. Les points de la spline sont définis dans l’attribut keyTimes et les points de contrôle pour chaque intervalle sont définis dans l’attribut keySplines.


* Des animations peuvent se déclencher suite à un geste d’utilisateur.
{{XMLelement|values &#x3d; "<liste>"}}
* Le geste de l’utilisateur crée un événement géré (ici) par les balises "begin".
* Autrement dit, le "begin" fait guetteur d’événement pour l’événement nommé.
* Une animation d’un élément peut se déclencher suite à un événement qui a lieu dans un autre élément (on bouge la souris sur l’ellipse et c’est le cercle qui apparaît)


=== Interaction SMIL - script ===
* Une liste d’une ou plusieurs valeurs, séparées par des points-virgules.
* Les valeurs que vous pouvez indiquer, dépendent du type d'animation !


Il existe deux cas de figure:
{{XMLelement|keyTimes &#x3d; "<liste>"}}
* Script -> SMIL
* SMIL -> Script


Ci-dessous un simple exemple qui montre comment déclencher un script depuis SVG et ensuite le script qui arrête l'animation avec une simples méthode DOM.
* Une liste de valeurs de temps, séparées par des points-virgules, utilisée pour le contrôle de la vitesse de défilement de l’animation. Chaque temps de la liste correspond à une valeur dans la liste de l’attribut values et définit quand la valeur est utilisée dans la fonction d’animation.
* Chaque valeur de temps, dans la liste de l’attribut keyTimes, est spécifié en valeur décimale comprise entre 0 et 1 (inclus), représentant un décalage proportionnel dans la durée simple de l’élément d’animation.


'''Exemple Pendule'''
{{XMLelement|keySplines &#x3d; "<liste>"}}
* http://tecfa.unige.ch/guides/svg/ex/smil-dom/pendula.svg


<source lang="XML">
* Un jeu de points de contrôle de Bézier, associé avec la liste de l’attribut keyTimes, définissant une fonction de Bézier cubique qui contrôle l’allure du défilement des intervalles.
<?xml version="1.0" ?>
 
=== Attributs qui contrôlent la succession des animations ===
 
{{XMLelement|additive &#x3d; replace &#124; sum}}
 
* Cette balise est utilisée lorsqu’on effectue plus qu’une seule transformation en même temps.
* sum = l’animation va s’ajouter à la valeur sous-jacente de l’attribut et des autres animations de faible priorité.
* replace = l’animation va surclasser la valeur sous-jacente de l’attribut et des autres animations de faible priorité. C’est la valeur par défaut
* Si une simple animation « agrandir » peut accroître la largeur d’un objet de 10 pixels ....
 
<source lang="xml">
<rect width="20px" ...>
  <animate attributeName="width" from="0px" to="10px" dur="10s"
            additive="sum"/>
</rect>
</source>
 
... il est souvent pratique, pour des animations répétées, de la construire sur la base de résultats précédents qui s’accumulent avec chaque itération. L’exemple suivant fait que le rectangle continue à grandir au fur et à mesure de la répétition de l’animation :
 
<source lang="xml">
<rect width="20px" ...>
  <animate attributeName="width" from="0px" to="10px" dur="10s"
            additive="sum" accumulate="sum" repeatCount="5"/>
</rect>
</source>
 
À la fin de la première répétition, le rectangle a une largeur de 30 pixels, à la fin de la deuxième une largeur de 40 pixels et à la fin de la cinquième une largeur de 70 pixels.


<svg xmlns="http://www.w3.org/2000/svg" version="1.0"  
{{XMLelement|accumulate &#x3d; "none &#124; sum"}}
    viewBox="0 0 300 200">
<script>
  function stop () {
  document.documentElement.pauseAnimations();
  }


  function start () {
* C.f. la spécification
  document.documentElement.unpauseAnimations();
  }


</script>
'''Exemple : Deltas d’une animation'''
<desc>
  The pendulum code was taken from http://www.treebuilder.de/xul/svg2apng/pendel.svg. The pauseAnimations method is documented in the SVG 1.1 spec: http://www.w3.org/TR/SVG/struct.html#__svg__SVGSVGElement__pauseAnimations
</desc>
<g>
<line x1="100" y1="0" x2="100" y2="90" stroke="black"/>
<circle cx="100" cy="90" r="10"/>
<animateTransform attributeName="transform" type="rotate" values="0,100,0;70,100,0;0,100,0;-70,100,0;0,100,0" keySplines="0,0.5,0.5,1;0.5,0,1,0.5;0,0.5,0.5,1;0.5,0,1,0.5" calcMode="spline" begin="0s" dur="4s" repeatCount="indefinite"/>
</g>


<g onclick="stop()" transform="translate(150 0)">
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/inc-growth.svg
<rect width="50" height="30" rx="10" stroke="black" fill-opacity="0.2"/>
* http://tecfa.unige.ch/guides/svg/ex/anim-trans/
<text id="t" style="font:16px Arial Black;fill:white;stroke:black" transform="translate(5 20)">STOP</text>
</g>


<g onclick="start()" transform="translate(5 0)">
* À la fin de la première répétition, le rectangle a une largeur de 40 pixels, à la fin de la deuxième une largeur de 60 pixels et à la fin de la cinquième une largeur de 120 pixels.
<rect width="50" height="30" rx="10" stroke="black" fill-opacity="0.2"/>
* L’animation totale dure 5 * 5 s = 25 secondes
<text id="t" style="font:16px Arial Black;fill:white;stroke:black" transform="translate(2 20)">START</text>
* On construit sur des résultats précédents, qui s’accumulent avec chaque itération:
</g>
<source lang="xml">


<rect x="50" y="50" width="20px" height="20px"
  style="fill:yellow;stroke:black">
  <animate attributeName="width" dur="5s" repeatCount="5"
          fill="freeze"   
          from="0px" to="20px"
          additive="sum" accumulate="sum"/>
</rect>


</svg>
<text x="55" y="90" style="stroke:#000099;fill:#000099;fontsize:24;">
  Hello. Let’s show a growing rectangle ! </text>
</source>
</source>


Ligne 928 : Ligne 1 040 :


* Scalable Vector Graphics (SVG) 1.1 (Second Edition), W3C Working Draft 22 June 2010, W3C Working Draft 22 June 2010, http://www.w3.org/TR/SVG11/
* Scalable Vector Graphics (SVG) 1.1 (Second Edition), W3C Working Draft 22 June 2010, W3C Working Draft 22 June 2010, http://www.w3.org/TR/SVG11/
* [http://www.w3.org/TR/smil-animation/ SMIL Animation W3C Recommendation 04-September-2001]
* [http://www.yoyodesign.org/doc/w3c/smil-animation/ SMIL Animation, Recommandation du W3C du 4 septembre 2001]
* [http://xmlfr.org/w3c/TR/smil20/animation.html#animationNS-AnimationModel Les modules d'animation de SMIL 2.0] Chapitre de la traduction française.


; Tutoriels et exemples utilisés
; Tutoriels et exemples utilisés
Ligne 933 : Ligne 1 051 :
* [http://svgopen.org/2008/presentations/70-Tricks_of_Javascript_and_declarative_animation/index.html Tricks of javascript, SVG and SMIL] (testé avec FF 4)
* [http://svgopen.org/2008/presentations/70-Tricks_of_Javascript_and_declarative_animation/index.html Tricks of javascript, SVG and SMIL] (testé avec FF 4)


'''Compatibilité'''
* [http://caniuse.com/#feat=svg-smil Can I Use - SVG SMIL Animation] (en anglais)
Voir aussi:
Voir aussi:
* [[:en:SVG links]]
* [[:en:SVG links]]
== Remerciements ==
Remerciements à J.J.Solari (le traducteur de la [http://www.yoyodesign.org/doc/w3c/svg1/ recommandation SVG1 du W3C] en version française). J’ai "pompé" pas mal de ce texte.
La section sur les principes de l'animation a été largement copiée de la traduction [http://www.yoyodesign.org/doc/w3c/smil-animation/ SMIL Animation Recommandation du W3C du 4 septembre 2001]. Cette traduction a été faite par Patrick Schmitz et Aaron Cohen et on les remercie également.




[[Catégorie: SVG]]
[[Catégorie: SVG]]
[[Catégorie:Ressources STIC]]

Dernière version du 30 octobre 2016 à 00:38


Introduction

Ce petit tutoriel offre une introduction à SVG dynamique, c-a-d. les animations. On introduira quelques éléments du langage SMIL ("Synchronized Multimedia Integration Language") incorporé dans la spécification SVG.

Objectifs:

  • Animations de type SMIL
  • Interactivité de type SMIL

Voir aussi:

Suite:

Attention:

  • Il faut utiliser le navigateur récent. IE 9 n'implémente pas SVG dynamique.
  • Les temps associés à l'attribut "dur" ne peuvent être mis en ms (millisecondes) car certains navigateurs n'arriveront pas à le lire, ce qui fera "bugger" votre animation.

Le principe de l'animation est assez simple: animer veut dire changer un attribut d’un élément SVG dans le temps.

Il existe deux méthodes:

(1) Animation de type "XML/SMIL" avec des balises SVG spéciales de type SMIL

  • On peut animer pratiquement chaque attribut avec les éléments d’animation SVG/SMIL (un peu comme en VRML/X3D).
  • L’animation SVG/SMIL étend celle de SMIL avec quelques extensions.

(2) Animation via le DOM de SVG avec un script

  • Chaque attribut et "style sheet setting" est accessible selon la norme DOM 1 & 2. En plus, il existe un jeu d’interfaces DOM additionnelles.
  • En gros, on écrit un petit programme ECMAScript (JavaScript) qui modifie les attributs d’éléments ou qui ajoute/enlève des éléments/attributs du DOM.

Voir: Tutoriel SVG dynamique avec DOM

Le principe du "time-based":

  • L’animation est "time-based" (vs. le "frame-based" de Flash): on indique le départ et la durée d’une animation.
  • On peut animer des attributs de façon indépendante (animations en parallèle).
  • Une animation peut se déclencher suite à un geste de l’utilisateur (event) ou encore au temps voulu après le chargement du SVG.

Les bases de l'animation

Les éléments de cette section, sur les principes de l'animation, ont été largement copiés de la traduction SMIL Animation Recommandation du W3C du 4 septembre 2001. J'ai juste simplifié quelques passages - Daniel K. Schneider 27 mars 2012 à 18:23 (CEST).

On définit l'animation comme la manipulation en fonction du temps d'un attribut d'un élément cible.

Les animations définissent un début et une durée simple qui peut être répétée. Chaque animation définit une fonction d'animation qui produit une valeur de l'attribut cible à chaque instant dans la durée simple. L'auteur peut définir pendant combien de temps et combien de fois la fonction d'animation devrait se répéter. La durée simple combinée à un comportement de répétition définit la durée active.

attribut cible est le nom d'une caractéristique d'un élément cible, soit un attribut XML contenu dans l'élément, soit une propriété CSS appliquée à l'élément. Par défaut, l´élément cible d'une animation sera le parent de l'élément d'animation.

Comme exemple simple, voici la définition d'une animation de forme rectangulaire SVG. Le rectangle variera d'une forme allongée mince à une forme aplatie large. Le rectangle débute par une largeur de 10 pixels augmentant jusqu'à 100 pixels pendant 10 secondes. Au cours de ces mêmes dix secondes, la hauteur du rectangle varie de 100 pixels à 10 pixels.

<rect x="50" y="50" width="10" height="100" style="fill:#CCCCFF;stroke:#000099">
   <animate attributeName="width"  from="10px"  to="100px" 
            begin="0s" dur="10s" />
   <animate attributeName="height" from="100px" to="10px"
            begin="0s" dur="10s" />
</rect>

La cible d'une animation peut être n'importe quel élément dans le document, identifié avec une référence de localisateur en:XLink.

 <rect id="TAG" .....>
 <animate xlink:href="#TAG"

L'exemple suivant montre le principe:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Simple animate example avec une référence xLink</title>
  <desc>Rectangle shape will change</desc>
  <rect id="monRect" x="50" y="50" width="10" height="100" style="fill:#CCCCFF;stroke:#000099"/>
  <animate xlink:href="#monRect" attributeName="width"  
	   from="10px"  to="100px" begin="0s" dur="10s" />
  <animate xlink:href="#monRect" attributeName="height"
	   from="100px" to="10px"  begin="0s" dur="10s" />
  <text x="50" y="170" style="stroke:#000099;fill:#000099;font-size:14;">
  Hello. Admire the dynamic rectangle. Animation defined with targetElement.</text>
</svg>

Cet exemple montre aussi que l'on peut définir un DocType. Cela facilite l'édition avec un éditeur XML. Notez également qu'il faut définir un espace de nommage ("namespace") pour l'attribut href qui fait partie du langage xlink.

Lorsque l'animation se déroule, elle ne devrait pas changer réellement les valeurs d'attributs dans le modèle objet du DOM ou du CSS Object model. Les animations manipulent donc seulement la valeur de présentation et ne devraient pas affecter ce qu'on appelle la valeur de base définie par le DOM ou encore le CSS OM.

Lorsqu'une animation se termine, l'effet de l'animation cesse de s'appliquer et la valeur de présentation revient par défaut à la valeur de base. Ceci dit, on peut "prolonger" l'effet d'animation et figer la dernière valeur pour le restant de la durée du document.

Dans une animation, on peut soit remplacer une valeur soit ajouter à la valeur de base de l'attribut. Dans ce contexte, la valeur de base peut être la valeur du DOM ou le résultat d'autres animations visant aussi le même attribut. Ce concept plus général de valeur de base est appelé valeur sous-jacente. Les animations qui ajoutent à la valeur sous-jacente sont dites additives. Les animations qui remplacent la valeur sous-jacente sont dites non additives.

Survol des balises pour l’animation SMIL

Il existe 5 balises (éléments XML) pour l’animation.

  1. animate: utilisé pour animer dans le temps un seul attribut ou une seule propriété
  2. set: offre un moyen simple pour le paramétrage d'une seule valeur d’attribut pour une durée spécifiée.
  3. animateMotion: entraîne le déplacement d’un élément le long d’un tracé de mouvement.
  4. animateColor: spécifie une transformation de couleur au cours du temps. Attention ! La balise animateColor est dépréciée ! Il est possible de transformer la couleur en utilisant simplement animate à l'aide de l'attribut fill.
  5. animateTransform: anime un attribut de transformation sur un élément cible, permettant de ce fait aux animations de contrôler translation, changement d’échelle, rotation et/ou inclinaison.

Pour chacune de ces balises on peut utiliser certains types d'attributs/valeurs que nous introduisons d'abord avec des exemples. Pour ceux qui savent lire une DTD nous avons inclus une définition partielle et formelle provenant essentiellement de la SMIL Animation W3C Recommendation 04-September-2001

Une discussion plus systématique des attributs communs se trouve à la fin.

Exemple de sensibilisation avec animate

<svg xmlns="http://www.w3.org/2000/svg">

 <rect x="50" y="50" width="200" height="100" style="fill:#CCCCFF;stroke:#000099">
  <animate attributeName="x" attributeType="XML" 
           begin="0s" dur="5s" from="50" to="300" fill="freeze"/>
 </rect>
 <text x="55" y="90" style="stroke:#000099;fill:#000099;fontsize:24;">
  Hello. Let’s show a crawling rectangle ! </text>
</svg>
  • L’élément <animate /> est simplement placé à l’intérieur de l’élément que l'on veut animer
  • On anime la position horizontale ("x" du rect)
    • attributeName = "x" indique qu’on anime l’attribut "x" du parent "rect"
    • begin = "0s" indique que l’animation commence après 0 seconde
    • dur="5s" indique que la durée est de 5 secondes
    • from="50" point de départ de X
    • to="300" point d’arrivé de X
    • fill="freeze" : l’animation gèle (c.a.d. le rectangle reste où il est)

Animation d'un attribut avec l'élément animate

L'élément animate permet d'animer un seul attribut.

L'exemple suivant montre d'abord comment créer une définition pour un gradient de circle: jaune à l'intérieur (255,255,0) et vert à l'extérieur (0,256,0). Ce gradient est ensuite utilisé dans le fill de l'ellipse.

Ensuite on crée une animation pour agrandir/rapetisser une ellipse. Pour cela, on anime les attributs rx et ry (radius en x et y) avec une série de valeurs qui expriment: min, max, min.

attributeName="rx" values="0%;50%;0%" dur="2s" 
attributeName="ry" values="0%;50%;0%" dur="2s"
<svg version="1.1"
  width="320" height="320"
  xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient id="circleGrad">
      <stop offset="0%"   stop-color="rgb(255, 255, 0)" />
      <stop offset="100%" stop-color="rgb(  0, 255, 0)" />
    </radialGradient>
  </defs>

  <ellipse fill="url(#circleGrad)" stroke="#000" 
           cx="50%" cy="50%" rx="50%" ry="50%">
    <animate attributeName="rx" values="0%;50%;0%" dur="2s" 
      repeatCount="indefinite" />
    <animate attributeName="ry" values="0%;50%;0%" dur="2s" 
      repeatCount="indefinite" />
  </ellipse>
</svg>

Définition partielle formelle

<!ELEMENT animate EMPTY>
<!ATTLIST animate
  calcMode       (discrete | linear | paced | spline ) "linear"
  values         CDATA  #IMPLIED
  keyTimes       CDATA  #IMPLIED
  keySplines     CDATA  #IMPLIED
  from           CDATA  #IMPLIED
  to             CDATA  #IMPLIED
  by             CDATA  #IMPLIED

  <!-- Timing attributes -->
  begin          CDATA  #IMPLIED 
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED 
  repeatDur      CDATA  #IMPLIED
  fill           (remove | freeze) "remove"

  <!-- Common animation attributes -->

  attributeName  CDATA  #REQUIRED
  attributeType  CDATA  (CSS | XML | auto) "auto"
  additive       (replace | sum) "replace"
  accumulate     (none | sum) "none"

  <!-- Common event attributes -->
  onbegin        CDATA  #IMPLIED 
  onend          CDATA  #IMPLIED 
  onrepeat       CDATA  #IMPLIED 
>

Attribut transform

Il est utile de se rappeler l'attribut transform, car animer veut souvent dire appliquer une transformation. L'attribut transform définit une liste de définitions de transformations qui sont appliqués à un élément et aux enfants de l'élément. Il peut y avoir plusieurs éléments éléments dans l'attribut transform :

  • Exemple avec translate et rotate
<svg width="180" height="200"
  xmlns="http://www.w3.org/2000/svg" 
  xmlns:xlink="http://www.w3.org/1999/xlink">

  <!-- Elément avant la translation et la rotation-->
 <path id="etoile_1" d="m81.270004,88.242004l47.042999,0l14.535995,-44.689804l14.535004,44.689804l47.042999,
0l-38.057999,27.619995l14.537994,44.690002l-38.057999,-27.619995l-38.059006,27.619995l14.53801,
-44.690002l-38.057999,-27.619995l0,0z" stroke-width="5" stroke="#000000" fill="#56ffff"/>

  <!-- Elément avec l'attribut transform -->

<path id="etoile_1" d="m81.270004,88.242004l47.042999,0l14.535995,-44.689804l14.535004,44.689804l47.042999,
0l-38.057999,27.619995l14.537994,44.690002l-38.057999,-27.619995l-38.059006,27.619995l14.53801,-44.690002l-38.057999,
-27.619995l0,0z" stroke-width="5" stroke="#000000" fill="#56ffff"
transform="translate(30) rotate(45 50 50)"/>

</svg>

Les éléments de la liste transform sont séparées par des blancs et / ou des virgules, et sont appliquées de droite à gauche.

  • translate : permet de faire une translation. Pour l'utilisation, il faut inscrire translate ( x, (y)). Le y n'est pas obligatoire, s'il n'est pas indiqué il prendra la valeur de 0.
  • rotate : permet de faire une rotation. Il prend en paramètre l'angle ou les angles de rotation en degrés.
  • scale : permet de changer d'échelle. Il prend deux paramètres : le changement d’échelle sur les abscisses en premier et en second sur les ordonnées.Il n'est pas obligatoire d'indiquer 2 paramètres, dans ce cas le second prendra la même valeur que le premier paramètre.
  • ...

Transformer un dessin avec l'élément set

De la spécification: L'élément 'set' offre un moyen simple pour le paramétrage d’une seule valeur d'attribut pour une durée spécifiée. Il gère tous les types d'attributs, y compris ceux qui ne peuvent pas être raisonnablement interpolés, comme les chaînes et les valeurs booléennes.

  • L'élément 'set' n'est pas additif. Donc les attributs qui contrôlent la succession des animations” ne marcheront pas.

Exemple: Simple animation avec set et animation

Le premier rectangle (bleu) ci-dessous apparaît après 4 secondes. Sa propriété visibility est d'abord hidden, ensuite visible.

<rect x="50" y="50" width="200" height="100" style="fill:#CCCCFF;stroke:#000099"
    visibility ="hidden" >
    <set attributeName="visibility" attributeType="XML" 
      begin="4s" dur="5s" to="visible"/>
  </rect>

<rect style="fill:yellow;stroke:#000099" x="250" y="50" width="200" height="100" opacity="0" >
    <animate attributeName="opacity" attributeType="XML" 
      begin="1s" dur="5s" from="0" to="1" fill="freeze"/>
  </rect>

Définition partielle formelle

<!ELEMENT set EMPTY>
<!ATTLIST set
  attributeName  CDATA  #REQUIRED
  attributeType  CDATA  (CSS | XML | auto) "auto"
  to             CDATA  #IMPLIED
 <!-- Timing attributes -->
  begin          CDATA  #IMPLIED 
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED 
  repeatDur      CDATA  #IMPLIED
  fill           (remove | freeze) "remove"
>

Animation de couleur avec animate

Exemple: Animation d’une couleur

<svg height="900" width="900">

<!-- un gros rectangle qui remplit l’écran -->
<rect style="fill:#000000;" height="900" width="900" y="0" x="0">
  <animate fill="freeze" dur="5s" begin="0.1s" 
        to="#FFFFFF" from="#000000" calMode="linear" attributeName="fill"/>
</rect>

<!-- représentation d’une tige (rectangle haut et fin) -->
<rect style="fill:#CC9933;stroke:#CC9933" width="20" height="500"
      ry="5" rx="5" y="100" x="400">
   <animate dur="5s" begin="1s" to="#000000" 
            from="#CC9933" calMode="linear" attributeName="fill"/>
   <animate dur="5s" begin="6s" from="#000000" 
            to="#CC9933" calMode="linear" attributeName="fill"/>
</rect>

Le principe est assez simple: on passe d’une couleur à une autre. Ici on a deux animations:

  • l’arrière-plan va de blanc à noir (from="#000000") à (to="#FFFFFF")
  • la tige va d’abord de from="#CC9933" à to="#000000" (après 1s et pendan 4sec)
    et ensuite de #000000" à "#CC9933".

Définition partielle formelle

<!ELEMENT animate EMPTY>
<!ATTLIST animate
  <!-- Timing attributes -->
  begin          CDATA  #IMPLIED 
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED 
  repeatDur      CDATA  #IMPLIED
  fill           (remove | freeze) "remove"

  <!-- Common animation attributes -->
  attributeName  CDATA  #REQUIRED
  attributeType  CDATA  (CSS | XML | auto) "auto"
  additive       (replace | sum) "replace"
  accumulate     (none | sum) "none"

  calcMode       (discrete | linear | paced | spline ) "linear"
  values         CDATA  #IMPLIED
  from           CDATA  #IMPLIED
  to             CDATA  #IMPLIED
  by             CDATA  #IMPLIED
  keyTimes       CDATA  #IMPLIED
  keySplines     CDATA  #IMPLIED
>

Interpolation de forme avec AnimateTransform

Exemple : Simple rotation

<?xml version="1.0" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
  <title>Simple rotation example</title>
  <desc> Rotation with a grouping node </desc>
  <g>
    <rect x="50" y="50" rx="5" ry="5" width="200" height="100"
	  style="fill:#CCCCFF;stroke:#000099"/>
    <text x="55" y="90" style="stroke:#000099;fill:#000099;font-size:18;">
	Hello. Let's rotate</text>
    <animateTransform attributeName="transform" type="rotate"
		      values="0 150 100; 360 150 100"
		      begin="0s" dur="5s" />
  </g>
</svg>


Cet exemple moche fait une rotation

  • on anime l’attribut "rotate" du <g> (qui au départ est à son défaut, c.à.d. sans rotation)
  • on indique juste deux degrés pour la rotation (0 au départ et 360 à la fin). Le reste est interpolé par la machine.

Définition partielle formelle

<!ELEMENT animateTransform EMPTY>
<!ATTLIST animateTransform
  type          (translate | scale | rotate | skewX | skewY)
  <!-- qqs. attributs en plus -->
  values         CDATA  #IMPLIED
  from           CDATA  #IMPLIED
  to             CDATA  #IMPLIED
  by             CDATA  #IMPLIED
  begin          CDATA  #IMPLIED 
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
>

Interpolation de movement avec AnimateMotion

Exemple: Animation de mouvement simple

Le chemin était fait rapidement avec SVG-Edit avec l'outil "path". Dans le code SVG, on a juste ajouté un "Z" a la fin pour fermer la boucle.

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>Simple Motion animation example</title>

 <rect x="15" y="5" rx="5" ry="5" width="20" height="10" style="fill:#CCCCFF;stroke:#000099">
  <animateMotion dur="6s" repeatCount="indefinite" rotate="auto">
       <mpath xlink:href="#path1"/>
    </animateMotion>
   </rect>
 <path id="path1" d="m21,39c0,0 46,-44 79,-1c33,43 62,58 97,26c35,-32 86,-30 86,
       -31c0,-1 61,-9 29,43c-32,52 -19,51 -87,51c-68,0 -158,-5 -158,-6c0,-1 -40,-11 -41,-12 Z" 
       stroke-width="5" stroke="#000000" fill="none"/>
</svg>


Exemple: Animation d’un mouvement le long d’un tracé très précis

Copie d'écran

Voici la définition d’un triangle et de son animation le long d’un chemin

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="5cm" height="3cm"  viewBox="0 0 500 300"
     xmlns="http://www.w3.org/2000/svg">
  <desc>Exemple animMotion01 - illustre les calculs d'animation du mouvement</desc>
  <rect x="1" y="1" width="498" height="298"
        fill="none" stroke="blue" stroke-width="2" />

  <!-- Dessine le contour du trace de mouvement en bleu, avec
          trois petits cercles au debut, au milieu et a la fin. -->
  <path d="M100,250 C 100,50 400,50 400,250"
        fill="none" stroke="blue" stroke-width="7.06"  />
  <circle cx="100" cy="250" r="17.64" fill="blue"  />
  <circle cx="250" cy="100" r="17.64" fill="blue"  />
  <circle cx="400" cy="250" r="17.64" fill="blue"  />

  <!-- Voici un triangle qui se déplacera sur le trace de mouvement.
       Il est defini avec une orientation verticale, la base du triangle etant
       centree horizontalement juste au-dessus de l'origine. -->
  <path d="M-25,-12.5 L25,-12.5 L 0,-87.5 z"
        fill="yellow" stroke="red" stroke-width="7.06"  >

    <!-- Definit l'animation sur le trace de mouvement -->
    <animateMotion dur="6s" repeatCount="indefinite"
                   path="M100,250 C 100,50 400,50 400,250" rotate="auto" />
  </path>
</svg>

Note: La définition du dessin du tracé suit exactement le même path. Notez également que si vous aviez voulu déplacer un objet qui avait une position initiale, comme par exemple le premier cercle bleu :

  <circle cx="100" cy="250" r="17.64" fill="blue"  />

Alors il faut définir tous les points du chemin en fonction de la position initiale de l'objet ! Ici le cercle est à x=100 et y=250. Si vous voulez déplacer le cercle de 100 vers la droite et de 100 vers le haut, vous devez indiquer comme point de chemin 100,100, c'est-à-dire juste le déplacement, il ne faut pas faire l'addition! Pour les points suivants, c'est toujours la même chose : c'est par rapport à la position initiale (et non pas par rapport à la position précédente)!

La représentation d'un chemin

La notion de Path ou chemin est particulière en SVG : elle sert à réaliser des figures complexes grâce à un ensemble de coordonnées et de commandes qui précisent les relations entre les points (lignes, courbes...). Voici les commandes disponibles :

  • M : déplacement (Move);
  • L : création d'une ligne (Line);
  • H : création d'une ligne horizontale (Horizontal line);
  • V : création d'une ligne verticale (Vertical line);
  • C : création d'une courbe (Curve);
  • S : création d'une courbe lisse (Smooth);
  • Q : création d'une courbe de bézier ;
  • T : création d'une courbe de bézier lissée ;
  • A : création d'un arc de cercle ;
  • Z : terminaison du chemin ou path.

Définition partielle formelle

<!ELEMENT animateMotion EMPTY>
<!ATTLIST animateMotion

  <!-- Timing attributes -->
  begin          CDATA  #IMPLIED 
  dur            CDATA  #IMPLIED
  end            CDATA  #IMPLIED
  restart        (always | never | whenNotActive)  "always"
  repeatCount    CDATA  #IMPLIED 
  repeatDur      CDATA  #IMPLIED
  fill           (remove | freeze) "remove"

  additive       (replace | sum) "replace"
  accumulate     (none | sum) "none"
  calcMode       (discrete | linear | paced | spline) "paced"
  values         CDATA  #IMPLIED
  from           CDATA  #IMPLIED
  to             CDATA  #IMPLIED
  by             CDATA  #IMPLIED
  keyTimes       CDATA  #IMPLIED
  keySplines     CDATA  #IMPLIED
  path           CDATA  #IMPLIED
  origin         (default) "default"
/>

Animations combinées

Il est assez difficile de synchroniser un script compliqué. Par contre, créer des suites d'animations ou des animations en parallèle est assez simple.

Exemple: animation combinée

A la place de définir l'animation selon des temps en secondes, il est possible de définir des séquences d'événements, en faisant démarrer un événement à la fin de l'événement précédent avec la construction suivante.

begin="événementprécédent.end"

L'exemple suivant utilise des secondes (pas très pratique pour créer des suites compliquées)

<rect id="carre" height="67" width="67" stroke-width="5" stroke="#000000" fill="#ffffff">
 <animate attributeName="x" attributeType="XML" begin="0s" dur="6s" 
          fill="freeze" from="300" to="0"/> 
 <animate attributeName="y" attributeType="XML" begin="0s" dur="6s" 
          fill="freeze" from="100" to="0"/>
 <animateColor attributeName="fill" attributeType="CSS" from="#ffffff" to="red"
          begin="2s" dur="4s" fill="freeze" />
</rect>

L'exemple implémente une vraie suite où la 2ème animation démarre lorsque la première est terminée.

<rect id="carre" height="67" width="67" stroke-width="5" stroke="#000000" fill="#ffffff">
  <animate attributeName="x" attributeType="XML" begin="0s" dur="6s" 
           fill="freeze" from="300" to="0"/> 
</rect>

<rect id="carre2" height="80" width="23" stroke-width="5" stroke="#000000" fill="#ffffff">
  <animate attributeName="x" attributeType="XML" begin="carre.end" 
           dur="6s" fill="freeze" from="300" to="0"/> 
</rect>

De cette manière, il est possible de faire des boucles d'événements complexes.


Exemple: animation combinée

Cet exemple est tiré de traduction française de la spécification SVG 1.0

Il contient plusieurs animations:

  • largeur/hauteur du rectangle jaune
  • déplacement de l’origine du rectangle jaune (vers le haut à gauche)
  • animation de couleur pour le texte
  • déplacement le long d’un chemin du texte
  • rotation du texte
  • agrandissement du texte
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="8cm" height="3cm"  viewBox="0 0 800 300"
 xmlns="http://www.w3.org/2000/svg">
 <desc>Exemple anim01 - illustre les elements d'animation. J'ai piqué cela dans la traduction française des spécifications DKS Mars 2005</desc>
 <rect x="1" y="1" width="798" height="298" 
  fill="none" stroke="blue" stroke-width="2" />

 <!-- Ce qui suit montre l'utilisation de l'element 'animate'
 pour animer les attributs x,y et width d'un rectangle, ainsi le rectangle
 croit jusqu'a finalement remplir la zone de visualisation. -->
 <rect id="RectElement" x="300" y="100" width="300" height="100"
  fill="rgb(255,255,0)"  >
  <animate attributeName="x" attributeType="XML"
   begin="0s" dur="9s" fill="freeze" from="300" to="0" />
  <animate attributeName="y" attributeType="XML"
   begin="0s" dur="9s" fill="freeze" from="100" to="0" />
  <animate attributeName="width" attributeType="XML"
   begin="0s" dur="9s" fill="freeze" from="300" to="800" />
  <animate attributeName="height" attributeType="XML"
   begin="0s" dur="9s" fill="freeze" from="100" to="300" />
 </rect>

 <!-- Installe un nouveau systeme de coordonnees utilisateur pour que
 l'origine du texte se trouve au point (0,0), permettant ainsi une rotation et
 un changement d'echelle par rapport a la nouvelle origine. -->
 <g transform="translate(100,100)" >
  <!-- Ce qui suit montre l'utilisation des elements 'set', 'animateMotion',
  'animateColor' et 'animateTransform'. L'element 'text' ci-dessous 
  est cache au depart (i.e., invisible). A 3 secondes, celui-ci :
  * devient visible
  * bouge en continu sur la diagonale de la zone de visualisation
  * change de couleur, du bleu vers un rouge fonce
  * pivote de -30 a zero degres
  * change d'un facteur d'echelle de trois. -->
  <text id="TextElement" x="0" y="0"
   font-family="Verdana" font-size="35.27" visibility="hidden"  > 
   Ça bouge !
   <set attributeName="visibility" attributeType="CSS" to="visible"
    begin="3s" dur="6s" fill="freeze" />
   <animateMotion path="M 0 0 L 100 100" 
    begin="3s" dur="6s" fill="freeze" />
   <animateColor attributeName="fill" attributeType="CSS"
    from="rgb(0,0,255)" to="rgb(128,0,0)"
    begin="3s" dur="6s" fill="freeze" />
   <animateTransform attributeName="transform" attributeType="XML"
    type="rotate" from="-30" to="0"
    begin="3s" dur="6s" fill="freeze" />
   <animateTransform attributeName="transform" attributeType="XML"
    type="scale" from="1" to="3" additive="sum"
    begin="3s" dur="6s" fill="freeze" />
  </text>
 </g>
</svg>

Exemple en ligne:

Exemple: animation combinée (étudiant R2D2 et D.K.Schneider)

Voici un autre exemple assez complexe qui combine quelques techniques et balises différentes. L'idée était de partir sur l'affichage de carré pour l'affichage d'un "tube" de temps. Le problème était le suivant. L'animation ne semblait pas vouloir repartir.

  • chaque carré est égal à 5 secondes, il faut regarder la minute au complet pour voir le problème.

chain-animation.svg (montre le problème)

Ainsi, pour résoudre le problème, deux solutions se sont profilées:

  • Dans la première, la solution provient de l'usage des values :
<?xml version="1.0"?>
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
  
  <title>Slow LEDs</title>
      
  <description>Let's turn the biest</description>
  <g transform="translate(0,100)">
    <g transform="rotate(-90)">
      <rect x="0" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="0" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
      
      <rect x="10" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;1;1;1;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="10" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;1;1;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="20" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;1;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="20" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;1;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="30" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;1;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="30" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;1;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="40" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;0;1;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="40" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;1;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="50" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;1;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="50" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;1;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="60" y="50" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;0;1;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
      <rect x="60" y="60" width="10" height="10" stroke="black" fill="#1591B9" opacity="0">
	<animate attributeName="opacity" values="0;0;0;0;0;0;0;0;0;0;0;0;1" begin="0s" dur="20s" repeatCount="indefinite" />
      </rect>
      
    </g>
  </g>
</svg>
  • Dans la deuxième solution, qui semble fonctionner uniquement sur firefox, c'est la combinaison de ma solution avec l'ajout de la balise "set" qui permet le redémarrage.
<?xml version="1.0"?>
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
  
  <title>Slow LEDs</title>
  <desc></desc>
      
  <g transform="translate(0,100) rotate(-90)">
      <rect x="0" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="0" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="50" width="10" height="10" stroke="black" fill="black" >  </rect>
      <rect x="70" y="60" width="10" height="10" stroke="black" fill="black" >  </rect>
      

      <g stroke="black">

	<rect x="10" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim1" attributeName="opacity" from="0" to="1" attributeType="XML" begin="0s; anim12.end+1s" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="10" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim2" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim1.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect  x="20" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim3" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim2.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="20" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim4" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim3.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="30" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim5" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim4.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="30" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim6" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim5.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="40" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim7" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim6.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="40" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim8" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim7.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="50" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim9" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim8.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="50" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim10" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim9.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="60" y="50" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim11" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim10.end" dur="2s" fill="freeze"/>    
	</rect>
	
	<rect x="60" y="60" width="10" height="10" fill="#1591B9" opacity="0" >
	  <set attributeName="opacity" attributeType="XML" to="0" begin="anim12.end"/>
	  <animateTransform id="anim12" attributeName="opacity" from="0" to="1" attributeType="XML" begin="anim11.end" dur="2s" fill="freeze"/>    
	</rect>
      </g>
  </g>
</svg>

On peut noter pour cette deuxième solution l'idée de démarrage pour la combinaison d'animation. En effet, le premier carré doit démarrer à 0 seconde mais aussi une fois que la dernière animation est terminée avec une seconde de décalage.

Voilà un petit aperçu du travail final : ébauche chrono

Les attributs communs aux balises d’animation

Voici un petit résumé des attributs les plus communs, sans rentrer dans les détails, à utiliser à titre indicatif. Consultez ensuite un manuel si nécessaire, ou cette traduction des recommandations du W3C.

xlink:href = "uri"

SVG utilise le langage XLink pour designer la cible d'animation. Autrement dit, il s’agit d’une référence URI (lien externe ou interne) vers l’élément qui est la cible de cette animation et dont un attribut sera donc modifié au moment voulu. Dit plus simplement:

  • On crée un lien vers l’attribut id de l’élément à animer

On n'a pas toujours besoin de se référer à un id pour animer. Si on place des balises d’animation à l’intérieur d’un élément, on se réfère aux attributs de cet élément.

Lorsqu'on utilise xlink, il faut absolument déclarer le namespace "xlink" dans un élément parent. On conseille de le faire dans l'élément racine (<svg>). Certains codes SVG que vous pouvez trouver sur Internet et même dans des ouvrages publiés ne le font pas et il faut l'ajouter pour le faire fonctionner dans un navigateur moderne.

 <svg width="8cm" height="3cm" xmlns="http://www.w3.org/2000/svg">

attributeName = "nom"

Indique le nom de l’attribut qu’il faut animer, par exemple x

  <animate attributeName="x" attributeType="XML" 
           begin="0s" dur="5s" from="50" to="300" fill="freeze"/>

attributType = "type"

Indique le type d’attribut qu’il faut animer, exemple:

 attributeType = "CSS | XML | auto"

Ci-dessous, on anime l’attribut "x" (la position x) d’un rectangle et c’est du type XML (SMIL):

<rect x="300">
 <animate attributeName="x" attributeType="XML"
   begin="0s" dur="9s" fill="freeze" from="300" to="100" />
</rect>

begin = begin-value-list

Définit quand l’élément devrait commencer (i.e. devenir actif).

La définition de begin-value-list est compliquée, on peut définir des multiples débuts et fins selon les besoins de synchronisation (cf. la spécification). Dans les cas simples on indique juste un début. L’exemple suivant dit "après 10 secondes" (voir ci-dessous pour d’autres "clock-value" simples:

<animate attributeName="x" attributeType="XML"
         begin="10s" dur="9s" fill="freeze" from="300" to="100" />

Plus tard, on verra qu’on peut aussi utiliser l'interaction d'un utilisateur avec un événement (ex. cliquer dessus) pour déclencher une animation.

dur = Clock-value | "media" | "indefinite"

définit la durée de l’animation

  • Clock-value spécifie la longueur d’une durée de présentation. La valeur doit être supérieure à 0.
  • "indefinite" spécifie la durée simple comme indéfinie (c’est le défaut si vous ne précisez ni durée ni "média")
  • Typiquement on indique des secondes, par ex. 10s = 10 secondes
<animate attributeName="x" attributeType="XML"
         begin="0s" dur="9s" fill="freeze" from="300" to="100" />

Il y a plusieurs façons de définir une "clock-value". Voici quelques exemples qui marchent:

  • Valeurs d’horloge (Clock-value) complètes :
02:30:03    = 2 heures, 30 minutes et 3 secondes
50:00:10.25 = 50 heures, 10 secondes et 250 millisecondes
  • Valeurs d’horloge partielles :
02:33   = 2 minutes et 33 secondes
00:10.5 = 10.5 secondes = 10 secondes et 500 millisecondes
  • Les valeurs Timecount :
3.2h    = 3.2 heures = 3 heures et 12 minutes
45min   = 45 minutes
30s     = 30 secondes
5ms     = 5 millisecondes
12.467  = 12 secondes et 467 millisecondes

end = end-value-list

définit quand une animation se termine

min = Clock-value | "media"

spécifie la durée minimale d'animation

max = Clock-value | "media"

Spécifie la valeur maximum de la durée active de l'animation.

Les trois attributs suivants sont moins souvent utilisés et peuvent contraindre la durée active. On peut indiquer une fin, un minimum ou encore un maximum de durée.

restart = "always" | "whenNotActive" | "never"

  • always: L’animation peut être relancée à tout instant. C’est la valeur par défaut.
  • whenNotActive: L’animation ne peut être relancée que si elle n’est pas active.
  • never: L'animation ne peut être relancée si elle l'a été une première fois, pour toute la "durée" du document (par exemple, jusqu'à que la page web soit réactualisée)

repeatCount : numeric value | "indefinite"

Spécifie le nombre d’itérations de la fonction d’animation. La valeur d’attribut peut être l’une des suivantes :

  • numeric value = valeur numérique « décimale » qui spécifie le nombre d’itérations.
  • "indefinite" = L’animation est définie comme se répétant indéfiniment (i.e. jusqu’à la fin du document).

repeatDur : Clock-value | "indefinite"

Spécifie la durée totale pour la répétition.

  • Clock-value = spécifie la durée
  • "indefinite" = l’animation est définie comme se répétant indéfiniment (i.e. jusqu’à la fin du document).


fill : "freeze" | "remove"

  • freeze = l’effet d’animation F(t) est défini pour geler la valeur d’effet à la dernière valeur de la durée active. L’effet d’animation est « gelé » pour le restant de la durée du document (ou jusqu’à ce que l’animation soit relancée)
  • remove = l’effet d’animation est stoppé (ne s’applique plus) quand la durée active de l’animation est terminée. (à moins que celle-ci ne soit relancée)


Le plus simple exemple pour appliquer ce qui était expliqué, est une montre qui se compose seulement de quelques lignes qui tournent autour d'un cercle ... Montre.jpg

                                   http://devfiles.myopera.com/articles/26/ex-c00.svg
<?xml version="1.1"?>
<svg xmlns="http://www.w3.org/2000/svg"
     width="240px" height="240px" viewBox="0 0 240 240">
<g transform="translate(120,120) rotate(180)">
  <g>
    <line stroke-width="5" y2="80" stroke="black" opacity=".5" />
      <animateTransform attributeName="transform" type="rotate"
         repeatCount="indefinite" dur="12h" by="360" />
    <circle r="7" />
  </g>
  <g>
    <line stroke-width="4" y2="95" stroke="red" opacity=".9" />
      <animateTransform attributeName="transform" type="rotate"
         repeatCount="indefinite" dur="60min" by="360" />
    <circle r="6" fill="red"/>
  </g>
  <g>
    <line stroke-width="2" y2="100" stroke="blue" />
    <animateTransform attributeName="transform" type="rotate"
        repeatCount="indefinite" dur="60s" by="360" />
    <circle r="4" fill="blue"/>
  </g>
</g>
</svg>

Attributs pour valeurs d’animation interpolés

Voici un petit résumé sans rentrer dans les détails, à utiliser à titre indicatif

  • Le principe de base de ce type de langage (comme dans VRML) est de laisser la possibilité à l’utilisateur d’indiquer simplement au moins 2 valeurs (début/fin) et de laisser la machine gérer le passage entre ces valeurs (interpolation)

Définition de la notion d’interpolation

  • En animation, calcul des images intermédiaires entre deux formes polynomiales ou encore entre 2 positions sur l’écran.
  • Pour la couleur, calcul des couleurs intermédiaires entre deux couleurs
  • Il existe ensuite plusieurs modes (cf. ci-dessus)

calcMode = "discrete | linear | paced | spline"

Spécifie le mode d’interpolation pour l’animation.

  • discrete = la fonction d’animation passera d’une valeur à l’autre sans aucune interpolation.
  • linear = une interpolation linéaire simple entre les valeurs est utilisée pour le calcul de la fonction d’animation. Sauf pour l’élément ’animateMotion’, c’est la valeur par défaut pour calcMode.
  • paced = interpolation qui produit une vitesse de transition égalisée au cours de l’animation.
  • spline = [selon la traduction française de la spécification SVG:] interpole à partir d’une valeur de la liste de l’attribut values sur la suivante, selon une fonction temporelle définie par une courbe (spline) de Bézier cubique. Les points de la spline sont définis dans l’attribut keyTimes et les points de contrôle pour chaque intervalle sont définis dans l’attribut keySplines.

values = "<liste>"

  • Une liste d’une ou plusieurs valeurs, séparées par des points-virgules.
  • Les valeurs que vous pouvez indiquer, dépendent du type d'animation !

keyTimes = "<liste>"

  • Une liste de valeurs de temps, séparées par des points-virgules, utilisée pour le contrôle de la vitesse de défilement de l’animation. Chaque temps de la liste correspond à une valeur dans la liste de l’attribut values et définit quand la valeur est utilisée dans la fonction d’animation.
  • Chaque valeur de temps, dans la liste de l’attribut keyTimes, est spécifié en valeur décimale comprise entre 0 et 1 (inclus), représentant un décalage proportionnel dans la durée simple de l’élément d’animation.

keySplines = "<liste>"

  • Un jeu de points de contrôle de Bézier, associé avec la liste de l’attribut keyTimes, définissant une fonction de Bézier cubique qui contrôle l’allure du défilement des intervalles.

Attributs qui contrôlent la succession des animations

additive = replace | sum

  • Cette balise est utilisée lorsqu’on effectue plus qu’une seule transformation en même temps.
  • sum = l’animation va s’ajouter à la valeur sous-jacente de l’attribut et des autres animations de faible priorité.
  • replace = l’animation va surclasser la valeur sous-jacente de l’attribut et des autres animations de faible priorité. C’est la valeur par défaut
  • Si une simple animation « agrandir » peut accroître la largeur d’un objet de 10 pixels ....
 <rect width="20px" ...>
   <animate attributeName="width" from="0px" to="10px" dur="10s"
            additive="sum"/>
 </rect>

... il est souvent pratique, pour des animations répétées, de la construire sur la base de résultats précédents qui s’accumulent avec chaque itération. L’exemple suivant fait que le rectangle continue à grandir au fur et à mesure de la répétition de l’animation :

 <rect width="20px" ...>
   <animate attributeName="width" from="0px" to="10px" dur="10s"
            additive="sum" accumulate="sum" repeatCount="5"/>
 </rect>

À la fin de la première répétition, le rectangle a une largeur de 30 pixels, à la fin de la deuxième une largeur de 40 pixels et à la fin de la cinquième une largeur de 70 pixels.

accumulate = "none | sum"

  • C.f. la spécification

Exemple : Deltas d’une animation

  • À la fin de la première répétition, le rectangle a une largeur de 40 pixels, à la fin de la deuxième une largeur de 60 pixels et à la fin de la cinquième une largeur de 120 pixels.
  • L’animation totale dure 5 * 5 s = 25 secondes
  • On construit sur des résultats précédents, qui s’accumulent avec chaque itération:
<rect x="50" y="50" width="20px" height="20px"
  style="fill:yellow;stroke:black">
  <animate attributeName="width" dur="5s" repeatCount="5" 
           fill="freeze"     
           from="0px" to="20px" 
           additive="sum" accumulate="sum"/>
 </rect>

 <text x="55" y="90" style="stroke:#000099;fill:#000099;fontsize:24;">
  Hello. Let’s show a growing rectangle ! </text>

Ressources

Spécification
  • Scalable Vector Graphics (SVG) 1.1 (Second Edition), W3C Working Draft 22 June 2010, W3C Working Draft 22 June 2010, http://www.w3.org/TR/SVG11/
Tutoriels et exemples utilisés

Compatibilité

Voir aussi:

Remerciements

Remerciements à J.J.Solari (le traducteur de la recommandation SVG1 du W3C en version française). J’ai "pompé" pas mal de ce texte.

La section sur les principes de l'animation a été largement copiée de la traduction SMIL Animation Recommandation du W3C du 4 septembre 2001. Cette traduction a été faite par Patrick Schmitz et Aaron Cohen et on les remercie également.