Snap SVG : approfondissements

Dans la page précédente nous avons découvert la bibliothèque et quelques méthodes de base.
Maintenant je vais aller plus loin pour vous montrer toutes les possibilités de ce framework en abordant d'autres méthodes.

Exemple 1 : after & before

Le rendu

Notez que la ligne noire est au dessus de l'ellipse et que l'ensemble est penché.

Le code correspondant

Un instruction HTML crée une zone SVG adaptative dans la page ; le script se contente de la remplir.

<svg viewBox ="0 0 800 400" width ="80%" height ="auto" id ="zone"> </svg> <script> var s = Snap("#zone") ; // utiliser une zone SVG existante var rx = 100; var ry = 150; // dimensions futures de l'ellipse var ligne = s.line(100,200,300,200).attr({stroke: 'black', strokeWidth : 30}) ; // dessiner ligne var ellipse = s.ellipse(200, 200, rx, ry).attr({fill: 'blue'}).after(ligne); // dessiner ellipse sous ligne var groupe = s.group(ellipse,ligne); // grouper les deux formes en un objet groupe.attr({transform : 't400r45'}); // translater et incliner l'objet

Je vous rappelle que si vous exprimez la largeur du canevas en % il faut impérativement utiliser l'attribut viewBox !
l'attribut ID est indispensable pour identifier la zone SVG dans le script.
Les paramètres d'une forme peuvent être des variables ; c'est ce que je fais pour dessiner l'ellipse.
Comme en jQuery on peut chainer les méthodes. Ainsi en une seule instruction il est possible de définir et colorier une forme (remplissage et contour).
L'instruction qui dessine l'ellipse est exécutée après celle qui dessine la ligne ; donc l'ellipse devrait être au dessus de la ligne or c'est l'inverse ... En effet j'ai utilisé la méthode after(élément). Il existe aussi la méthode before(élément).
On peut grouper plusieurs formes en un seul objet avec la méthode group(élément,élément, ...).
Ici je groupe les deux formes en un groupe intitulé "groupe" et j'applique à cet objet une transformation avec : translation & rotation.

Exemple 2 : utiliser dans le script des boucles

Via Snap SVG on peut utiliser les boucles JS !

Le code correspondant

... <svg viewBox ="0 0 800 400" width ="80%" height ="auto" id ="zone1"> </svg> <script> var s = Snap("#zone1") ; var pos_x = 50, pos_y = 50; var carre = s.rect(pos_x,pos_y,100,100).attr({stroke : "red", fill : "none", strokeWidht : 2}); for(var vcompteur = 1; vcompteur < 15 ; vcompteur++) { pos_x = pos_x + 20; pos_y = pos_y + 20; carre.clone().attr({x: pos_x, y:pos_y}); } ...

Grâce à une boucle un canevas SVG existant (et adaptatif) est rempli de 14 carrés !
Notez l'utilisation de la méthode clone().

Le rendu

Exemple 3 : Méthodes polygon() & polyline

Dans cet exemple je présente les méthodes polygon(), polyline(). J'en profite aussi pour expliquer comment produire des contours sous forme de tirets.

Le script

	var s = Snap("#zone2");
	s.circle(100, 100, 80).attr({fill: "none",stroke: 'red',  strokeWidth: 30,    strokeDasharray: "15 10"});
	// une forme fermée
	s.polygon(100, 200, 380, 200, 380, 400).attr({fill : "none", stroke : "purple", strokeWidth : 10, strokeLinejoin : "bevel"}); 
	// une forme ouverte
	s.polyline(50, 300, 350, 300, 350, 500).attr({fill : "none", stroke : "orange", strokeWidth : 10, strokeLinecap : "round"}); 

Ceux qui ont utilisé les balises line, polygon, polyline en SVG traditionnel ne sont pas surpris par le code. Ces balises deviennent des méthodes avec Snap ; les attributs sont écrits selon la syntaxe JS !
Donc l'apprentissage rapide de Snap SVG suppose d'avoir quelques connaissances dans le langage SVG. A chaque balise SVG correspond une méthode Snap !

Le contour du cercle est une suite de tirets rouges grâce à l'attribut strokeDasharray : "15 10".
La méthode polygon(x1,y1, x2,y2,..., xn,yn) permet de réaliser des formes fermées puisque une ligne est automatiquement ajoutée entre le premier et le dernier point.
Le style des angles est défini avec l'attribut strokeLinejoin : bevel / round / miter (par défaut)
La méthode polyline(x1,y1, x2,y2,..., xn,yn) permet de réaliser des formes ouvertes.
Le style des extrémités des lignes (et suites de lignes) est défini avec l'attribut strokeLinecap : round / square / butt (par défaut)

Le résultat

Exemple 4 : insertion d'images matricielles et de textes

Dans ce quatrième exemple je vais vous montrer comment insérer (une simple liaison) une image existante dans une zone SVG.
Vous savez qu'en SVG traditionnel il faut utiliser la balise image et donc d'après vous qu'elle est la méthode dans Snap ???
J'insère aussi dans le canevas SVG du texte ...

Le code CSS & HTML

<style> .forme1{fill : red ; font-size : 30px ;text-anchor : middle ; } ... <svg viewBox ="0 0 600 400" width ="80%" height ="auto" id ="zone3" style = "background : url(fond1.jpg); background-size : cover;"> </svg>

Une classe "forme1" pour formater du texte SVG.
Je rappelle que la propriété text-anchor gère l'alignement horizontal du texte par rapport au paramètre x. Si valeur est "middle" le texte se positionne autour du point x.

La zone de dessin dispose en "background" une belle image dont les dimensions sont adaptées au canevas

Le script

var s = Snap("#zone3"); var requin = s.image("requin.gif",50,50,100,70); var plongeur =s.image("plongeur.gif",500,200,90,50); var contenu ="Rencontre funeste"; var texte = s.text(300,350, contenu); texte.attr({class : "forme0"}); function effacer() {this.remove(); } requin.click(effacer); plongeur.click(effacer);

la méthode image(src,x,y,L,H) permet d'insérer (sous forme d'un liaison) une image matricielle dans un canevas SVG.
this.remove() efface l'élément courant. Donc la fonction intitulée "effacer" est générique : s'applique à l'élément courant.
Il existe aussi la méthode s.clear() qui vide le canevas identifié "s" de tous ses éléments.

Notez comme la programmation événementielle est simple en Snap SVG : élément.événement(fonction)

Le rendu

Cliquez sur le requin OU le plongeur pour effacer cet objet.
Actualisez la page pour afficher de nouveau les "sprites".

Exemple 5 sur la méthode transform()

Compte tenu de son importance le mot "transform" n'est pas seulement un attribut de la méthode attr() mais peut être également une méthode à part entière !

Le script

	var s = Snap("#zone4");
	//insertion d'une image SVG dans le canevas
	var avion = s.image("avion.svg", 0,0, 260,110 );
	// clonage de l'image vectorielle importée
	var avion2 = avion.clone(); var avion3 =avion.clone();
	// transformations relatives aux clones
	avion2.transform('t100,300 r15');
	avion3.transform('t600,0 s .5 r-30'); 
	
	function effacer() {this.remove(); };
	avion.click(effacer); 
	avion2.click(effacer);
	avion3.click(effacer);

On peut insérer avec la méthode image() non seulement des images matricielles mais aussi des images vectorielles (fichier au format SVG).
Le fichier "avion.svg" a été produit avec Inkscape !
J'applique la méthode transform() aux clones de avion.svg
Comme dans le canevas précédent on peut effacer l'élément courant.

Les résultat

Cliquez sur un élément pour l'effacer. Actualisez la page pour réafficher toutes les formes.

Les clones ont subi des translations, des rotations et des changements d'échelle !

Les méthodes relatives aux classes

Sachez que les méthodes addClass(), removeClass(), toggleClass() présentes chez jQuery existent aussi chez Snap SVG.

Le CSS relatif au canevas

	.forme1 {fill: red; stroke-width : 5 ; stroke : green; }
	.forme2 {fill: yellow; stroke-width : 5 ; stroke : purple; }
	.forme3{fill : none ; font-size : 30px ; stroke : navy ; stroke-width : 1 ; text-anchor : middle ; }

Le script

	var s = Snap("#zone5");
	var carre5 =s.rect(10,10,100,100,50);
	// un carré qui ressemble à un rond !
	carre5.addClass("forme1"); 
	var cercle5 =s.circle(200,200,50);
	cercle5.addClass("forme2"); 
	
	// fonction qui supprime la classe 
	function effacer_forme() {carre5.removeClass("forme1"); cercle5.removeClass("forme2"); }
	
	var texte1 = s.text(200,350,"Effacer mise en forme"); 
	texte1.addClass("forme3");
	texte1.click(effacer_forme); 
	
	// fonction bascule : rajoute ou supprime la classe
	function bascule() { carre5.toggleClass("forme1"); cercle5.toggleClass("forme2"); }
	
	var texte2 = s.text(600,350,"bouton bascule"); 
	texte2.addClass("forme3");
	texte2.click(bascule); 

J'en profite pour vous montrer comment dessiner un cercle avec la méthode rect(). Il suffit de dessiner un carré avec des angles arrondis : rayon d'arrondi = la moitié du côté.

Il est plus simple d'utiliser la méthode addClass() que la méthode attr() avec l'attribut "class".
La méthode removeClass(nomClasse) permet de retirer une classe à un élément.
La méthode toggleClass(nomClasse) ajoute la classe à l'élément si elle est absente ; retire la classe à l'élément si elle est présente.

Le résultat

Cliquez sur le texte "effacer mise en forme" pour que les formes soient noires.
Cliquez sur le texte "bascule" pour retirer/ajouter les couleurs aux formes.

Les méthode Snap.paste()

Grâce à cette méthode utilisée conjointement avec append() on injecte du code SVG traditionnel dans le script.

Le script

var paper = Snap("#zone6"); //création d'une infobulle var bulle = Snap.parse('<title>Ceci est un carré noir</title>'); var carre6 = paper.rect(20,20,40,40); // ajout de l'infobulle au carré carre6.append(bulle); // définition d'un rectangle var rectangle6 = Snap.parse('<rect x ="100" y ="100" width ="200" rx ="50" height ="100" fill ="yellow" />'); // ajout du rectangle au canevas paper.append(rectangle6);

Ici le canevas est désigné par la variable "paper" ; c'est le terme d'usage dans la documentation officielle de Snap SVG.
Une info bulle et un rectangle sont définis avec la méthode Snap.parse(code SVG traditionnel)
Ensuite l'info bulle est ajoutée à "carre6" et le nouvel élément SVG est ajouté à "paper".

Le résultat

Survolez le carré noir ; une infobulle apparait.

Transform : rotation

Revenons sur la méthode transform et sur les rotations en particulier.
On peut préciser l'origine d'une rotation. Donc la syntaxe de la méthode transform devient : transform : "r angle,x,y"

Exemple : dessiner une horloge

Le script

s = Snap("#zone7");
// attributs communs à plusieurs formes
var param ={fill : "none", stroke : "black", strokeWidth : 2 }; 
// dessiner cadran, aiguilles des heures et des minutes
var cadran = s.circle(200,200,150).attr(param);
var minute =s.line(200,200,200,60).attr(param); 
var heure = s.line(200,200,200,100).attr(param); 
minute.transform("r30,200,200");
heure.transform("r60,200,200");

Notez l'utilisation de la variable param qui permet d'affecter les mêmes attributs à plusieurs formes.
On dessine deux lignes en rotation dont l'origine et le point de coordonnées 200, 200.

Transformations - suite

Exemple

Survolez le carré et observez

Sur survol du carré, celui-ci et le texte subissent une rotation plus un changement d'échelle du carré.
A la fin du survol retour à l'état initial.

Le script

Pour info le code SVG traditionnel :

<svg id="zone8" width ="80%" height="auto"> </svg>

Donc le script doit définir un viewbox puisqu'il est absent dans la balise SVG !

	var s = Snap("#zone8"); 
	// le viewBox du canevas SVG est créé dans le cadre du script Snap SVG !
	s.attr({ viewBox: "0 0 600 300" });
	var carre = s.rect(100,100,100,100,20,20).attr({ stroke: '#123456', 'strokeWidth': 20, fill: 'red', 'opacity': 0.2 });
	var texte = s.text(100,100,"rotation et changement d'échelle");
	function t1()
	{
		texte.transform("r45,100,100"); 
		carre.transform("s2 r45,100,100");
	}
	function t2()
	{	
		texte.transform("r0");
		carre.transform("s1 r0");
	}
	carre.hover(t1,t2); 

Notez bien la façon d'annuler une rotation et un changement d'échelle : "r0" pour annuler une rotation et "s1" pour annuler un changement d'échelle.

Passons au chapitre suivant Suite !
Retour menu