SVG & JavaScript : animer un objet SVG

Avec JavaScript de base

Le rond rouge est de plus en grand et de plus opaque puis c'est l'inverse et le cycle reprend à l'infini ...

Le code SVG

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

Pour que l'image vectorielle s'adapte à tous les écrans (image adaptative), la largeur du canevas SVG est exprimée en pourcentage. Les positions et dimensions des formes seront calculées grâce aux valeurs de l'attribut viewBox.
Rappel : notion cruciale de viewBox est présentée dans le tuto "Dessiner avec SVG" dans le même site.

Le script

var X = 400 ; //largeur définie dans le viewbox var rond = document.querySelector('circle') ; var rayon = rond.getAttribute('r'); var opacite =rond.style.fillOpacity ; rayon = parseInt(rayon) ; opacite =parseFloat(opacite); var v_rayon = 2; var v_opacite = 0.01 ; setInterval(animate,100) ; function animate() { if (rayon == X/2) { v_rayon = -2 ;v_opacite = -0.01; } if (rayon == 10) { v_rayon = 2 ; v_opacite = 0.01; } rayon += v_rayon ; opacite += v_opacite; rond.setAttribute('r',rayon) ; rond.style.fillOpacity = opacite ; } // fin fonction animate

Commentaire

Si vous savez modifier le DOM HTML via JavaScript vous ne serez pas surpris par le code du script.
Ici il faut modifier la valeur de la propriété opacity) et celle de l' attribut R pour l'élément SVG de type circle.

Il est difficile dans le cadre d'un script de récupérer une des valeurs de l'attribut viewBox de la balise SVG. Donc je me contente d'écrire l'instruction : var X = 400 (largeur définie dans le viewBox). Donc si vous décidez de modifier les valeurs de l'attribut viewBox il faudra corriger cette instruction du script.

Continuons l'examen du script !

rond est une variable objet qui référence le premier élément de type "circle" puisque j'utiliser querySelector().
var rayon = rond.getAttribute('r') : cette instruction permet de récupérer la valeur de l'attribut r de l'élément "rond".
Mais attention la valeur primitive de la variable rayon est la chaine "10" (et non pas l'entier 10). Et comme en JavaScript "10" + 2 donne 102 (Il y a en effet concaténation puisque l'un des termes est une chaine). Il faut donc avant toute tentative d'incrémentation de la variable rayon convertir cette dernière en un entier avec la fonction parseInt.

var opacite =rond.style.fillOpacity : la variable opacité récupère la valeur de la propriété de style fill-opacity. Mais dans un script il faut écrire fillOpacity (syntaxe JavaScript).
La variable opacite récupère une chaine. Il faut donc la convertir sous forme d'un décimal avec la fonction parseFloat.

C'est la fonction JS animate qui modifie le rayon du cercle et son opacité.
Cette fonction est appelée tous les 100 millisecondes donc 10 fois par seconde grâce à setInterval.

Étudions maintenant de plus près la fonction animate !
Pour changer la valeur d'un attribut il faut utiliser la syntaxe : élément.setAttribute("attribut",nouvelle valeur).
Pour changer la valeur d'une propriété de style il faut utiliser la syntaxe : élément.style.propriété = nouvelle valeur.
La variable v_rayon est tantôt égale à 2 et tantôt égale à -2. Donc l'instruction rayon += v_rayon incrémente ou décrémente la variable rayon.
La valeur de rayon est au maximum de X/2 et au minimum de 10.
La variable v_opacite est tantôt égale à 0.01 et tantôt égale à -0.01. Donc l'instruction opacite += v_opacite incrémente ou décrémente la variable opacite.

Avec jQuery

Rien n'interdit d'animer des éléments SVG en JS-jQuery.
Reprenons le même thème cette fois un script écrit en jQuery.

Le code HTML et SVG

... <script src ="jquery.js"></script> ... </head><body> ... <svg width="50%" height="auto" viewBox ="0 0 400 400" style = 'background : yellow; ' > <circle cx="200" cy="200" r="10" style =" fill : red ; fill-opacity : 0.1;" /> </svg>

Il faut bien sûr dans la partie HEAD charger la librairie jQuery avec un script. J'ai bien sûr supposé que le fichier .js est dans le même dossier que la page.

Le code SVG est strictement identique à la version précédente.
Notez bien que le rayon est passé en attribut et l'opacité est passée en propriété CSS !

Le script

var rond2 = $('circle:last') ; var X = 400 ; var rayon2 = rond2.attr('r'); var opacite2 =rond2.css('fillOpacity') ; rayon2 = parseInt(rayon2) ; opacite2 =parseFloat(opacite2); var v_rayon = 2; var v_opacite = 0.01 ; setInterval(animate2,100) ; function animate2() { if (rayon2 == X/2) { v_rayon = -2 ;v_opacite = -0.01; } if (rayon2 == 10) { v_rayon = 2 ; v_opacite = 0.01; } rayon2 += v_rayon ; opacite2 += v_opacite; rond2.attr('r',rayon2) ; rond2.css('fillOpacity', opacite2); } // fin fonction animate

On doit référencer le dernier élément "circle" de la page.
Pour récupérer / modifier la valeur d'un attribut il faut utiliser la méthode attr().
Pour récupérer /modifier la valeur d'une propriété CSS il faut utiliser la méthode css().

On ne peut pas dire que le script soit vraiment plus succinct qu'en JS de base mais la syntaxe est beaucoup plus simple : mêmes méthodes pour récupérer OU modifier les attributs et propriétés ; ce qui n'est pas le cas en JS de base (des méthodes SET et des méthodes GET). Autre différence notable avec JS de base : le ciblage des noeuds du DOM.
Retour menu