weeXord.org HTML5 et sa sauce JavaScript servi sur son coulis de Jeux Vidéos

Initiation aux Canvas

07.08.2010 · Posté dans Tutoriels

Je parle des canvas, c’est bien mignon mais encore faudrait-il savoir les utiliser ! Pour cela j’ai décidé de faire un petit tutoriel -plus ou moins complet- afin de faire un petit tour d’horizon de l’API de dessin.

Qu’est-ce qu’un Canvas ?

C’est un composant issu du HTML5, qui n’est pas encore complet mais qui nous permet dors et déjà pas mal de choses. On peut apparenter cet élément à une zone de dessin, qui peut être manipulée à l’aide d’une API spécifique en JavaScript.

Comment ça marche ?

On a tout d’abord la partie HTML qui va définir l’élément Canvas d’un point de vue de la page. Cette partie aura pour but de positionner le Canvas dans notre page, mais aussi de définir sa taille.

1
2
3
<canvas id="premierCanvas" class="mesCanvas" width="300" height="300">
	Votre navigateur ne supporte pas les Canvas :(
</canvas>

Rien de plus complexe que ça, c’est en réalité aussi simple que de créer une IFRAME
Donc c’est une simple balise type, où l’on peut spécifier ses dimensions de 3 façons différentes : directement dans la balise, via son style CSS, ou bien via le DOM.
Sachez que dans l’exemple ci-dessus la ligne 2 est optionnelle, et son texte ne sera affiché que si le navigateur ne prends pas en charge les Canvas, sauf dans le cas de Safari qui ne prends pas en charge la balise de fermeture et qui affichera à coup sur votre texte alternatif.

Comment ça se manipule ?

Donc à l’heure actuelle si vous ouvrez votre page dans un VRAI navigateur vous ne verrez absolument rien, car pour pouvoir afficher votre Canvas il faut initialiser le contexte de dessin.

Sachez qu’il existe 2 types de contextes : 2D et 3D mais pour ma part je n’ai jamais utilisé le 3D qui est extrêmement limité et n’est supporté par quasiment aucun navigateur ! Mais on peut imaginer dans le futur voir la manipulation de Canvas en 3D se généraliser, mais je n’y crois pas vraiment.

1
2
var element = document.getElementById('premierCanvas');
var canvas = element.getContext('2d');

Donc simplement on récupère notre élément via le DOM, puis on appelle la méthode getContext() qui va nous permettre d’utiliser les fonctions de dessin.

Maintenant je vais vous montrer comment empêcher de se bouffer des erreurs JavaScript parce qu’on tente d’exécuter notre code sur un navigateur qui ne supporte par les Canvas.

1
2
3
4
var element = document.getElementById('premierCanvas');
if (element.getContext) {
	var canvas = element.getContext('2d');
}

Bien sur n’oubliez pas de laisser tout le code relatif au Canvas dans le if, sinon ça ne sert strictement à rien :(

Comment on dessine dedans ?

Pour commencer on va aborder le dessin de formes simples. Donc il faut savoir que tout se mesure en pixels et que par défault l’origine du Canvas se situe en haut à gauche donc toutes nos coordonnées se baseront sur ce point.

Les rectangles

  fillRect(x,y,width,height)
    Pour dessiner un rectangle plein
  strokeRect(x,y,width,height)
    Pour dessiner un rectangle vide
  clearRect(x,y,width,height)
    Pour effacer la zone spécifiée et la rendre transparente
1
2
3
4
5
6
7
8
9
function draw() {
	var element = document.getElementById('premierCanvas');
	if (element.getContext) {
		var canvas = element.getContext('2d');
		canvas.fillRect(10,10,280,280);
		canvas.clearRect(20,20,260,260);
		canvas.strokeRect(140,140,20,20);
	}
}

L’exemple ci-dessus va dessiner un grand rectangle, dont une grande partie sera ensuite effacée et rendue transparente, dans laquelle on dessinera un petit rectangle vide. L’exécution de la fonction draw() devrait donc vous donner ça :

Les chemins

Voilà la seule autre possibilité dessin, mais pas des moindres puisqu’elle permet de dessiner absolument toutes les formes possibles !
Cette méthode se décompose en 4 étapes bien distinctes :

  • beginPath() – On commence la création d’un chemin, donc il faut voir ça comme une liste d’instructions qui sera (ré)initialisée à chaque appel de cette méthode
  • On appelle les méthodes de dessin de chemins (on va voir ça bientôt)
  • closePath() – On peut ensuite appeler ou non cette méthode afin de fermer le chemin en partant du point courant jusqu’au point de départ.
    Notez que si la forme est fermée, ou qu’il n’y a qu’un point cette méthode est inutile
  • Pour finir on appellera la méthode stroke() si on veut dessiner une forme vide, ou fill() pour une forme remplie

Je vais maintenant vous présenter les méthodes de base des chemins

  • moveTo(x,y)
    Cette méthode permet de dessiner un point de départ, mais sachez que ce point est réinitialisé à chaque appel de beginPath() aux coordonnées (0,0)
  • lineTo(x,y)
    Cette méthode permet de dessiner une ligne, partant du point de départ jusqu’au point passé en paramètre (x,y)
  • arc(x,y,rayon,angleDepart,angleFin,sensInverse)
    Cette méthode permet de dessiner des arc, ou cercles avec un point central aux coordonnées (x,y), avec un angle de départ et de fin (en radians).
    Le paramètre sensInverse permet de définir le sens de rotation, lorsqu’il est à false il dessine l’arc dans le sens des aiguilles d’une montre

Il existe d’autres fonctions qui permettent de dessiner des courbes, mais je n’ai pas jugé bon de les aborder car je souhaites seulement aborder les « bases ».
Je vous ait donc préparé un petit exemple vous montrant ce que l’ont peut rapidement réaliser avec les méthodes ci-dessus.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
function draw() {
	var element = document.getElementById('premierCanvas');
	if (element.getContext) {
		var canvas = element.getContext('2d');
 
		// Rectangle vide
		canvas.beginPath();
		canvas.moveTo(5,5);
		canvas.lineTo(291,5);
		canvas.lineTo(5,293);
		canvas.closePath();
		canvas.stroke();
 
		// Rectangle plein
		canvas.beginPath();
		canvas.moveTo(7,295);
		canvas.lineTo(295,5);
		canvas.lineTo(295,295);
		canvas.fill();
 
		var angleFin = Math.PI * 2;
			// Cercle vide
			canvas.beginPath();
			canvas.arc(55,75,20,0,angleFin,true);
			canvas.stroke();
 
			// Cercle plein
			canvas.beginPath();
			canvas.arc(85,75,20,0,angleFin,true);
			canvas.fill();
	}
}

On dessine tout simplement 2 rectangles inversés ainsi que 2 cercles, un vide et un plein afin que vous voyez les deux méthodes. Et normalement l’exécution de la fonction draw() devrait vous dessiner quelque chose comme ça :

Les images

Voici une partie extrêmement importante et vraiment facile à aborder. En effet si vous commencez à jouer avec les Canvas, vous aurez très certainement besoin d’intégrer des images, utiliser un système de sprites et je vais de ce pas vous expliquer comment ça se passe.
Pour pouvoir utiliser votre image il faut bien évidemment qu’elle soit intégrée à la page, donc plusieurs cas de figure d’offrent à vous :

  • Soit votre image est incluse dans votre code HTML et dans ce cas il suffira d’utiliser document.getElementById ou document.getElementsByTagName pour pouvoir accéder à votre image
  • Sinon vous pouvez aussi inclure votre image à partir d’un fichier
    1
    2
    3
    4
    
    // On crée notre objet
    var pic = new Image();
    // Puis on indique le chemin notre l'image
    pic.src = 'mon-image.png';
  • La dernière méthode est d’utiliser les Data URI en gros ça corresponds simplement au code de votre image encodé en base64. De ce fait l’image peut être inclue très facilement et sans avoir à appeler d’autre(s) fichier(s) sur le serveur
    1
    2
    3
    4
    
    var pic = 'data:image/png;base64,
    iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
    //+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
    g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC';

Maintenant que vous savez comment accéder à votre image, il ne reste plus qu’à la dessiner dans notre joli canvas. Pour ce faire nous allons utiliser la fonction drawImage().

  • drawImage(image,x,y)
    dessinera l’image à la position souhaitée (dans les exemples ci-dessus image = pic)
  • drawImage(image,x,y,w,h)
    vous permettra de redimensionner votre image
  • drawImage(image,x1,y1,w1,h1,x2,y2,w2,h2)
    vous permet de dessiner seulement une partie de l’image source, et voici un petit schéma illustrant les paramètres de la fonction

Texte

Nous allons maintenant voir très brièvement comment écrire un texte personnalisé dans un Canvas, et pour cela un exemple sera bien plus parlant qu’un long discours, donc je vous laisse admirer…

1
2
3
4
// On défini la taille du texte, et la police d'écriture
canvas.font = "12px Verdana";
// Puis on va écrire notre texte à la position souhaitée
canvas.fillText("Hello world !",10,10);

Couleur et transparence

Maintenant nous allons voir comment mettre de la couleur à nos textes/dessins, et pour cela nous auront besoin de 2 propriétés qui peuvent utiliser différents format de couleur :

  • fillStyle()
    1
    2
    3
    4
    5
    6
    7
    8
    
    // Nom de couleur (comme en CSS)
    canvas.fillStyle = "rouge";
    // Format hexadécimal
    canvas.fillStyle = "#FF0000";
    // Format RGB
    canvas.fillStyle = "rgb(255,0,0)";
    // Format RGB avec transparence de 0.0 (invisible) à 1.0 (opaque)
    canvas.fillStyle = "rbga(255,0,0,1)";
  • strokeStyle()
    Fonctionne de la même manière que fillStyle()

Maintenant concernant la transparence, la propriété globalAlpha nous permettra de modifier la valeur de transparence de dessins effectués dans le canvas. Pour vous illustrer les propos de ce chapitre, je vous propose sans plus attendre un exemple :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
function draw() {
	var element = document.getElementById('premierCanvas');
	if (element.getContext) {
		var canvas = element.getContext('2d');
 
		// On initialise le tableau de couleur,
		// le compteur de tour,
		// et les positions de départ
		var color = [
			'orange',
			'#ff017d',
			'rgb(0,255,0)',
			'rgba(0,0,255,0.1)'
		],
		c = 0,
		x = 25,
		y = 25;
 
		for (var i=0;i<8;i++) {
			// On trace le chemin du cercle
			canvas.beginPath();
			canvas.arc(x,y,20,0,Math.PI*2,true);
 
			// Cette condition sera vraie une foi sur 2
			if (i%2 == 0) {
				// On dessinera juste le contour
				canvas.strokeStyle = color[c];
				canvas.stroke();
				x += 83;
			}
			else {
				// On aura un dessin rempli
				canvas.fillStyle = color[c];
				canvas.fill();
				x += 83;
				c++;
 
				// Si on est à la moitié de la boucle,
				// on passe à la deuxième ligne
				if ((c == 2) && (y == 25)) {
					y = 70;
					x = 25;
				}
			}
		}		
	}
}

Ce qui devrait donner quelque chose du genre :

Conclusion

Ce tutoriel est vraiment simpliste et sert plutôt de manuel qu’autre chose, maintenant j’ai essayé de m’exprimer de façon simple, mais je ne suis pas sur de pouvoir être objectif sur ce point, donc je vous invite à me faire part de vos remarques/commentaires.

Je tiens à préciser que je n’ai pas parlé de tout ce que j’aurai voulu car en abordant seulement les bases, le tutoriel a atteint une taille assez conséquente, donc je vous propose d’aller voir la documentation du developer center de Mozilla pour plus d’informations.

Allez à vous de jouer ! :)

Répondre