Les zones de dessin restent vides car votre navigateur a bloqué le JavaScript

Accueil

Traduction

Dessiner avec SVG - sommaire

Dessiner avec SVG - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Snap SVG : les chemins, le texte, les événements

Avec Snap SVG un chemin peut être noté en relatif (comme en SVG natif).
Pour réduire les lignes de code il ne faut pas hésiter à grouper les formes car certaines méthodes peuvent s'appliquer à un groupe !
Le clonage doit aussi être utilisé sans aucune modération.

Les chemins avec Snap SVG

Objectif : dessiner un sapin de Noël. Il est préférable de réaliser d'abord un croquis sur une feuille à petit carreaux. Ce n'est pas une perte de temps bien au contraire ...

Ci-dessous le croquis

Grâce à ce schéma je détermine facilement les arguments du chemin.
Je vois que si je code le chemin en relatif, je vais avoir des couples 'l 50 50' et des couples 'h-25' puis des couples 'l 50 -50' ...

Le code dans cette page web

CSS & HTML

	.ligne {fill : none ; stroke : gold ; stroke-width : 2px ; }
...
< svg id ="zone1" > 
...

La classe "ligne" pour styler la guirlande.
L'instruction HTML qui dessine un canevas vierge ne précise pas la largeur d'affichage et le système de coordonnées (viewBox).

Le script Snap

	var s = Snap("#zone1");
	s.attr({viewBox :"0 0 400 300", width : "80%"});
	var branches =s.path("M 200 50 l 50 50 h-25 l 50 50 h-25 
		l 50 50 l -200 0 l 50 -50 h-25  l 50 -50 h-25 z").attr({fill : "green"});
	var tronc = s.rect(175,200,50,50).attr({fill : "maroon"});
	// groupage
	var sapin =s.group(branches,tronc); 
	// définition de filtres
	var f1 = s.filter(Snap.filter.blur(2,2));
	var f2 = s.filter(Snap.filter.shadow(10, 10, .5));
	//floutage et ombrage du sapin
	sapin.attr({filter : f1});     
	sapin.attr({filter : f2});   
	// ajout guirlande
	var guirlande =s.polyline(175,75, 225,100,  150,150, 250,150, 125,175).attr({class :"ligne"});
	// ajout boules
	var boule = s.circle(250,100,5).attr({fill : "gold"});
	boule.clone().attr({cx : 150, cy : 100}); 
	boule.clone().attr({cx : 125, cy : 150});
	boule.clone().attr({cx : 275, cy : 150});
	boule.clone().attr({cx : 275, cy : 150});
	boule.clone().attr({cx : 100, cy : 200});                   
	boule.clone().attr({cx : 300, cy : 200});

Remarquez la syntaxe pour rajouter le viewBox au canevas SVG.

Notez que le chemin exprimé en relatif pour dessiner le branchage. Pas de virgules entre les x et y !
Les deux filtres (floutage, ombrage) sont appliqués à "sapin" qui est un groupe de formes (branches + tronc).
Emploi de la méthode polyline() pour dessiner la guirlande. A la différence de polygone le chemin n'est pas fermé. J'aurais pu utiliser path().
Je ne dessine une boule puis je la clone N fois.

Si vous ne connaissez la notation en relatif d'un chemin, je vous renvoie au chapitre sur les chemins dans le tuto sur le SVG natif.
Notation en absolu ou relatif des chemins SVG

Le rendu

Une bannière avec Snap SVG

Nous allons traiter dans cet exemple de la méthode text().

Le rendu

Le code dans cette page web

CSS & HTML

	...
	.forme1{fill : none ; font-size : 40px ; stroke : black ; stroke-width : 2px ; text-anchor : middle ; 
		text-shadow : 5px 5px 5px gray ; }
	...
	<svg viewBox ="0 0 600 100"  width ="100%"  id ="zone2"
		style ="background: linear-gradient(to right, blue,skyblue, white) ;" >

CSS : pour styler le texte d'un canevas, le plus simple est de créer une classe.
On ne peut pas appliquer la propriété box-shadow à un élément SVG ; par contre la propriété text-shadow est compatible avec le DOM SVG.
Je rappelle que la propriété CSS text-anchor spécifique au texte SVG aligne le texte horizontalement ; et si sa valeur est "middle" alors disposition du texte autour du point X.

HTML : la balise SVG étant un élément HTML ; on peut donc lui appliquer la propriété CSS background.

Le script

	var s2 = Snap("#zone2") ;
	var contenu ="Snap SVG, c'est magique !!!";
	var texte = s2.text(300,70, contenu); 
	texte.attr({class : "forme1"}); 

Le script est des plus succinct.

Les événements

Exemple1

Dans ce premier exemple je vous montre qu'il y d'autres événements gérés par Snap que le clic.

Survolez le requin ou le plongeur pour l'agrandir.
Double cliquez sur le requin / le plongeur pour déplacer un de ces objets.

Le code correspondant dans le document HTML

Ici je démarre l'encodage en SVG standard :

J'utilise le SVG standard pour importer des images car cette solution offre un avantage : dans l'élément IMAGE, l'attribut height est absent ; ainsi aucun risque de déformation des "sprites" : hauteur ajustée pour respecter le ratio largeur / hauteur dans l'image source.

Le script :

	var s = Snap("#zone3") ;
	var requin = Snap("#requin");
	var plongeur = Snap("#plongeur"); 
	
	// définitions des fonctions
	function agrandir() {this.transform('s2'); }
	function reduire() {this.transform('s1'); }
	function supprimer() {this.remove();}
	function deplacer() {this.transform('t400 -50'); }
	
	// appel des différentes fonctions
	requin.mouseover(agrandir); 
	requin.mouseout(reduire); 
	requin.dblclick(deplacer); 
	
	plongeur.mouseover(agrandir); 
	plongeur.mouseout(reduire); 
	plongeur.dblclick(deplacer ); 

Notez le mot clé "this" dans les définitions des fonctions.
Chaque "sprite" peut être agrandi et déplacé vers la droite.

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 ...

Exemple 2 : l'événement hover

Snap SVG gère l'événement hover comme jQuery.

Le canevas

Survolez l'une des images ; elle s'agrandit et devient opaque !
L'image reprend sa transparence et sa taille initiale à la fin du survol.

Le code correspondant

Le canevas est identifié "zone4" et y est défini un repère cartésien de 900 par 600.

Le script :

var s = Snap("#zone4") ;
//insertion de deux images sexy dans le canevas
var image1 =s.image("../images/brune_nue.jpg",50,100,250,100).attr({opacity : .1}); 
var image2 =s.image("../images/black_nue.jpg",500,100,150,200).attr({opacity : .1}); 
// deux fonctions 
function f1() {this.attr({opacity : 1, transform : 's2'}) }; 
function f2() {this.attr({opacity : 0.1, transform : 's1'}) }; 
// application des fonctions 
image1.hover(f1,f2);  
image2.hover(f1,f2); 

Emploi de la méthode image() pour importer deux images matricielles.
Emploi de la méthode hover() qui remplace avantageusement les méthodes mouseover & mouseout
Syntaxe de cette méthode : élément.hover(fonction1, fonction2).
"fonction1" est déclenchée lors du survol ; "fonction2" est déclenchée dès que le pointeur quitte l'élément.

Les utilisateurs de jQuery ne seront pas surpris par cet événement ...

Il y a un problème avec la méthode image() : les quatres paramètres sont obligatoires. En d'autres termes, il faut préciser la hauteur de l'image dans le canevas d'où un risque de déformation.
Il est donc préférable de renoncer à Snap SVG pour les importations mais d'utiliser la balise IMAGE.