Accueil

Dessiner avec SVG - sommaire

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

Vous savez qu'avec le SMIL et en particulier la balise ANIMATE on peut enchainer les animations et on peut répéter à l'infini une séquence d'animations.
Peut-on faire la méme chose avec Snap SVG ?

Animations avec Snap SVG : approfondissements

Vous savez qu'avec le SMIL et en particulier la balise ANIMATE on peut enchainer les animations et on peut répéter à l'infini une séquence d'animations.
Peut-on faire la méme chose avec Snap SVG ?
La réponse est OUI !

Enchainer les animations

La méthode animate peut avoir un troisième argument : une fonction de "callback".

Le rendu

Actualisez la page pour relancer l'animation !

Il y a deux animations qui s'enchainent : d'abord celle concernant l'ellipse bleu marine puis celle concernant l'ellipse rouge.

Le code correspondant

<svg id="zone" width ="80%" height="auto"> </svg> <script> var s = Snap("#zone") ; s.attr({ viewBox: "0 0 600 400" }); // définition d'un repère cartésien de 600 par 400 var X = 600; var Y = 400; var ellipse = 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}); ellipse.animate({ry:100}, 4000, function(){ellipse2.animate({ry: 200}, 4000)}) ; ...

Attention, ça devient un peu compliqué au niveau des accolades et parenthèses.

Le canevas est responsive et l'attribut "viewBox" est rajouté dans le script.

Notez l'astuce pour que les cercles et ellipses soient centrées dans le canevas ; les arguments cx & cy exprimés par rapport aux deux dernières valeurs du viewBox.
Donc si les valeurs du viewBox changent il faut mettre à jour le script : changer les valeurs des variables X et Y.

Ici la méthode animate a ici un troisième argument : une fonction de rappel ("callback") c'est à dire une fonction exécutée à la fin de l'animation.
Dans l'exemple le "callback" consiste en une deuxième animation mais qui s'applique cette fois à "ellispe2" (l'ellipse rouge).
Donc les deux animations s'enchainent !

Répéter une suite d'animations à l'infini

L'animation

Patientez quelques secondes ...

Remarquez que le requin ne sort pas de la zone d'animation.

Le code HTML correspondant

<svg width ="80%" height="auto" viewBox ="0 0 600 400" id="zone2" style ="background-image :url(fond1.jpg) ; background-size : cover ;" > <image xlink:href="requin.gif" width="100" height="70" x = '0' y ='0' id ="requin"/> </svg>

J'aurais pu inséré le requin (gif animé) via le script avec la méthode image() mais je ne l'ai pas fait car je veux vous montrer ici la grande souplesse de la librairie Snap : on écrit le code d'abord en SVG puis dès qu'on aborde l'animation on se dit qu'il est plus facile d'utiliser Snap SVG que le SMIL ou CSS ou encore JavaScript.

Le script correspondant

	var s = Snap("#zone2") ;
	// utiliser une zone SVG existante
	var x_max = 500 ; 	var y_max = 330; 
	var squale = Snap('#requin');
	// identifier l'image matricielle insérée dans le canevas
	function deplace()
	{
		squale.animate({x: x_max, y: y_max},3000, 
		function(){squale.animate({x: 0, y: 0},3000);});
	};
	// fonction qui fait faire un aller-retour au requin : 
	// 3 sec à l'aller et 3 sec au retour
	deplace(); 
 	setInterval(deplace, 6000);
	// appel de la fonction tout les 6 secondes
...

Comme l'image PNG fait 100 par 70 les coordonnées maximales sont 500 et 330 compte tenu des width & height du viewBox (600 par 400).

On définit une fonction "deplace" contenant les deux animations qui s'enchainent.
Cette fonction est ensuite appelée toutes les 6 secondes via l'instruction basée sur la méthode "setInterval".
Méthode setInterval() bien connue de ceux qui connaissent l'API JavaScript Canvas.

Les événements

Une animation peut être déclenchée suite à un événement.

Le canevas avec les animations

Cliquez sur le requin pour le déplacer !
Survolez le bouton de commande pour agrandir le squale ! agrandir / réduire le requin

Le code HTML et SVG correspondant

<svg id="zone3" width ="100%" height="auto" viewBox ="0 0 600 400" style ="background-image :url(fond1.jpg) ; background-size : cover ;" > <g id="bouton"> <rect x="0" y="360" height="40" width="200" fill="gray"/> <text x="0" y="380" font-size="20" fill="white">agrandir / réduire le requin</text> </g> </svg>

Le script

	var s = Snap("#zone3") ;
	var squale2 = s.image("requin.gif",50,50,100,70); 
	// insertion d'une image matricielle dans le canevas
	var bouton = Snap('#bouton'); 
	//déplacement du requin
	function deplace() 
	{
	squale2.animate({ x: 500, y: 330}, 4000, 
		function(){squale2.animate({x: 0, y: 0}, 4000)}) ;
	}
	//taille du requin augmente
	function agrandir() 
	{
		squale2.animate({width: 200, height : 140},1000);
	}
	// taille du requin diminue
	function reduire() 
	{
		squale2.animate({width: 100, height : 70},1000);
	}
	
	// animations : 
	squale2.click(deplace); 
	bouton.mouseover(agrandir); 
	bouton.mouseout(reduire); 
	...

Commentaire

En SVG on dessine le canevas et à l'intérieur de celui-ci un rectangle grise avec un texte en blanc et identifiée :"agrandir/réduire le requin".

Pour éviter toute confusion avec le script précédent (mais dans la même page web) l'image PNG est ici référencée par la variable squale2.

Nous voyons deux nouveaux événements de Snap : mouseover() & mouseout().
Donc les événements Snap ressemblent aux événements jQuery. Pour chaque type d'événement et comme avec jQuery, le préfixe "on" a disparu !
Il faut écrire "click" (et non pas "onclick"), dblclick (et non pas "ondblclick"), etc ...