Snap SVG : chemins, masques et découpes

Avec Snap SVG un chemin peut être noté en relatif (comme en SVG traditionnel).
Pour réduire les lignes de code il ne faut pas hésiter à grouper les formes car la méthode attr() peut s'appliquer à un groupe !
Le clonage doit aussi être utilisé sans aucune modération (lol).
Les outils "masque" et "découpe" sont aussi disponibles avec Snap SVG.

Exemple 1 : 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 correspondant

CSS & HTML

... <style> .ligne {fill : none ; stroke : gold ; stroke-width : 2px ; } ... <svg viewBox ="0 0 400 300" width ="80%" height ="auto" id ="zone"> </svg> ...

Une classe "ligne" pour colorier certains chemins.

Le script

	var s = Snap("#zone") ;
	var branches =s.path("M 200 50 l50 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});

Notez le chemin exprimé en relatif pour dessiner le branchage. Pas de virgules entre les x et y !
Si vous ne comprenez rien dans ce code vous devez visiter la page Notion de chemin
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 qu'une boule ; les autres sont des clones de la première.

Le rendu

Le sapin est légèrement flouté et ombré.
Il comporte une guirlande et des boules.

Ce serait plus amusant si la guirlande et les boules clignotaient ...
La solution prochainement !

Exemple 2 : masque et découpe

Je vous conseille de revoir le chapitre concernant les masques et les découpes en SVG traditionnel afin de bien comprendre à quels effets correspondent ces deux termes. Masques et découpes

Exemple traité avec Snap SVG

Ci-dessous une image insérée dans un canevas et bénéficiant d'un masque et d'une découpe mais cette fois via Snap SVG.

Le script correspondant

	var s = Snap("#zone0") ;
	var rect1 = s.rect(0,0,500,300).attr({fill: "white", fillOpacity : 0.4}); 
	var rect2 = s.rect(0,300,500,300).attr({fill: "white", fillOpacity : 0.2}); 
	var masque = s.group(rect1,rect2); 
	// définition d'un masque comprenant deux parties avec des opacités différentes
	var ellipse = s.ellipse(250,300,200,300).attr({fill : "none"}); 
	// définition d'une découpe
	s.image("../images/jolie_fille.jpg",0,0,500,600).attr({mask : masque, clipPath : ellipse});
	// application à l'image insérée du masque et la découpe

Donc en toute logique les attributs à utiliser dans le cadre de la méthode attr() sont : mask & clipPath !

Exemple 3 : une bannière avec Snap SVG

Le rendu

Le code correspondant

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%" height ="auto" id ="zone2" style ="background: linear-gradient(to right, blue,skyblue, white) ;"> </svg>

On ne peut pas appliquer la propriété box-shadow à un élément SVG. Par contre la propriété text-shadow est compatible !
Je rappelle que la propriété text-anchor aligne le texte horizontalement ; si valeur est "middle" alors disposition du texte autour du point X.
La balise SVG étant un élément HTML de type "block" on peut lui appliquer un dégradé CSS.

Le script

Vous allez aimer Snap ...
Le script est des plus succinct.

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

Prolongements

Snap SVG dispose de différentes méthodes pour animer les formes. Initiation aux animations avec Snap SVG
Retour menu