Accueil
Mes tutoriels sur la programmation

Dessiner avec SVG - sommaire


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

SVG & CSS : animer un canevas SVG via le CSS

Un exemple basique pour commencer

Thème : un rond devient de plus en plus gros et de plus en plus opaque puis c'est l'inverse.

<svg width="50%" height="auto" viewBox ="0 0 400 400" style ="background : yellow" > <circle cx="200" cy="200" r='10' /> </svg>

On ne peut plus simple.

Le code CSS

@keyframes animer
	{ 
		0% {fill-opacity:0.1; transform :scale(1); fill:red ;}
		50% {fill-opacity :1 ; transform :scale(20) ; fill : green ; }
		100% {fill-opacity:0.1; transform :scale(1); fill: red ;}
	}
circle {animation : animer 20s 0s infinite linear;transform-origin : 50% 50%;}

Pour qu'il y ait seulement changement de rayon il faut règler l'origine de la transformation au centre du canevas avec la propriété transform-origin. En effet par défaut l'origine d'un transformation pour un canevas SVG est l'angle haut gauche.

Le code CSS : autre solution

On aurait pu écrire l'animation CSS autrement :

	@keyframes animer
	{ 
		from {fill-opacity:0.1; transform :scale(1); fill:red ;}
		to{fill-opacity :1 ; transform :scale(20) ; fill : green ; }
	}
circle {animation : animer 10s 0s infinite linear alternate;transform-origin : 50% 50%;}

Quelques explications sont nécessaires ...
Au lieu d'une animation de 20 secondes qui agrandit puis réduit le rond je me contente d'écrire un "keyframes" qui se contente d'agrandir le rond. Mais quand j'applique ce "keyframes" à l'objet SVG circle je précise une animation de 10 secondes mais en "alternate".
alternate veut dire que le sens de lecture du modèle d'animation change à chaque cycle (sens normal puis sens inversé puis de nouveau sens normal et ainsi de suite.

Animation de texte

Animez le SVG avec CSS !

Le code SVG

<svg width="100%" height="auto" viewBox ="0 0 900 100" > <text x ='100' y ='60' width = '600' height = '60' >Animez le SVG avec CSS !</text> </svg>

Le code CSS

    
	svg{background : linear-gradient( 75deg, navy, aqua,white );}
	text{font-family : arial ; font-weight : bold ;	font-size : 60px ;  
		text-shadow : 5px 5px 5px grey ;fill : navy; }
	@keyframes deplace
	{ 
		0% {transform:translateX(-900px); }
		50%{transform : translateX(0px);}
		100% {transform : translateX(900px);}
	}
	text{animation : deplace 10s 0s infinite linear alternate;}

La balise SVG est un élémént HTML a qui on peut appliquer un dégradé linéaire CSS.

Le texte change de direction car dans la propriété animation il y a le paramètre alternate.

SVG & CSS : pièges à éviter

Après s'être habitué à animer des objets HTML via CSS on peut être tenté d'intégrer dans un "keyframes" devant s'appliquer à un objet SVG des propriétés de style telles box-shadow, background, position, top, left et d'autres. Or ces propriétés CSS ne sont pas reconnues par le format SVG !
Pour un élément SVG et à la place de "background", il faut utiliser la propriété "fill".
par contre, comme nous l'avons vu ci-dessus, on peut appliquer à du texte SVG la propriété "text-shadow".

Déplacer des 'sprites' dans le canevas SVG

Le code du fichier SVG (extrait)

... <svg viewBox="0 0 800 500" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com" xmlns:xlink="http://www.w3.org/1999/xlink"> <style> @keyframes deplace { 0% {transform : translateX(800px); } 100% {transform : translateX(-60px); } } #cycliste1 {animation : deplace 15s 1s infinite linear;} #cycliste2 {animation : deplace 20s 1s infinite linear;} </style> <defs> <bx:grid x="0" y="0" width="100" height="100"/> <filter id="flou"> <feGaussianBlur stdDeviation="2" /> </filter> </defs> <rect y="1" width="800" height="333" style="fill-opacity: 0.4; fill: rgb(152, 220, 239);" filter="url(#flou)" /> <rect y="334" width="800" height="166" style="fill: rgb(114, 109, 109);" filter="url(#flou)" /> <rect y="334" width="800" height="53" style="fill: rgb(55, 225, 70);" filter="url(#flou)" /> <rect x="0" y="437" width="800" height="6" style="fill: rgb(245, 234, 115);" filter="url(#flou)"/> <g filter="url(#flou)"> <ellipse style="fill: rgb(255, 255, 255);" cx="279" cy="83" rx="148" ry="43"/> <ellipse style="fill: rgb(255, 255, 255);" cx="512" cy="49" rx="143" ry="30"/> </g> <desc>arbres</desc> <g transform="matrix(1.1261, 0, -0.00688, 1.11564, 113.61607, -34.63032)" filter="url(#flou)"> <ellipse style="fill: rgb(19, 229, 19);" cx="201" cy="180" rx="26" ry="79"/> <rect x="196" y="259" width="11" height="83" style="fill: rgb(159, 55, 14);"/> </g> <g transform="matrix(1.1261, 0, 0, 1.10802, 483.35812, -32.02557)" filter="url(#flou)"> <ellipse style="fill: rgb(19, 229, 19);" cx="201" cy="180" rx="26" ry="79"/> <rect x="196" y="259" width="11" height="83" style="fill: rgb(159, 55, 14);"/> </g> <g transform="matrix(1.1261, 0, 0, 1.11564, 398.93243, -34.63029)" filter="url(#flou)"> <ellipse style="fill: rgb(19, 229, 19);" cx="201" cy="180" rx="26" ry="79"/> <rect x="196" y="259" width="11" height="83" style="fill: rgb(159, 55, 14);"/> </g> <g transform="matrix(1.1261, 0, 0, 1.05442, -101.06808, -13.69294)" filter="url(#flou)"> <ellipse style="fill: rgb(19, 229, 19);" cx="201" cy="180" rx="26" ry="79"/> <rect x="196" y="259" width="11" height="83" style="fill: rgb(159, 55, 14);"/> </g> ... <desc>GIF animes inseres dans zone de dessin</desc> <image y="350" width = "60" height ="60" xlink:href="../images/cycliste1.gif" id ="cycliste1" /> <image y="350" width = "60" height ="60" xlink:href="../images/cycliste2.gif" id ="cycliste2" /> </svg>

Pour créer cette animation j'ai d'abord utilisé l'application en ligne Boxy SVG pour dessiner, ciel, arbres, route,etc.

Insertion des animations SVG dans une page web

Attention comme le fichier SVG contient des liens vers d'autres images, l'insertion dans la page de cette animation ne peut se faire qu'avec la balise object. J'ai donc écrit dans cette page web le code suivant :

<object type="image/svg+xml" data="road_css.svg" width ="80%"></object>

Une animation 3D

Ci-dessous un jet qui atterit sur la piste.

L'animation 3D correspond à un fichier SVG. Je vous communique le code de ce fichier ci-dessous.
Ce fichier SVG comprend non seulement du SVG mais aussi du CSS.

Le code du fichier "atterisage.svg"

... <svg width ="90%" height ="auto" viewBox ="0 0 900 600" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style ="background-image :url(../images/piste.svg); background-size :cover;" > <style> @keyframes animer { 0% {transform : scale(0.1);} 25% {transform : scale(0.4) ;} 50% {transform : scale(0.8) ;} 75% {transform : scale(1) ;} 90% {transform : scale(1.4) ;} 100% {transform : scale(1.5) ;} } #jet {animation : animer 16s 0s infinite linear forwards ;} </style> <defs> <g id ="avion" > <line x1="0" y1="70" x2="260" y2="70" stroke="lightgrey" stroke-width ="4px" stroke-linecap = 'round'/> <line x1="130" y1="0" x2="130" y2="40" stroke="lightgrey" stroke-width ="2px" stroke-linecap = 'round'/> <line x1="80" y1="20" x2="180" y2="20" stroke="lightgrey" stroke-width ="2px" stroke-linecap = 'round'/> <circle cx="130" cy ="60" r ="30" fill ="lightgrey" /> <circle cx="130" cy ="65" r ="2" fill ="grey" /> <circle cx="80" cy ="90" r ="15" fill ="lightgrey" /> <circle cx="180" cy ="90" r ="15" fill ="lightgrey" /> <circle cx="80" cy ="90" r ="10" fill ="gray" /> <circle cx="180" cy ="90" r ="10" fill ="gray" /> <line x1="100" y1="70" x2="100" y2="100" stroke="lightgrey" stroke-width ="2px" /> <line x1="160" y1="70" x2="160" y2="100" stroke="lightgrey" stroke-width ="2px" /> <line x1="110" y1="90" x2="110" y2="110" stroke="darkgrey" stroke-width ="6px" /> <line x1="150" y1="90" x2="150" y2="110" stroke="darkgrey" stroke-width ="6px" /> <polygon points ="130,30 155,50 105,50" fill ="black" /> <line x1="130" y1="30" x2="130" y2="50" stroke="lightgrey" stroke-width ="2px" /> </g> </defs> <use xlink:href ="#avion" x ="750" y ="450" /> <use xlink:href ="#avion" id ="jet" x ="250" y ="250" /> </svg>

Commentaire

Rappel : dans le cadre d'un code SVG externe (fichier SVG) les "namespaces" xmlns="http://www.w3.org/2000/svg" & xmlns:xlink="http://www.w3.org/1999/xlink" sont obligatoires. Codez un document SVG sans ces "namespaces" et demandez une exécution avec un navigateur vous verrez ...

Le canevas SVG a pour background une image vectorielle qui a été produite avec Inkscape (piste.svg).

Le document SVG comprend une feuille de style avec un "keyframes" ; ce modèle d'animation est appliqué à l'objet SVG identifié "jet".
Cet objet "jet" est le clone d'un modèle défini et identifié "avion".
Un autre clone pour représenter un avion sur le tarmac.

Notez que le modèle d'animation repose sur la propriété transform avec ici la fonction scale() qui provoque de facto une translation puisque le point d'origine de la transformation dans un canevas SVG est le coin haut gauche du canevas !

Insertion de l'image vectorielle animée dans cette page

Pour les mêmes raisons que l'exemple précédent, la balise IMG ne convient pas. Il faut utiliser la balise OBJECT pour insérer le fichier SVG dans la page.

<object type="image/svg+xml" data="atterrissage.svg"></object>