Les effets et les animations avec jQuery

Il y a encore quelques années la seule technologie pour créer des transitions voire des animations était jQuery désormais il est possible d'utiliser CSS3 avec les nouvelles propriétés transition et animation mais les possibilités sont plus limitées qu'avec jQuery et de plus ça ne "marche" qu'avec des navigateurs récents ...
Donc jQuery garde toute son utilité.

Effets : les méthodes show(), hide() et toggle()

Nous avons déjà abordé ces trois méthodes.

Les méthodes show() et hide()

Le code de l'exemple :

... <body> <button>Afficher lignes paires</button> <button>Masquer lignes paires</button> <table> <tr><td>1</td><td>impaire</td><td>impaire</td></tr> ... <tr><td>6</td><td>paire</td><td>paire</td></tr> </table> <script> $("tr:even").css("background","yellow"); $("tr:odd").css("background","orange"); $('button:eq(0)').click(function() { $('tr:odd').show('slow'); } ); $('button:eq(1)').click(function() { $('tr:odd').hide(1000); }); </script> ...

Si clic sur le premier bouton les lignes paires du tableau sont affichées
Si clic sur le deuxième bouton les lignes paires sont masquées.
Le paramètre de la méthode show ou hide est la durée de la transition en millisecondes ou un mot : slow ou fast.
Remarquez que le tableau est mis en couleur via deux instructions jQuery afin de faire l'économie d'une feuille de style.
Testez l'exemple !

La fonction de rappel : callback

Depuis les dernières versions de jQuery les méthodes show et hide peuvent avoir un deuxième argument : une fonction qui s'exécute à la fin de l'effet. On parle de fonction de rappel ou callback.

Le code de l'exemple :

... <style> img {height : 24% ; display : none ;} </style> </head> <body> <button>Afficher images !</button> <button>Images masquées !</button> <div> <img src ="../images/bikini.jpg" /> <img src ="../images/trikini.jpg" /> ... </div> <script> $("button:eq(0)").click(function() { $("img").show("slow", function() {$("button:eq(0)").html("images affichées !");$("button:eq(1)").html("Masquer images !")}) }); $("button:eq(1)").click(function() { $("img").hide("slow", function() {$("button:eq(0)").html("Afficher images !");$("button:eq(1)").html("Images masquées !")}) }); </script> ...

CSS : les images sont par défaut masquées (display : none).

HTML : Comme les images sont masquées les légendes par défaut des boutons sont : "Afficher images !" et "Images masquées".

Le script est un peu compliqué.
Il comprend deux instructions. Chaque instruction liée à un bouton de commande.
Si clic sur le premier bouton les images s'affichent et les deux boutons changent de légende pour préciser le changement d'état
Si clic sur le deuxième bouton les images sont masquées et les deux boutons changent à nouveau de légende.

Observez attentivement la première instruction !

La fonction de rappel contient deux instructions qui modifient les contenus des éléments button

La deuxième instruction a la même structure mais cette fois basée sur la méthode hide.
Testez l'exemple avec callback !

Plutôt que de changer les légendes des boutons de commande on aurait pu imaginer d'autres solutions :
- masquer le bouton inutile (exemple : le bouton qui affiche alors que les images sont déjà affichées).
- désactiver le bouton inutile (exemple : le bouton qui masque alors que les images sont déjà masquées).

La méthode toggle()

La méthode toggle permet d'afficher un élément masqué et masquer un élément affiché. C'est l'effet bascule.

Le code de l'exemple :

... <button>Afficher/masquer lignes impaires</button> <button>Afficher/masquer lignes paires</button> <table> <tr><td>1</td><td>impaire</td><td>impaire</td></tr> ... <tr><td>5</td><td>impaire</td><td>impaire</td></tr> </table> <script> $("tr:even").css("background","yellow"); $("tr:odd").css("background","orange"); $('button:eq(0)').click(function() { $('tr:even').toggle(1000); } ); $('button:eq(1)').click(function() { $('tr:odd').toggle(1000); }); </script> ...

Si clic sur premier bouton les lignes impaires (even) sont affichées ou masquées.
Si clic sur deuxième bouton les lignes paires (odd) sont affichées ou masquées.
Donc il est possible de masquer toutes les lignes du tableau ...


Testez l'exemple !

Apparition et disparition en cascade

Le code de l'exemple :

... <body> <button>Faire apparaître en cascade les images</button> <button>Faire disparaître en cascade les images</button> <img src ="../images/bikini.jpg" width ="30%" /> ... <script> $('button:eq(0)').click(function() { $('img').first().show(1000, function afficher_suivante() { $(this).next('img').show(1000, afficher_suivante); }); }); $('button:eq(1)').click(function() { $('img').first().hide(1000, function masquer_suivante() { $(this).next('img').hide(1000, masquer_suivante); }); });af </script> ...

Un clic sur le premier bouton fait apparaître les images les unes après les autres : d'abord la première puis la seconde et ainsi de suite.
Un clic sur le deuxième bouton fait disparaître les images les unes après les autres (effet domino)

Etudiez attentivement la première instruction !
Elle est un peu compliquée mais d'une puissance exceptionnelle.

Si clic sur le premier bouton de commande la première image est affichée en 1 seconde puis appel de la fonction
afficher_suivante() qui affiche l'image suivante puis appelle la fonction afficher_suivante()

Donc nous sommes en présence d'une fonction qui s'appelle elle-même.
On appelle cette technique la récursivité.

La deuxième instruction est aussi basée sur la récursivité mais avec la méthode hide().
Testez l'exemple !

Apparition et disparition en cascade : deuxième solution

En utilisant la méthode toggle il est possible de n'utiliser qu'un seul bouton de commande !

... <body> <button>Afficher/masquer les images en cascade</button> ... <script> $('button:eq(0)').click(function() { $('img').first().toggle(2000,function suivante() { $(this).next('img').toggle(2000, suivante); }); }); </script>

Un seul bouton de commande pour afficher ou masquer en cascade.

Une seule instruction appelant la fonction récursive suivante.
Cette dernière fonction étant basée sur la méthode toggle
Testez l'exemple !

Méthodes slideDown, slideUp et slideToggle

Premier exemple :

... <button>Déplier/replier images</button> <img src ="../images/bikini.jpg"/> ... <script> $('button:eq(2)').click(function() {$("img").slideToggle(2000); }); </script> ...

Un bouton qui permet de déplier ou de replier les images en fonction du contexte.
En effet le bouton unique appelle une instruction basée sur la méthode slideToggle.
Testez l'exemple !

Deuxième exemple avec fonction callback

Les méthodes slideDown, slideUp, slideToggle peuvent aussi avoir comme deuxième paramètre une fonction de rappel.

Le code de l'exemple (extraits) :

... <button>Replier les images</button> <button style ="visibility :hidden;">Déplier les images</button> <img src ="../images/bikini.jpg" /> <img src ="../images/trikini.jpg" /> ... <script> $("button:eq(0)").click(function() { $("img").slideUp("slow", function() {$("button:eq(0)").css("visibility","hidden");$("button:eq(1)").css("visibility","visible")}) }); $("button:eq(1)").click(function() { $("img").slideDown("slow", function() {$("button:eq(1)").css("visibility","hidden");$("button:eq(0)").css("visibility","visible")}) }); ...

HTML : deux images affichées et deux boutons de commande dont le deuxième masqué.

Deux instructions : l'une basée sur la méthode slideDown (déplier) et l'autre sur la méthode slideUp (replier).
Non seulement il y a dépliement ou repliement mais en plus un des deux boutons est alternativement masqué. Ainsi lorsque les images sont repliées le bouton légendé "replier les images" est masqué et inversement lorsque les images sont dépliées le bouton légendé "replier les images" est masqué. Il faut bien sûr penser à démasquer l'autre bouton !
Testez l'exemple avec callback

Enchaîner les dépliements/repliements

Il faut donc créer une fonction récursive.

La première image est dépliée/repliée puis la suivante et ainsi de suite.

Le code de l'exemple :

... <button>Replier les images</button> <button>Déplier les images</button> <img src ="../images/bikini.jpg" /> ... <script> $('button:eq(0)').click(function() { $('img').first().slideUp(1000,function replier_suivante() { $(this).next('img').slideUp(1000, replier_suivante); }); }); ...

Deux boutons de commande !

A vous d'imaginer le code de la deuxième instruction avec une fonction récursive deplier_suivante ; fonction basée sur la méthode slideDown Testez l'exemple !

Le code de l'exemple : deuxième solution :

... <button>Déplier/replier les images</button> ... $('...').click(function() { $('img').first().slideToggle(1000,function suivante() { ... }); });

Un seul bouton de commande !
Dans le script une seule instruction avec une fonction récursive suivante basée sur la méthode toggle. Testez l'exemple !

Méthodes fadeIn, fadeOut, fadeTo

Ces méthodes permettent de créer un effet "fondu".

Avec la méthode fadeOut l'objet disparaît complétement ; ce qui peut être évité avec la méthodefadeTo

Exemple simple

Le code correspondant :

... <style> img {opacity : 0.2; width : 15% ; margin:auto:} ... <body> ... <img src ="../images/bikini.jpg" /> <img src ="../images/trikini.jpg" /> ... <script> $("img").mouseover(function(){$(this).fadeTo(1000,1).width("30%"); }); $("img").mouseout(function(){$(this).fadeTo(1000,0.2).width("15%"); }); ...

Au départ les images sont miniatures et quasi transparentes.
Si survol d'une image celle-ci s'agrandit et devient opaque.

Dans les deux instructions on chaîne les méthodes fadeTo et width.
Testez l'exemple !

Rappel : plutôt que deux instructions liées aux événements mouseover et mouseout j'aurais pu utiliser une seule instruction basée sur l'événement hover.
Faut-il rappeler la grande souplesse de la méthode width (ou height) qui permet de redimensionner un objet que les dimensions initiales aient été passées en attribut ou en propriété de style.

Avec fonction de rappel (callback)

Les méthodes fadeIn et fadeOut acceptent un deuxième argument : une fonction de rappel.
Testez l'exemple avec fonction de rappel

Vous constatez qu'il y a toujours qu'un bouton de commande visible en fonction du contexte. Lorsque les images sont apparentes seul le bouton "rendre transparent" est affiché. C'est logique.

Le code :
Je vous communique que des brides de code car vous devez être capable de le reconstituer en fonction des exemples précédents. En particulier de l'exemple de callback avec les méthodes slideUP et slideDown.

... <style> img {width : 15% ; display : inline-block ; vertical-align : top ; } ... <button ...>Rendre opaque les images</button> <button>Rendre transparent les images</button> <img src ="../images/bikini.jpg" /> <img src ="../images/trikini.jpg" /> ... <script> $("button:first").click(function() { $("img").fadeIn("slow", function() {... }) }); $("button:last").click(function() { $("img").fadeOut("slow", function() {... }) }); ...

HTML: un des boutons est par défaut masqué ; les images sont apparentes (opaques).

Script : puisqu'il n'y a que deux boutons de commande c'est plus simple de les désigner par :first et :last.

Réaliser un diaporama

Les images empilées (grâce au positionnement absolu) selon un certain ordre (géré par la propriété CSS z-index) apparaissent successivement.

... <style> img { position: absolute; left: 100px; top: 100px; width : 400px; } </style> </head> <body> <button>Lancer diaporama</button> <img src ="../images/bikini.jpg" style ="z-index :4;"/> <img src ="../images/trikini.jpg" style ="z-index :3;"/> ... <script> $("button").click(function(){ $('img').first().fadeOut(3000, function suivante() { $(this).next('img').fadeOut(3000, suivante); }); }); </script> ...

Le premier élément de la collection des images (bikini.jpg) est en premier plan (z-index : 4).
Le dernier élément de la collection des images (jolie_fille.jpg) est en dernier plan (z-index :1).
la première image s'efface progressivement puis c'est au tour de la deuxième et ainsi de suite.

Encore une fois l'enchaînement est réalisé grâce à une fonction récursive ! Testez l'exemple !

Animations personnalisées

Exemple 1

Si clic sur la boîte celle-ci voit sa taille doubler et devenir complètement opaque puis dans un deuxième temps la taille est divisée par 2 et la boîte redevient transparente.

Le code correspondant :

... <body> <p class ="remarque">Cliquez sur la boîte rose pourqu'elle double de taille et devienne opaque puis dans un deuxième temps se réduise de moitié et redevienne transparente. <div id="carre" style ="width : 100px ; height :100px ; background : red; opacity : 0.1;"></div> <script> $('div').click(function() { $(this) .animate({width: '200', height: '200', opacity : "1"},2000) .animate({width: '50', height: '50', opacity : "0.1"},2000); }); </script> ...

Emploi de la méthode animate.
Dans l'instruction on chaîne plusieurs fois la méthode animate.

Syntaxe de la méthode animate

sélecteur.animate({propriété : valeur, propriété : valeur,... }[, durée, fonction])
Ainsi dans l'exemple ci-dessus on modifie pour chaque étape de l'animation trois propriétés de mise en forme : width, height, opacity.
La durée de chaque étape de l'animation est exprimée sous forme d'un entier (en millisecondes) ou sous forme d'une chaîne (fast, normal, slow).
Cet argument est facultatif. Dans ce cas la durée est de 400 millisecondes.
Si vous précisez fast la durée est de 200 millisecondes et de 600 millisecondes pour slow et de 400 millisecondes pour normal. Testez l'exemple !

Exemple 2

Une balle parcourt un carré de 40% sur 200 et ce sans fin.

Le code correspondant :

... <style> #balle { width: 20px; height: 20px; background-color: red; border-radius: 10px; position : relative ; box-shadow : 5px 5px 5px grey; } ... <p class ="remarque">La balle parcourt un carré de 40% sur 200 et ce de façon continue. <div id="balle"></div> <script> function deplacement() { $('#balle').animate({left: '+=40%'}, 'slow') .animate({top: '+=200'}, 'slow') .animate({left: '-=40%'}, 'slow') .animate({top: '-=200'}, 'slow', deplacement) }; deplacement(); // appel fonction deplacement </script> ...

Le CSS :
Attention l'objet identifié balle doit être positionné en relatif ou absolu pour pouvoir utiliser les propriétés left et top.
Il faut utiliser la propriété border-radius pour transformer le carré en rond.

Le script :

Dans le cadre de la fonction deplacement la méthode animate est appliquée quatre fois à la balle afin que celle-ci parcoure un carré.

Dans la description de la fonction d'animation dénommée deplacement il y a appel de cette fonction (dans le dernier animate.
Donc cette fonction est récursive afin que l'animation soit sans fin !

Remarquez les valeurs des propriétés left/top. Ainsi left: '+=40%' veut dire que la valeur de left est incrémentée de 40% (par rapport à la largeur du container). top: '-=200' veut dire que la valeur de top est décrémentée de 200 pixels. On dit que les valeurs sont exprimées en relatif.
Testez l'exemple !

Il n'est pas obligatoire d'utiliser une fonction récursive pour obtenir une animation qui se répète sans fin.
Si vous avez visité les tutos sur l'API Canvas ou sur "Animer des objets SVG" vous savez déjà que le "couteau suisse" de l'animation en JavaScript est la fonction setInterval.

Exemple 2 : deuxième solution

Je reprend le thème de la balle qui parcourt un carré mais dans le script je vais cette fois utiliser la fonction setInterval

Le code HTML :

... <p class ="remarque">La balle parcourt un carré de 40% sur 200 et ce sans fin. <br>Un peu de patience : l'animation démarre au bout de deux secondes ! <div id="balle"></div> <button>Mettre fin au déplacement de la boule rouge</button> ...

Le CSS est identique à la première solution.

Par contre dans le HTML j'ai ajouté un bouton de commande qui permettra de mettre fin à l'animation.

Le script correspondant :

function deplacement() { $('#balle').animate({left: '+=40%'}, 'slow') .animate({top: '+=200'}, 'slow') .animate({left: '-=40%'}, 'slow') .animate({top: '-=200'}, 'slow') }; // fin définition fonction deplacement var animation = setInterval(deplacement,2400); // appel de la fonction toutes les 2400 millisecondes $("button").click(function(){clearInterval(animation);}); // arrêt de l'animation par le visiteur

La fonction deplacement n'est plus récursive.

J'appelle la fonction deplacement via la fonction setInterval toutes les 2400 millisecondes.
Pourquoi 2400 millisecondes ?
Car chaque phase est réglée à slow ou 600 millisecondes et comme il y a quatre phases ... 600 * 4 = 2400 !
L'appel régulier de la fonction est identifié par la variable animation. Ainsi il est possible au visiteur de mettre fin à cette animation : clerInterval(animation).
Pratique !
Testez cette deuxième solution!

Il y a un problème ! La boule démarre son déplacement 2,4 secondes après le chargement de la page ...
C'est logique : Avec la fonction setInterval() le premier appel de la fonction deplacement a lieu au bout de 2400 millisecondes.
Pour éviter ce genre de situation il suffirait d'insérer dans le code juste avant l'instruction basée sur la fonction setInterval un simple appel simple de la fonction deplacement() !
Donc le script deviendrait alors (extrait) :

... }; // fin définition fonction déplacement deplacement(); // appel au chargement de la fonction var animation = setInterval(deplacement,2400); // appel de la fonction toutes les 2400 millisecondes et à partir de 2,4 secondes ...
Testez cette deuxième solution "débuggée"
Retour menu