Sommaire de l'article
Dernière mise à jour : avril 2021
L'élément HTML5 canvas
c'est quoi ?
L'élément canvas
est une spécificité HTML5 qui, au travers de la balise du même nom : <canvas>
, permet de créer une aire de dessin.
Couplé avec JavaScript, il est alors possible de générer des formes (plus ou moins complexes) à l'intérieur de cette aire et de les animer.
L'élément canvas
se présente sous cette forme :
<canvas width="300" height="300">
Texte alternatif pour les navigateurs ne supportant pas Canvas.
</canvas>
Le support est bon puisque même Internet Explorer (9+) permet d'utiliser cet élément.
L'élément canvas
requiert deux attributs : hauteur (height
) et largeur (width
) qui sont optionnels. Par défaut, la largeur d'un canevas est de 300px
et la hauteur est fixée à 150px
.
Vous pouvez ajouter une bordure, un remplissage, une couleur d'arrière-plan, des marges... en CSS comme avec n'importe quel autre élément HTML5. Si aucun style n'est donné, le canvas sera transparent.
De part son côté intéractif, cet élément permet de dessiner des graphiques, de réaliser des compositions d'images, des animations, ou encore des jeux. Par ailleurs, avec l'élément canvas
, il est possible d'enregistrer des images au format .png
ou .jpg
.
Toutefois, canvas
dépend de la résolution, possède de piètres capacités de rendu de texte et peut se révéler très lent sur de grandes surfaces.
Le contexte de rendu
Par défaut, le canevas est vide. Pour afficher quelque chose en son sein, il est nécessaire de pouvoir accéder au contexte de rendu. C'est le langage JavaScript qui va s'en charger.
L'élément canvas
possède une méthode nommée getContext()
, qui va retourner le contexte de rendu. Cette dernière compte plusieurs valeurs :
- -
2d
: contexte de représentation bi-dimensionnel via l'interfaceCanvasRenderingContext2D
. - -
webgl
: contexte de représentation tri-dimensionnel via l'interfaceWebGLRenderingContext
- -
webgl2
: contexte de représentation tri-dimensionnel via l'interfaceWebGL2RenderingContext
- -
bitmaprenderer
: fonctionnalité de remplacement du contenu du canevas par une ImageBitmap via l'interfaceImageBitmapRenderingContext
.
Voici un exemple de code JavaScript pour obtenir un contexte de rendu avec pour argument 2d
:
let canvas = document.getElementById('canvas'); /*on créé le canvas dans le DOM*/
let ctx = canvas.getContext('2d');
Dessiner avec canvas
Le rectangle :
L'élément canvas
ne prend en charge qu'une seule forme primitive, à savoir le rectangle :
Ci-dessous un exemple classique de rectangle (le canevas est représenté par la ligne noire) :
<canvas id="exemple1" width="200" height="200">
</canvas>
let canvas = document.getElementById("exemple1");
let context = canvas.getContext("2d");
context.fillStyle = "#7d68e8";
context.fillRect(50,50,100,100);
Pour placer ce rectangle à l'intérieur du canevas, nous avons utilisé un système de coordonnés (axe x
et axe y
). Il commence en haut à gauche et chaque unité est en pixels.
Il existe trois fonctions pour dessiner des rectangles dans l'élément canvas
:
- -
fillRect()
: permet de dessiner un rectangle rempli. - -
strokeRect()
: permet de dessiner un contour au rectangle. - -
clearRect()
: permet d'effacer le rectangle.
Nous avons vu qu'il n'est possible que de dessiner des rectangles. Ce n'est pas totalement juste. En effet, il est possible de réaliser des trajets complexes en utilisant une liste de points. Il existe plusieurs fonctions pour cela.
Les tracés
Dans un premier temps, il faut faire appel à la méthode beginPath()
qui permet de commencer à dessiner des chemins. Par ailleurs, nous aurons besoin de déclarer deux méthodes : moveTo()
et lineTo()
.
La méthode moveTo()
indique le point de départ, tandis que la méthode lineTo()
le point d'arrivée.
Dans l'exemple ci-dessous, nous traçons une ligne qui prend repère en haut à gauche pour se terminer en bas à droite. Pour les deux méthodes, il faut remplir deux chiffres qui vont indiquer leur position par rapport au bord en haut à gauche du canevas.
let ligne = document.getElementById('ligne');
let contexte = ligne.getContext('2d');
contexte.strokeStyle = '#7d68e8';
contexte.moveTo(0,0);
contexte.lineTo(400,200);
contexte.stroke();
Pour tracer cette ligne, nous avons finalement utilisé la méthode stroke()
. Si vous souhaitez contrôler l'épaisseur d'un tracé, il suffira de déclarer la propriété lineWith
et de renseigner un chiffre.
Exemple avec plusieurs tracés :
let ligne1 = document.getElementById('ligne1');
let contexte1 = ligne1.getContext('2d');
contexte1.strokeStyle = '#7d68e8';
contexte1.lineWidth = '3';
contexte1.moveTo(20,20);
contexte1.lineTo(380,180);
contexte1.lineTo(20,180);
contexte1.lineTo(20,20);
contexte1.stroke();
Vous avez sans doute remarquer que nous n'avons pas utilisé la méthode beginPath()
puisqu'on applique les mêmes valeurs à tous les traits. Il faudra cependant utiliser cette méthode si vous souhaitez attribuer différentes valeurs à chaque trait.
let ligne2 = document.getElementById('ligne2');
let contexte2 = ligne2.getContext('2d');
contexte2.lineWidth = '3';
contexte2.strokeStyle = '#3ee6cc';
contexte2.moveTo(20,20);
contexte2.lineTo(380,180);
contexte2.stroke();
contexte2.beginPath();
contexte2.strokeStyle = '#555';
contexte2.moveTo(20,180);
contexte2.lineTo(380,180);
contexte2.stroke();
contexte2.beginPath();
contexte2.strokeStyle = '#7d68e8';
contexte2.moveTo(20,180);
contexte2.lineTo(20,20);
contexte2.stroke();
Arcs de cercle et cercles
Pour créer un arc de cercle ou un cercle, nous allons utiliser la méthode arc()
. De plus, nous allons déclarer la propriété Math.Pi
qui va servir à convertir les angles dans la méthode arc()
en radians (et non en degrés).
Pour créer un cercle complet, on multiplie Math.Pi
par deux (2*Math.PI
).
let cercle = document.getElementById('arc');
let contexte3 = cercle.getContext('2d');
contexte3.lineWidth = '5';
contexte3.strokeStyle = '#3ee6cc';
contexte3.arc(100,100,50,0,Math.PI);
contexte3.stroke();
contexte3.beginPath();
contexte3.fillStyle = '#7d68e8';
contexte3.arc(240,100,50,Math.PI,2*Math.PI);
contexte3.fill();
contexte3.beginPath();
contexte3.strokeStyle = '#3ee6cc';
contexte3.arc(360,100,50,0,2*Math.PI);
contexte3.stroke();
contexte3.beginPath();
contexte3.fillStyle = '#7d68e8';
contexte3.arc(500,100,50,0,2*Math.PI);
contexte3.fill();
Texte
Dessiner du texte dans l'élément canvas
n'est pas très compliqué. On utilisera la propriété font
ainsi que les méthodes strokeText()
ou fillText()
selon que l'on souhaite remplir ou non notre texte.
let texte = document.getElementById('texte');
let contexte4 = texte.getContext('2d');
contexte4.font = "bold 2rem Arial, serif";
contexte4.fillStyle = '#7d68e8';
contexte4.fillText('Du texte dans un canevas',5, 100);
Les dégradés
Tout comme en CSS ou SVG, il est possible de créer des dégradés linéaires ou radiaux dans l'élément canvas
.
Pour créer un dégradé linéaire, nous allons utiliser la méthode createLinearGradient()
et la méthode createRadialGradient()
pour un dégradé radial.
let degrade = document.getElementById('degrade');
let contexte5 = degrade.getContext('2d');
let lineaire = contexte.createLinearGradient(0,0,200,200);
lineaire.addColorStop(0,'#3ee6cc');
lineaire.addColorStop(1, '#7d68e8');
contexte5.fillStyle = lineaire;
contexte5.fillRect(0,0,200,200);
let degrade1 = document.getElementById('degrade1');
let contexte6 = degrade1.getContext('2d');
let radial = contexte.createRadialGradient(100, 100, 50, 100, 100, 100);
radial.addColorStop(0,'#3ee6cc');
radial.addColorStop(1, '#7d68e8');
contexte6.fillStyle = radial;
contexte6.fillRect(0, 0, 200, 200);
Les images et motifs
C'est la méthode drawImage()
qui va permettre d'insérer une image dans l'élément canvas
.
Pour cela, deux choix s'offrent à vous. Le premier consite à déclarer dans le corps HTML l'élément img
contenant l'image que vous souhaitez voir apparaître dans le canevas. Le second choix consite à utiliser JavaScript pour afficher l'image.
Dans les deux cas, il nous faudra déclarer l'évènement onload
dans le script afin d'attendre le chargement complet de l'image.
<img style=display:none id=image src ="image.jpg" alt>
On prendra soin de rendre l'image invisible dans le document HTML avec la propriété CSS display
et la valeur none
. Sinon vous aurez deux fois la même image, une dans le corps HTML, l'autre dans le canevas.
let imageCanvas = document.getElementById('image-canvas');
let context7 = imageCanvas.getContext('2d');
var image = document.getElementById('image');
image.addEventListener('load', charge);
function charge(){
context7.drawImage(image,90,10,420,279);
}
La méthode en pur JavaScript consiste à déclarer une nouvelle instance de l'objet Image()
et de fournir la source de l'image.
let imageCanvas1 = document.getElementById('image-canvas1');
let context8 = imageCanvas1.getContext('2d');
let image1 = new Image();
image1.src ="image.jpg" ;
image1.addEventListener('load', charge);
function charge(){
context8.drawImage(image,90,10,420,279);
}
Pour créer un motif, on va utiliser la méthode createPattern()
:
let motifCanvas = document.getElementById('motif-canvas');
let contexte11 = motifCanvas.getContext('2d');
let motif = new Image();
motif.src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='hexagons' fill='%237a5fff' fill-opacity='0.4' fill-rule='nonzero'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E";
motif.onload = function() {
let pattern = contexte11.createPattern(motif, 'repeat');
contexte11.fillStyle = pattern;
contexte11.fillRect(0, 0, 600, 200);
};
Les transformations
Il est possible de définir une transformation à un dessin dans l'élément canvas
. Pour cela, vous avez deux méthodes : rotate()
pour la rotation et translate()
pour le déplacement
Nous avons vu plus haut la propriété Math.Pi
qui convertit les degrés en radians. Nous en aurons besoins pour calculer la rotation.
let rotation = document.getElementById('rotation');
let context9 = rotation.getContext('2d');
context9.rotate(Math.PI/4); /* = 45° */
context9.fillStyle = "#7d68e8";
context9.fillRect(90,-50,100,100);
let deplacement = document.getElementById('deplacement');
let contexte10 = deplacement.getContext('2d');
contexte10.fillStyle = '#7d68e8';
contexte10.fillRect(0,0,100,100);
contexte10.translate(0,100);
contexte10.fillStyle = 'rgba(1, 255, 137, 0.73)';
contexte10.fillRect(300,0,100,100);
Exemple avancé
Faites un double-clic pour recommencer et un clic droit pour enregistrer votre oeuvre d'art.
Aller plus loin avec Canvas :
Les bases de l'élément canvas
(EN) .
Introduction à canvas
(EN) .
Récapitulatif des fonctionnalités de canvas
.
Tutoriel jeu vidéo (EN) avec canvas
.
Quelques démonstrations avec l'élément Canvas :
Quelques bibliothèques :
Vous rencontrez un problème avec cet article ?
Vous avez remarqué une faute, un oubli, un lien mort ? Vous ne comprenez pas un point précis de l'article ? Vous pouvez me contacter par mail (contact@guyom-design.com) et je vous aiderai si je le peux. Je ne réponds qu'aux messages respectueux.