SVG vs Canvas, à l'heure du choix
Quel format choisir pour intégrer des graphismes dans une page Web, ou pour réaliser une application en ligne?
Balises contre fonctions
SVG est un langage à balise dérivé de XML. Canvas est une API, donc un ensemble de fonctions JavaScript utilisant la balise <canvas> comme conteneur (SVG utilise la balise <svg>).
Par exemple, voila comment on affiche un texte vectoriel en SVG:
<svg width="320px" height="48px">
<g>
<text font-size="24" font-style="italic" x="16" y="24" style="fill:purple">
Un texte en SVG
</text>
</g>
</svg>
Et avec Canvas:
<canvas id="can" width="320" height="48">Un texte avec Canvas</canvas>
<script>
function cText()
{
var ctx = document.getElementById('can').getContext('2d');
ctx.fillStyle="rgb(255,32,32)";
ctx.font='italic normal 24px Calibri, sans-serif';
ctx.fillText("Un texte avec Canvas", 16, 24);
}
window.onload=cText;
</script>
Vectoriel et bitmap?
Même s'il est certain que SVG est vectoriel, donc que l'utilisateur peut changer la taille de l'image, Canvas n'est pas bitmap pour autant. En fait l'API dispose de la fonction "scale" qui permet de redéfinir la taille de l'image dynamiquement.
En outre les deux supports peuvent contenir des images bitmap, donc l'opposition vectoriel contre bitmap ne vaut pas comme on le fait souvent à tort.
Interaction avec l'utilisateur
Le code SVG est fait de balises qui peuvent se combiner avec les balises HTML. Par exemple on peut placer un lien dans une image SVG ainsi:
<svg width="320px" height="48px">
<g>
<a href="#" onclick='alert("Clic")'>
<text font-size="16" x="16" y="16" style="fill:blue">
Un lien cliquable
</text>
</a>
</g>
</svg>
Vous pouvez cliquer sur le texte. En fait on peut attacher un évènement tel que onclick à n'importe quelle balise SVG: le code SVG fait partie du DOM.
Génération automatique vs contenu dynamique
Du fait que SVG soit fait de balises XML, il est possible de produire un graphisme au format SVG avec un éditeur graphique. Un dessin produit avec Inkscape peut être sauvé comme fichier SVG et intégré directement dans une page Web.
A l'inverse, les graphismes dans Canvas sont produits dynamiquement par du code JavaScript au moment du chargement de la page.
Scripting
On sait que le contenu de Canvas est réalisé par un script, mais peut-on faire de même avec SVG? Effectivement, dessinons par exemple un rectangle vert...
<svg width="320px" height="100px">
<g id="mysvg"></g>
</svg>
function rect(svgelement, x, y, w, h)
{
var rec = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rec.setAttribute("style", "fill:green");
rec.setAttribute("x", x);
rec.setAttribute("y", y);
rec.setAttribute("width", w);
rec.setAttribute("height", h);
svgelement.appendChild(rec);
}
rect(document.getElementById("mysvg"), 10, 10, 200, 80);
On voit que l'on peut donc générer un contenu dynamique avec SVG en définissant des fonctions équivalentes à celles de l'API Canvas.
Vitesse
Sur le plan de la rapidité, Canvas l'emportera toujours car le contenu SVG s'intègre au document et au DOM, même quand il est généré dynamiquement, ce qui le ralentit.
Le jeu classique Invaders porté en SVG est lent. Canvas convient mieux dans ce cas.
Conclusion
On peut souvent faire la même chose avec les deux formats, par exemple, créer un bouton en SVG ou en canvas. L'avantage de SVG est la possibilité de produire des documents visuellement avec un logiciel. Ces documents peuvent devenir interactifs en attachant des évènements tels que onClick.
On peut définir facilement une interface utilisateur graphique en SVG comme avec XUL ou XAML.
Mais Canvas est beaucoup plus rapide et convient mieux pour des animations, pour des graphismes qui changent par programmation.
Ressources
- Spécification SVG. Tous les objets et propriétés.
- Inkscape. Logiciel de dessin vectoriel open source.
- SVG dans Canvas. Afficher des images SVG dans une balise Canvas.
- Tutoriel Canvas.