Retourner à la page d'accueil de TJS

Dessiner dans le navigateur avec JavaScript et canvas

HTML5 a introduit l'objet canvas qui permet de dessiner dans le navigateur avec JavaScript. Canvas est essentiellement utilisé pour afficher des graphiques mais il est même possible de réaliser des jeux 3D.

Dans ce tutoriel, nous allons voir comment dessiner des lignes, des formes simples, les remplir et se repérer sur la zone de dessin.

L'objet HTML canvas

Le mot canvas signifie canevas. Il est donc très orienté création graphique et artistique. Il se déclare simplement par la balise canvas et se comporte à l'affichage comme un div.

Définissons un style pour tous les canvas de notre tuto :

canvas {
  border:2px solid #999;
  background-color:#fff;
}

Créons notre premier canvas :
<canvas id="canvas1" width="700" height="200">Votre navigateur est trop vieux</canvas>

Le repérage dans le canvas se fait par les coordonnées cartésiennes (x, y) avec l'origine (0, 0) en haut à gauche

Il faut aussi maîtriser la gestion des angles et la trigonométrie pour les tracés de cercle.

Tracer des lignes

Notre premier dessin avec un peu de JavaScript. Vous noterez que le principe est basique et très proche du langage LOGO (et de sa tortue) :

var monCanvas=document.getElementById("canvas1");
var ctx = monCanvas.getContext("2d");
ctx.lineWidth="8";
ctx.strokeStyle="#316AC5";

ctx.beginPath(); /* Dessiner le T */
ctx.moveTo(50, 50);
ctx.lineTo(150, 50);
ctx.lineTo(90, 45);
ctx.lineTo(100, 150);
ctx.stroke();

ctx.beginPath(); /* Dessiner le J */
ctx.moveTo(200, 50);
ctx.lineTo(200, 150);
ctx.lineTo(180, 140);
ctx.stroke();

ctx.beginPath(); /* Dessiner le S */
ctx.moveTo(300, 50);
ctx.lineTo(250, 80);
ctx.lineTo(300, 120);
ctx.lineTo(250, 150);
ctx.stroke();

TJS s'affiche à l'exécution !

Emulation de la console

Quelques explications simples pour comprendre les grands principes de dessins sur canvas s'imposent :
Classiquement, on cherche le canvas avec getElementById() qui renseigne la variable monCanvas.
La variable ctx est alimentée par l'appel à getContext() méthode propre à l'objet HTMLCanvasElement.
Ensuite, toutes les actions de dessin dans le canvas passent par des appels de méthodes et des affectations de propriétés sur ce contexte.

La propriété lineWidth contient la largeur du crayon.

La propriété strokeStyle contient la couleur du crayon.

La méthode beginPath() initialise un tracé.

La méthode moveTo(x, y) déplace le pointeur à la position (x, y).

La méthode lineTo(x, y) trace une ligne depuis la position du curseur jusqu'à la position (x, y).

La méthode stroke() affiche le dessin non rempli initialisé dans le canvas. Tant que stroke() n'est pas appelé, le dessin d'un chemin n'est pas affiché.

Tracer des formes

La gestion des formes est assez poussée :

<canvas id="canvasShape" width="700" height="200">Votre navigateur est trop vieux</canvas>

Quelques exemples de tracé de formes :

var monCanvas=document.getElementById("canvasShape");
var ctx = monCanvas.getContext("2d");

/* Un rectangle */
ctx.lineWidth="8";
ctx.strokeStyle="#316AC5";
ctx.rect(20,20,660,160)
ctx.stroke();

/* Un chemin fermé (un triangle) */
ctx.lineWidth="4";
ctx.strokeStyle="#FFA500";
ctx.beginPath(); 
ctx.moveTo(60,60);
ctx.lineTo(190,35);
ctx.lineTo(50,160);
ctx.closePath(); 
ctx.stroke();

/* Un cercle et un arc de cercle */
ctx.lineWidth="4";
ctx.strokeStyle="#31528C";
ctx.beginPath();
ctx.arc(300, 105, 65, 0, 2*Math.PI);
ctx.stroke();

ctx.beginPath();
ctx.arc(500, 105, 25, Math.PI/2, 2*Math.PI);
ctx.stroke();


Voici les formes qui s'affichent :

Emulation de la console

La méthode rect(x, y, largeur, hauteur) trace un rectange dont le coin supérieur gauche est en (x,y) avec largeur et hauteur comme dimensions.

La méthode closePath() referme un chemin ouvert avec beginPath().

La méthode arc(x, y, r, angleDepart, angleFin) crée un arc de cercle centré en position (x,y) avec un rayon r entre 2 angles exprimés en radians (donc entre 0 et 2*PI qui correspondent à 0 et 360°).

Les modes de remplissage

Nous avons déjà vu le remplissage par une couleur unie. Il est aussi possible de remplir une zone par un gradient (dégradé de couleurs) ou par une répétition d'images :

<canvas id="canvasFill" width="700" height="200">Votre navigateur est trop vieux</canvas>

Voici les 3 formes à remplir

var canvasFill=document.getElementById("canvasFill");
var ctxFill = canvasFill.getContext("2d");

/* Un rectangle de couleur unie */
ctxFill.lineWidth="8";
ctxFill.fillStyle="#316AC5";
ctxFill.fillRect(20,20,660,160)

/* Deux cercles avec des gradients de couleur */
var monGradient = ctx.createLinearGradient(215, 0, 270, 0);
monGradient.addColorStop(0, '#ffa500');
monGradient.addColorStop(1, '#ffffff');
ctxFill.fillStyle = monGradient;
ctxFill.beginPath();
ctxFill.arc(250, 105, 55, 2*Math.PI, 0);
ctxFill.fill();
console.log(monGradient);

var monGradient2 = ctx.createRadialGradient(450, 80, 50, 450, 85, 2*Math.PI);
monGradient2.addColorStop(0, '#ffa500');
monGradient2.addColorStop(1, '#ffffff');
ctxFill.fillStyle = monGradient2;
ctxFill.beginPath();
ctxFill.arc(450, 105, 55, 0, 2*Math.PI);
ctxFill.fill();
console.log(monGradient2);

/* Une forme définie par un chemin remplie par une image */
var img = new Image();
img.src = 'pattern.gif?1';
img.onload = function() {
  var pattern = ctx.createPattern(img, 'repeat');
  ctxFill.fillStyle = pattern;
  ctxFill.beginPath();
  ctxFill.moveTo(500,60);
  ctxFill.lineTo(590,35);
  ctxFill.lineTo(600,160);
  ctxFill.lineTo(490,90);
  ctxFill.fill();
}

/* Un carré sombre avec une transparence */
ctxFill.fillStyle = 'rgba(15, 15, 15, 0.3)';
ctxFill.fillRect(250, 5, 100, 100);

Voici les formes qui s'affichent et se remplissent :

Emulation de la console

La propriété fillStyle contient le style de remplissage. Cet exemple montre le cas d'une couleur unie, d'un gradient de couleur ou d'un motif issue d'une répétion d'image.

La méthode fillRect trace un rectangle rempli avec le style défini dans fillStyle.

La méthode fill() remplit un chemin avec le style prédemment défini. Elle est à mettre en relation avec stroke() qui trace les contours du chemin.

Les gradients de couleur sont des objets CanvasGradient représentant des dégradés définis précisément à partir d'une forme et de couleurs. Canvas accepte 2 types de gradients.

Le gradient linéaire créé par createLinearGradient(x1, y1, x2, y2) définit un vecteur entre les points (x1, y1) et (x2, y2). Ce vecteur est colorisé par un dégradé de couleurs ajoutées par addColorStop(numero, codeCouleur).

Le gradient circulaire créé par createRadialGradient(x1, y1, r1, x2, y2, r2) définit 2 cercles avec leur position et leur rayon.

Les gradients nécessitent un peu de tatonnement pour obtenir l'effet souhaité...

Il existe enfin une possibilité de remplir une forme avec une image répétée, dont l'effet est comparable à la propriété CSS background-url. La subtilité est qu'il faut attendre le chargement de l'image pour pouvoir créer le motif avec createPattern(). Cela oblige a détecté l'événement onload sur l'objet JavaScript Image.

Ecrire du texte

Bien sûr, le canvas permet d'afficher du texte simplement.

<canvas id="canvasText" width="700" height="200">Votre navigateur est trop vieux</canvas>

Voici un exemple pour écrire du texte :

var monCanvas=document.getElementById("canvasText");
var ctx = monCanvas.getContext("2d");
ctx.font="50px arial";
ctx.strokeText("TJS et canvas",10,50);

ctx.fillText("TJS et canvas",10,110);

ctx.fillStyle="#316AC5";
ctx.fillText("TJS et canvas",10,170);

console.log("Taille du texte : "+ctx.measureText("TJS et canvas").width+" px");
ctx.stroke();

Et voici quelques exemples de styles de texte !

Emulation de la console

font contient les propriétés de style du texte.

strokeText() affiche les contours des lettres.

fillText() affiche le texte plein.

Positionner du texte

measureText() retourne la largeur en pixel du texte occupé dans le canevas. Cette donnée permet de positionner le texte plus précisément.

Par défaut, la position du texte est le coin inférieur gauche de la boîte de texte.

La propriété textBaseline contient le type de ligne d'appui du texte. Par défaut, la valeur est alphabetic avec un texte qui s'appuie sur la ligne principale d'écriture. Voici quelques exemples d'appui :

Tranformations et rotations

Il existe un moyen de réaliser des transformations avant de faire un tracé sur le canvas avec setTransform() et rotate().

Voici un exemple pour tourner un texte verticalement. On se rend rapidement compte que le code nécessaire pour réaliser cette opération relativement simple est à la fois long et complexe. La création d'une fonction paraît vraiment utile.

<canvas id="canvasTextRotate" width="300" height="250">Votre navigateur est trop vieux</canvas>

var monCanvas=document.getElementById("canvasTextRotate");
var ctx = monCanvas.getContext("2d");
ctx.font="30px arial";
/* Texte sans transformation */
ctx.fillText("TJS et canvas",10,50);

/* Rotation d'un huitième de tour */
ctx.rotate(Math.PI/4);
ctx.fillText("TJS et canvas",10,50);

/* Affichage du texte à la verticale en position (280, 200) */
ctx.setTransform(1, 0, 0, 1, 280, 220);
ctx.rotate(3*Math.PI/2);
ctx.fillText("TJS et canvas",0,0);

Et voici quelques exemples de rotation de texte !

Emulation de la console

Par défaut la rotation se fait sur le point (0, 0) du canvas. Il faut donc utiliser les 2 derniers paramètres de setTransform() pour translater le point de rotation.

Tutoriel écrit par webmaster mis à jour le

Chercher une fonction, un objet, ...

Le 24/11/2017 13:44:17 sur php7 en 13.93 ms