ac681333cf23d0633fa361aa65d9a52fe9a81035
[svganimation.git] / doc / page.md
1 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
2 <script type="text/javascript" src="../SVGAnimation.js"></script>
3 <script type="text/javascript" src="../SVGPlayerOne.js"></script>
4 <script type="text/javascript">
5   function charge(i,p,a,b) {
6     var anim = new Animation(i,p,a,b);
7     anim.loopOnload();
8     var player = new Controle(anim);
9     player.connect();
10   }
11   function charge_anim2() {
12     var a = new Animation('anim2','../ellipsographe/svg/ellipsographe-',1,91);
13     a.loopOnload();
14     var b = new Controle(a);
15     b.connect();
16   }
17   $(window).load(function() {
18     anim = new Animation('XXXX','../ellipsographe/svg/ellipsographe-',1,91);
19     anim.loopOnload();
20     player = new Controle(anim);
21     player.connect();
22     });
23 </script>
24
25
26 **Participants :** Chupin Maxime, Sarlat Jean-Michel.
27
28 **Interface du dépôt Git :** <http://melusine.eu.org/syracuse/G/git/?p=svganimation.git;a=summary>
29
30 L'objectif est de développer, en particulier, du code Javascript afin de
31 présenter des animations de fichiers SVG produits, en particulier, par
32 MetaPost. Ce développement n'étant pas tout à fait prédéterminé, il sera
33 constitué à partir de l'exploration de différents scénarios de
34 présentation de ces animations et des modes de construction des fichiers
35 SVG.
36
37 <div class="alert alert-warning">
38 <p>Les différents exemples se chargent en cliquant sur le bouton
39 dédié. Ceci **n'est pas** le comportement par défaut, c'est du code
40 JavaScript qui permettra de choisir quand l'animation se charge. Il
41 s'agit
42 d'éviter de charger toutes les animations présentes sur cette page,
43 cela serait bien trop lourd.</p>
44 <p>Nous présentons, dans la section <a
45 href="#chargement-différé">Chargement différé</a>, le code qui permet de
46 charger l'animation sur demande.</p>
47 </div>
48
49 ## Installation
50
51 Le fichier `SVGAnimation.js` (que l'on supposera dans un répertoire
52 nommé `js`) est à charger dans la page `html` en mettant les lignes
53 suivantes :
54
55     <script type="text/javascript" src="js/SVGAnimation.js"></script>
56
57
58 ## Principe
59
60 Le principe est simple : on dispose d'un ensemble d'images au format
61 SVG qui constituent, par une suite chronologique, une animation à
62 visionner. La libraire `SVGAnimation` permet de visionner cette
63 animation dans une page HTML grâce à JavaScript.
64
65 ### La famille d'images
66
67 Les différentes images composant l'animation doivent se nommer avec un
68 *prefixe* suivi d'un nombre (indice), celui-ci pouvant être
69 formater de différente façons :
70
71     monfichier-1.svg  monfichier-2.svg monfichier-3.svg ...
72
73 ou, autre exemple :
74
75     monfichier-001.svg  monfichier-002.svg monfichier-003.svg ...
76
77 Nous verrons comment gérer le formatage de l'indice des images dans
78 les sections suivantes.
79
80 <div class="alert alert-info">
81 <p>L'idée d'une telle librairie est venue du fait que le logiciel
82 MetaPost permet de produire des images SVG, et nous l'utilisons
83 abondamment pour la production d'animations.</p>
84 </div>
85
86
87 ## L'utilisation
88
89 ### Côté HTML
90
91 La librairie `SVGAnimation` définit le *prototype* javascript
92 `Animation`. Pour l'utiliser il faut déclarer une balise HTML `div`
93 avec un identifiant (`id`) unique. Choisissons pour l'exemple `XXXX`.
94 À l'intérieur de ces balises, il
95 faut&#8239;:
96
97 * une balise `img` contenant un image `svg` qui servira de vignette à
98   l'animation;
99 * une balise `div` avec l'identifiant `id="XXXX_message"` où `XXXX` est
100   l'identifiant de la balise englobante. Dans cette balise *message*,
101   on y met, si on le souhaite, un message à afficher avant le
102   chargement de l'animation;
103 * une balise `div` avec l'identifiant `id="XXXX_boutons"`.
104
105
106 En supposant que les images SVG se trouvent dans un répertoire nommé
107 `svg`, voici un exemple d'une telle structure :
108
109 ~~~~~~~ { .html }
110 <div id="anim1">
111   <img src="svg/ellipsographe-1.svg" alt="animation1"/>
112   <div class="message" id="anim1_message">Chargement</div>
113   <div id="anim1_boutons"></div>
114 </div>
115 ~~~~~~~
116
117 ### Côté JavaScript
118
119 Une fois qu'on a la structure HTML présentée ci-dessus, il est
120 nécessaire d'ajouter un peu de code JavaScript pour permettre à l'animation
121 de se jouer.
122
123 #### Construire l'objet `Animation`
124
125 Le *constructeur* du prototype JavaScript s'utilise, pour l'exemple
126 donné à la section précédente, de la façon
127 suivante :
128
129 ~~~~~~~ { .javascript }
130 var anim = new Animation('XXXX','svg/ellipsographe-',1,91);
131 anim.loopOnload();
132 ~~~~~~~
133
134 `XXXX` est l'identifiant de la balise `div` HTML *englobante*,
135 `svg/ellipsographe-` est le préfixe dont on a parlé plus haut, `1` est
136 l'indice de la première image à animer, et `91` l'indice de la
137 dernière.
138
139 `anim.loopOnload()` permet le chargement de l'animation.
140
141 Une fois celle-ci chargée, il faut en permettre la lecture qui se fait
142 grâce à un nouvel objet nommé `Controle`. Ce contrôle s'utilise en
143 fait comme ceci :
144
145 ~~~~~~~ { .javascript }
146 var anim = new Animation('XXXX','svg/ellipsographe-',1,91);
147 anim.loopOnload();
148 var player = new Controle(anim);
149 player.connect();
150 ~~~~~~~
151
152 Nous verrons par la suite comment personnaliser le contrôle de la
153 lecture de l'animation.
154
155 Tout ceci n'est toujours pas suffisant car il faut exécuter ce code
156 JavaScript. Ceci peut être fait grâce à `JQuery` par exemple, en
157 exécutant ces quatre lignes de code à l'ouverture de la fenêtre :
158
159 ~~~~~~~ { .javascript }
160 $(window).load(function() {
161     var anim = new Animation('XXXX','svg/ellipsographe-',1,91);
162     anim.loopOnload();
163     var player = new Controle(anim);
164     player.connect();
165 });
166 ~~~~~~~
167
168 Bien sûr, ceci nécessite le chargement, dans la page HTML, de la
169 librairie `JQuery`.
170
171
172
173
174
175 #### Le résultat
176
177 Tout ceci donne le code suivant
178
179 ~~~~~~~ { .html }
180 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
181 <script type="text/javascript" src="../SVGAnimation.js"></script>
182 <script type="text/javascript">
183 $(window).load(function() {
184     var anim = new Animation('XXXX','svg/ellipsographe-',1,91);
185     anim.loopOnload();
186     var player = new Controle(anim);
187     player.connect();
188 });
189 </script>
190 <!--[...]-->
191 <div id="XXXX">
192   <img src="svg/ellipsographe-1.svg" alt="animation1"/>
193   <div class="message" id="XXXX_message">Chargement...</div>
194   <div id="XXXX_boutons"></div>
195 </div>
196 ~~~~~~~
197
198 dont l'affichage est :
199
200 <div id="XXXX">
201   <img src="../ellipsographe/svg/ellipsographe-1.svg" alt="animation1"/>
202   <div class="message" id="XXXX_message">Chargement...</div>
203   <div id="XXXX_boutons"></div>
204 </div>
205
206
207 #### Chargement différé
208
209 On peut laisser le chargement d'une animation à la demande en créant une
210 fonction Javascript.
211
212 ~~~~~~~ { .javascript }
213 function charge_anim2() {
214   var a = new Animation('anim2','svg/ellipsographe-',1,91);
215   a.loopOnload();
216   var b = new Controle(a);
217   b.connect();
218 }
219 ~~~~~~~
220
221 Fonction qui sera liée à l'*événement* `onclick` d'un bouton proposant
222 justement le chargement de l'animation...
223
224 ~~~~~~~ { .html }
225 <div id="anim2" style="...">
226  <img src="../ellipsographe/svg/ellipsographe-1.svg" alt="animation1" style="..."/>
227  <div class="message" id="anim2_message">Ellipsographe</div>
228  <div id="anim2_boutons">
229    <button onclick="charge_anim2();">Charger l'animation</button>
230  </div>
231 </div>
232 ~~~~~~~
233
234 Dans le même temps, le *style* des éléments englobants a été adapté.
235
236 <div id="anim2"  style="margin:10px auto;padding:10px;width:354px;border:2px solid #AAA;border-radius:4px">
237   <img src="../ellipsographe/svg/ellipsographe-1.svg" alt="animation1" style="width:330px;height:240px"/>
238   <div class="message" id="anim2_message">Ellipsographe</div>
239   <div id="anim2_boutons"><button onclick="charge_anim2()">Charger l'animation</button></div>
240 </div>
241
242
243
244 ### Les paramètres
245
246 L'objet `Animation` ne possède que deux propriétés configurables, autres
247 que celles (4) qui lui sont passées en argument.
248
249 &bull; **delai** *(valeur par défaut : 50)* &mdash; C'est la durée, en millisecondes, entre deux images.
250
251 ~~~{.javascript}
252 var a = new Animation('anim','svg/pre',1,100);
253 a.delai = 200;
254 a.loopOnload();
255 ~~~
256 Ceci fixera le défilement à 5 images/s. Un *player* comme ceux que nous vous proposons ci-dessous peut
257 modifier cette valeur.
258
259 &bull; **pad** *(valeur par défaut : 0)* &mdash; Ce paramètre n'a d'effet
260 que s'il est supérieur ou égal à 2, il permet de fixer la longueur des
261 index des images en complétant avec des 0.
262
263 ~~~{.javascript}
264 var a = new Animation('anim','svg/pre',1,100);
265 a.pad = 3;
266 a.loopOnload();
267 ~~~
268 Les images chargées seront, successivement, `svg/pre001.svg`, `svg/pre002.svg`, ..., `svg/pre100.svg`.
269
270 ## Les *players*
271
272 Le fichier `SVGAnimation.js` contient le constructeur `Controle` qui est
273 la base des *players*. S'il est invoqué directement, il fournit un
274 contrôle *simpliste* de l'animation, comme cela a été vu
275 [ci-dessus](#côté-javascript).
276
277 ### `SVGPlayerOne.js`
278
279 Pour utiliser un *player* plus *sophistiqué*, il faut surcharger la
280 méthode `Initialisation` de l'objet `Controle`. Pour plus de détails
281 sur les *players*, nous vous invitons à consulter la page dédiée.
282
283 L'idée que nous présentons ici est de construire un objet JavaScript
284 qui mettra des boutons de contrôle (lecture, stop, etc.).
285
286 Ceci peut se faire de la façon suivante :
287
288 ~~~~~~~ { .javascript }
289 function SVGPlayerOne(a) { // déclaration de l'objet
290   Controle.call(this,a); // construit à partir de l'objet Controle
291   SVGPlayerOne.prototype.connect = Controle.prototype.connect // et de
292   // la méthode connect du Controle
293 }
294 ~~~~~~~
295
296 Une fois déclaré un tel objet, il suffit de surcharger la méthode
297 `Initialisation` de l'objet `Controle` fourni dans `SVGAnimation.js`.
298 Dans l'exemple ci-dessous, on « vide » la `div` `XXXX_message`, et on
299 ajoute des boutons à la `div` `XXXX_boutons` qui réagissent aux
300 `onclick` pour lancer les fonctions JavaScript adéquates définies dans
301 le fichier `SVGAnimation.js`.
302
303 ~~~~~~~ { .javascript }
304 // Surcharge de la méthode [Initialisation]
305 SVGPlayerOne.prototype.Initialisation = function() {
306   var a = this.a; // l'animation courante
307   var self = this.me; // le player
308   a.image.style.display = 'inline';
309   a.message.parentNode.removeChild(a.message); // on supprime la
310       //balise d'id=XXXX_message
311   var play = document.createElement('button'); // on crée un bouton
312   play.className = "SVGplay playBtn"; // ajout de classe pour le style
313   play.innerHTML = "Play"; // on y met du texte
314   play.onclick = function(){a.action = true; a.rotate(self.a)}; // on
315       // associe une fonction JS
316   // on recommence
317   var stop = document.createElement('button');
318   stop.className = "SVGplay stopBtn";
319   stop.innerHTML = "Stop";
320   stop.onclick = function(){a.action = false;};
321   var debut = document.createElement('button');
322   debut.className = "SVGplay debutBtn";
323   debut.innerHTML = "Début";
324   debut.onclick = function(){a.action = false; a.first(self.a)};
325   var fin = document.createElement('button');
326   fin.className = "SVGplay finBtn";
327   fin.innerHTML = "Fin";
328   fin.onclick = function(){a.action = false; a.last(self.a)};
329   var moins = document.createElement('button');
330   moins.className = "SVGplay moinsBtn";
331   moins.innerHTML = "-";
332   moins.onclick = function(){a.delai = a.delai > 2000 ? 2000 : a.delai * 1.414};
333   var plus = document.createElement('button');
334   plus.className = "SVGplay plusBtn";
335   plus.innerHTML = "+";
336   plus.onclick = function(){a.delai = a.delai < 30 ? 30 : a.delai / 1.414};
337   // placement des boutons
338   a.boutons.appendChild(play);
339   a.boutons.appendChild(stop);
340   a.boutons.appendChild(debut);
341   a.boutons.appendChild(fin);
342   a.boutons.appendChild(moins);
343   a.boutons.appendChild(plus);
344 }
345 ~~~~~~~
346
347 Un fois déclaré tout ceci (le mieux étant dans un fichier externe), on
348 associe le *player* `SVGPlayerOne` à l'animation de la même façon que
349 le *player* `Controle` :
350
351 ~~~~~~~ { .javascript }
352 var anim = new Animation('anim2','svg/ellipsographe-',1,91);
353 anim.loopOnload();
354 var player = new SVGPlayerOne(anim);
355 player.connect();
356 ~~~~~~~
357
358 <script type="text/javascript">
359   function charge_anim3() {
360     var anim = new Animation('anim3','../ellipsographe/svg/ellipsographe-',1,91);
361     anim.loopOnload();
362     var player = new SVGPlayerOne(anim);
363     player.connect();
364   }
365 </script>
366
367 <div id="anim3" style="margin:10px auto;padding:10px;width:354px;border:2px solid #AAA;border-radius:4px">
368   <img src="../ellipsographe/svg/ellipsographe-1.svg" alt="animation1" style="width:330px;height:240px"/>
369   <div class="message" id="anim3_message">Ellipsographe</div>
370   <div id="anim3_boutons"><button onclick="charge_anim3()">Charger l'animation</button></div>
371 </div>
372
373 Le fichier `SVGPlayerOne.js` est fourni à la racine du projet SVGAnimation.
374
375
376
377 ## Exemples d'utilisation
378
379 <div class="row">
380 <div class="col-md-4">
381 <a href="//melusine.eu.org/syracuse/G/svganimation-exemples/mvtretrograde/"
382 alt="lien vers l'exemple"><img src="img/mvtretrograde.png"
383 alt="Image de l'exemble" style="width: 100%;"/></a>
384 </div>
385 <div class="col-md-8">
386 Animation  avec le *player* `SVGPlayerButtons` et une factorisation
387 avec MetaPost du matériel qui se répète sur chaque image. Le fond
388 est mis en *background* de la balise englobante, permettant ainsi
389 d'alléger l'animation.
390 </div>
391 </div>

Licence Creative Commons Les fichiers de Syracuse sont mis à disposition (sauf mention contraire) selon les termes de la
Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International.