Vous pouvez me contacter via Facebook pour questions & suggestions :
Page Facebook relative à mon site
Dans le chapitre précédent les différentes animations étaient simultanées.
Quid de l'enchainement d'animations : animation1 puis animation2, etc ?
Comment répéter à l'infini une fonction incluant une séquence d'animations ?
Le rythme de l'animation n'est pas forcément linéaire.
Les méthodes snap.animation() & snap.set() permettent d'obtenir des scripts très courts tout en animant
plusieurs objets du canevas.
La méthode animate peut avoir un troisième argument : une fonction de "callback".
Deux animations qui s'enchainent !
Cliquez dans le canevas pour lancer l'animation.
Actualisez la page pour revenir à l'état initial.
HTML : un canevas identifié "zone1".
Le script :
var s = Snap("#zone1") ;
s.attr({ viewBox: "0 0 600 400" });
var X = 600; var Y = 400;
var ellipse1 = s.ellipse(X/2, Y/2,100,200).attr({ fill: 'Navy',fillOpacity : .5});
var ellipse2 =s.ellipse(X/2, Y/2,200,100).attr({ fill: 'red',fillOpacity : .5});
// fonction avec enchainement de deux animations
function fanimer()
{
ellipse1.animate({ry:100}, 4000, function(){ellipse2.animate({ry: 200}, 4000)});
}
// appel fonction
s.click(fanimer);
Remarquez l'astuce pour que les ellipses soient bien centrées : on crée deux variables X & Y qui correspondent
aux limites (les deux dernières valeurs du viewBox) du repère cartésien.
Les paramètres de position des ellipses (cx & cy) deviennent donc égales X/2 et Y/2.
Dans la fonction "fanimer" on définit un enchainement de deux animations grâce à un troisième argument à la méthode
animate(). Cette fonction de callback définit une animation sur l'objet "ellipse2".
Les deux premiers arguments quant à eux, définissent une animation sur l'objet "ellipse1".
Un carré de couleur "olive" et ombré fait un AR dans le canevas.
Le HTML :
< svg width ="80%" viewBox ="0 0 600 400" id="zone2" style ="background : radial-gradient(darkgreen, green, lime,palegreen );" >
Le canevas est rempli avec un dégradé radial CSS3.
Le script :
var s = Snap("#zone2") ;
var x_max = 550 ; var y_max = 350;
var ombrage = s.filter(Snap.filter.shadow(10,10, .5));
var carre =s.rect(0,0,50,50).attr({fill : "olive", filter : ombrage});
function fdeplace()
{
carre.animate({x: x_max, y: y_max},3000, function(){
carre.animate({x: 0, y: 0},3000); });
};
fdeplace(); // pour ne pas patienter 6 secondes !
setInterval(fdeplace, 6000);
// appel de la fonction tout les 6 secondes
Piqure de rappel sur les filtres en Snap SVG et plus précisément l'ombrage.
Comme le canevas fait 600 par 400 et que le carré fait 50 par 50 les valeurs de x_max& y_max sont respectivement 550 et 350 afin que le carré ne sorte jamais du canevas.
Observez bien la définition de la fonction fdeplace() : une instruction unique basée sur la méthode animate() avec trois arguments dont une fonction de callback. Ainsi vous générer un aller-retour.
Notez l'utilisation d'une méthode bien connue du JS standard : setInterval(fonction, intervalle de temps) pour appeler régulièrement la fonction fdeplace().
Cette méthode permet de définir très rapidement un ensemble d'objets voire de les animer.
L'emploi de cette méthode
Cliquez sur le premier rond pour démarrer l'animation.
Actualisez la page pour revenir à la situation initiale.
Les ronds grandissent, deviennent opaques et changent de couleur sauf le quatrième qui n'est pas concerné par l'animation
Le viewbox dans l'instruction HTML définit un repère de 900 par 600.
Le script :
var paper = Snap("#zone3");
var ombrage = paper.filter(Snap.filter.shadow(10,10,.5));
var rond1 = paper.circle(30, 30,20);
var ensemble = Snap.set(rond1, paper.circle(100,100,30),paper.circle(200,200,40), paper.circle(300,300,50));
var param = {fill : "red", fillOpacity : .2, filter : ombrage};
ensemble.attr(param);
function fanimer()
{
ensemble.animate(
[{r: 30,fillOpacity :.5, fill : "black"}, 3000],
[{r: 50,fillOpacity :.8, fill : "orange"}, 4000],
[{r: 60,fillOpacity :1, fill:"green"}, 5000]
);
}
rond1.click(fanimer);
Le gros avantage de la méthode Snap.set() est qu'elle permet de définir et animer de nombreux éléments sans devoir les nommer.
Ici la méthode animate() ne comprend que trois paires de crochets donc seuls les trois premiers objets de la série "ensemble" sont
animés.
Rien n'interdit de combiner dans un même script deux méthodes puissantes : Snap.set() et Snap.animation()
Grâce à ces deux méthodes un script très succinct permet d'animer des nombreux objets.
Cliquez sur le premier rond pour démarrer l'animation.
Actualisez la page pour revenir à la situation initiale.
Les quatre ronds se déplacent vers la droite et le bas tout en passant au violet et en doublant de taille.
HTML : un canevas SVG identifié "zone4" avec un viewBox de 900 par 600.
Le script :
var paper = Snap("#zone4");
var ombrage = paper.filter(Snap.filter.shadow(10, 10, .5));
var rond2 = paper.circle(30,30,20);
var serie = Snap.set(rond2, paper.circle(100, 100, 30),paper.circle(200,200,40), paper.circle(300,300,50));
var param = {fill : "red", fillOpacity : .2, filter : ombrage};
serie.attr(param);
var anime_modele = Snap.animation({fillOpacity : 1 , transform :'s2 t400 200', fill : "purple" },5000);
function fanimer2()
{
serie.animate(
[anime_modele],
[anime_modele],
[anime_modele],
[anime_modele]
);
}
rond2.click(fanimer2);
Je crée un ensemble d'éléments SVG nommé "serie".
Je définis un modèle d'animation dans la variable anime_modele qui prévoit : opacité totale, transformation, passage au violet.
J'argumente serie.animate avec ce modèle d'animation quatre fois.
Dans le cadre des animations avec Snap SVG on peut aussi avoir des animations avec des rythmes non linéaires comme je montre dans l'exemple ci-dessous.
Cliquez sur le premier rond pour lancer l'animation.
Actualisez la page pour revenir à l'état initial.
Les boules se déplacent vers la droite, deviennent opaques et changent de couleur.
Pour chaque boule l'animation dure 10 secondes. Aucune des six boules n'a un rythme de déplacement identique !
Par contre l'état final est identique : toutes les boules s'alignent à droite avec un rayon de 50.
HTML : un canevas SVG identifié "zone5" avec un viewBox de 1200 par 600.
Le script :
var paper = Snap("#zone5");
var ombrage = paper.filter(Snap.filter.shadow(10, 10, .5));
// définition d'un ombrage
var rond5 = paper.circle(30,30,30);
var serie5 = Snap.set(rond5, paper.circle(30,130, 30), paper.circle(30,230,30), paper.circle(30,330,30),paper.circle(30,430,30),paper.circle(30,530,30));
// serie5 désigne un ensemble de six ronds
var param_init = {fill : "red", fillOpacity : .2, filter : ombrage};
// attributs initiaux des ronds
serie5.attr(param_init);
function ffin()
{
this.attr({r:50});
}
function fanimer5()
{
serie5.animate(
[{cx : 1100,fillOpacity : 1, fill : "navy"}, 10000, mina.linear, ffin],
[{cx : 1100,fillOpacity : 1, fill : "purple"}, 10000, mina.bounce,ffin],
[{cx : 1100,fillOpacity : 1, fill : "black"}, 10000, mina.easein,ffin],
[{cx : 1100,fillOpacity : 1, fill : "orange"}, 10000, mina.easeout,ffin],
[{cx : 1100,fillOpacity : 1, fill : "olive"}, 10000, mina.elastic,ffin],
[{cx : 1100,fillOpacity : 1, fill : "yellow"}, 10000, mina.easeinout,ffin]
);
} // fin fonction
rond5.click(fanimer5);
La fonction fanimer5() se résume à une instruction unique.
Cette instruction unique comprend 6 paires de crochets donc six animations qui s'appliquent respectivement
aux 6 objets de "serie5".
Dans chaque animation il y a 4 arguments ; le troisième argument est un mot qui précise le rythme de l'animation : linéaire (linear)
OU avec rebond (bounce) OU avec accélération (easein)
OU décélération (easout) OU effet élastique (elastic).
Donc on retrouve exactement la même terminologie que pour les animations CSS.
Le quatrième argument est la fonction ffin; fonction basée sur le mot "this".
Je vais maintenant vous montrer qu'il est possible d'importer une image vectorielle.
Cette image tenant lieu de décor à une animation.
Ladite animation est déclenchée par un clic sur l'objet animé ; elle se répète alors
à l'infini.
Cliquez sur l'autocar pour déclencher l'animation qui se répète alors à l'infini.
HTLM : un canevas avec un viewBox de 1000 par 600.
Le script :
var s6 = Snap("#zone6");
var fond = s6.image("rue.svg",0,0,1000,600);
var autocar = s6.image("autobus.png",800,450,300,100);
function fAR() // AR comme aller retour
{ autocar.animate({x:-300},4000, function(){autocar.animate({x: 1100}, 4000)}); }
// appel fonction
function frepeter()
{
fAR(); // pour éviter d'attendre 8 secondes
setInterval(fAR,8000);
}
s6.click(frepeter)
Notez que la fonction frepeter() appelle la fonction fAr().