jeudi 5 janvier 2012

Canvas 2D HTML5 en 10 étapes faciles

Dans ce billet, je vous présenterai les notions élémentaires nécessaires pour débuter avec le canvas HTML5. À la fin de ce tutoriel, vous devriez être en mesure de réaliser des oeuvres graphiques complètement inutiles (la seule limite est votre imagination). Si ce n'est pas le cas, vous trouverez un exemple de mon cru à la fin accompagné de son code source.

Vous aurez besoin :
  • un fureteur qui supporte le HTML5 (si vous insistez pour utiliser une version antérieure à Internet Explorer 9, je vous monterai plus loin comment le rendre compatible)
  • du JavaScript
  • jQuery (optionnel mais comme j'en utilise dans mes exemples...)

1. Créez un document HTML5 puis incluez-y une balise canvas

<canvas id="myCanvas" width="800" height="600">
Le canvas HTML5 ne fonctionne pas avec ton browser déficient :-(
</canvas>
2. Référence au contexte

Comme on dessinera en deux dimensions, on invoquera le contexte 2D du canvas (tout en s'assurant que le fureteur le supporte).
var canvas = $('#myCanvas');

if(canvas && canvas.get(0).getContext){
var context = canvas.get(0).getContext('2d');

// ...
)
3. Tracer une ligne

On commence par une ligne droite horizontale en déterminant les points de départ et d'arrivée. On ajustera les coordonnées x et y du point d'arrivée si on veut obtenir une ligne verticale ou diagonale (le point 0, 0 représente le coin supérieur gauche de la zone du canvas).
context.beginPath();
context.moveTo(50, 25); // x, y
context.lineTo(250, 25); // x, y
context.closePath()
context.stroke();
4. Dessiner un carré

On utilisera fillRect, parce qu'après tout, un carré est un rectangle avec des côtés égaux.
context.fillRect(50, 75, 50, 50); // x, y, width, height
5. Dessiner un rectangle
context.fillRect(50, 175, 100, 50); // x, y, width, height
6. Définir seulement le contour

Attention, le contour est extérieur à la forme donc le rectangle semble légèrement plus grand.
context.strokeRect(200, 175, 100, 50);
7. Dessiner un cercle parfaitement rond

Ce qui peut être mêlant ici, c'est que la coordonnée x, y représente le centre du cercle. Il faut l'aligner en conséquence.
context.beginPath();
// centre(x, y), rayon, angle de départ, angle final, anticlockwise context.arc(100, 325, 50, 0, Math.PI*2, false);
context.closePath()
context.fill();
8. Changer de couleur

Vous n'aimez pas la couleur noire par défaut ? Modifiez la propriété du contexte avant de dessiner. La couleur sera retenue pour tous les futurs traits.
context.fillStyle = '#0000FF';
context.fillRect(50, 400, 100, 50); // x, y, width, height
9. Ajouter du texte

Parce qu'on est fier, on signe son oeuvre.
context.font = "18px Arial";
context.fillStyle = '#7E2217';
context.fillText("http://code18.blogspot.com", 200, 450);
Tadaaaaam ! Voici le résulat :


Euh, j'avais pas dit 10 étapes faciles ? Voici donc la dixième.

10. Donner un sursis au condamné

En cas d'incompatibilité avec une version d'Internet Explorer périmée, on peut inclure en entête le script magique ExplorerCanvas de Google Code et souhaiter que tout se passe pour le mieux (les deux exemples de ce billet sont supportés à 100%).
<!--[if IE]><script src="ExplorerCanvas/excanvas.js"></script><![endif]-->
Allez, on peut faire mieux. Comme par exemple reproduire les barres de calibrage d'un écran de télévision (couleurs obtenues à partir de cette image).
// merci de ne pas me faire remarquer que
// je n'ai pas pris soin d'optimiser le code :-)

$(document).ready(
function(){
var canvas = $('#myCanvas');

if(canvas && canvas.get(0).getContext){

var context = canvas.get(0).getContext('2d');

var top = ['F4F4F6', 'FFF461', '7EF3F6', '00FD41', 'FF74FF', 'FF204E', '5260FD'];
var middle = ['8696FF', '3C281D', 'FF8CFF', '161616', '77F0F5', '131011', 'EDECF1'];
var bottom = ['5F8CDD', 'FDFDFD', '7237D5', '101214', '0D0E11'];

var screenWidth = 800;
var screenHeight = 600;

var h = 0;
var colWidth = 0;
var colWidthTop = parseInt(screenWidth/top.length);
var colWidthMiddle = parseInt(screenWidth/middle.length);
var colWidthBottom = parseInt(screenWidth/bottom.length);

offset = 0;
colWidth = colWidthTop;
$(top).each(
function(){
context.fillStyle = '#' + this;
context.fillRect(offset, 0, colWidth, screenHeight); // x, y, width, height
offset += colWidth;
}
);

offset = 0;
colWidth = colWidthMiddle;
h = screenHeight*0.25;
$(middle).each(
function(){
context.fillStyle = '#' + this;
context.fillRect(offset, screenHeight - h, colWidth, screenHeight - h); // x, y, width, height
offset += colWidth;
}
);

offset = 0;
colWidth = colWidthBottom;
h = screenHeight*0.20;
$(bottom).each(
function(){
context.fillStyle = '#' + this;
context.fillRect(offset, screenHeight - h, colWidth, screenHeight - h); // x, y, width, height
offset += colWidth;
}
);
}
}
);
Wow, c'est dont ben beau! Je pense que je devrais en faire un agrandissement pour l'encadrer dans mon salon.



Je vous l'avais dit, ça ne sert pas à grand chose mais c'est joli.

3 commentaires:

  1. La prochaine étape est de faire l'animation de la "neige" télévisée avec Canvas!

    RépondreEffacer
  2. Pourquoi intégrer tout le framework jQuery pour sélectionner un élément via son id et utiliser du js pur par la suite ?

    document.getElementById('myCanvas') suffirait ;)

    Ah si, il y a aussi un $().each() qui pourrait être remplace par un for(x in y)...

    Je suis fan de jQuery mais pour 2 malheureuses fonctions, l'insérer en entier me semble un peu... abusif, non ?

    RépondreEffacer
  3. Intégrer jQuery n'est jamais abusif quand on regarde plus loin qu'un simple exemple :-)

    RépondreEffacer