I. Barista part II▲
I-A. Charger une texture▲
Voir le code : GitHub
Cliquez pour lire la vidéo
En JavaScript (et donc en Typescript), il est très simple de charger une image, aussi appelée texture dans le domaine du jeu vidéo, d’ailleurs nous utiliserons ce terme dorénavant. Il y a plusieurs façons de faire, pour le besoin de ce chapitre, nous utiliserons la plus simple qui est d’inclure les images directement dans la structure HTML. Il nous suffira alors de démarrer le script au chargement complet de la page et pour ça, nous utiliserons l’événement natif de l’objet « window » à savoir « load ».
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.
function
init
(
){
const
canvas =
getCanvas
(
);
const
context =
getContext
(
);
// on détermine les dimensions du canvas
canvas.
width =
640
;
canvas.
height =
480
;
// on sauvegarde le contexte
context.save
(
);
// on va incorporer nos opérations de dessin ici
// on restaure le contexte
context.restore
(
);
}
function
getContext
(
){
return
getCanvas
(
).getContext
(
"2d"
);
}
function
getCanvas
(
){
return
document.querySelector
(
"canvas"
);
}
window.addEventListener
(
"load"
,
init);
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<!
DOCTYPE html
>
<html lang
=
"en"
>
<head>
<meta charset
=
"UTF-8"
>
<meta name
=
"viewport"
content
=
"width=device-width, initial-scale=1.0"
>
<meta http-equiv
=
"X-UA-Compatible"
content
=
"ie=edge"
>
<title>Barista</title>
<script src
=
"./dist/main.js"
></script>
</head>
<body>
<canvas id
=
"barista"
></canvas>
<img src
=
"kirby.png"
/>
</body>
</html>
I-B. Dessiner une texture▲
Pour dessiner une texture, l’API de dessin de canvas embarque une méthode dont voici la première signature possible :
context.drawImage
(
image,
dx,
dy)
- le paramètre image représente la texture que l’on souhaite dessiner ;
- les paramètres dx et dy représentent les coordonnées auxquelles on souhaite dessiner l’image.
Cette méthode vous permettra de dessiner directement la texture sur le canvas, sans aucune transformation.
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.
function
init
(
){
const
canvas =
getCanvas
(
);
const
context =
getContext
(
);
// on détermine les dimensions du canvas
canvas.
width =
640
;
canvas.
height =
480
;
// on sauvegarde le contexte
context.save
(
);
// on récupère l'élément html de type image qui nous sert de texture (ici kirby)
const
kirby =
document.querySelector
(
"img"
);
// puis on le dessine à l'aide de la méthode drawImage de l'objet de type context
context.drawImage
(
kirby,
0
,
0
);
// on restaure le contexte
context.restore
(
);
}
function
getContext
(
){
return
getCanvas
(
).getContext
(
"2d"
);
}
function
getCanvas
(
){
return
document.querySelector
(
"canvas"
);
}
window.addEventListener
(
"load"
,
init);
I-C. Méthodes de dessin avancées▲
Jusqu’ici, nous avons vu la méthode classique pour dessiner une texture, nous allons à présent faire un tour du côté des méthodes de dessin avancées en commençant par dessiner une texture à la taille que l’on souhaite obtenir. Pour ce faire, nous allons voir la deuxième manière d'appeler la méthode context.drawImage() :
context.drawImage
(
texture,
dx,
dy,
dw,
dh)
- le paramètre texture représente la texture que l’on souhaite dessiner ;
- les paramètres dx, dy, dw et dh représentent un rectangle de largeur dw et de hauteur dh dont le coin en haut à gauche est situé en dx et dy. Ce rectangle représente les nouvelles dimensions de la texture au sein du canvas.
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
init
(
){
const
canvas =
getCanvas
(
);
const
context =
getContext
(
);
// on détermine les dimensions du canvas
canvas.
width =
640
;
canvas.
height =
480
;
// on sauvegarde le contexte
context.save
(
);
// on récupère l'élément html de type image qui nous sert de texture (ici kirby)
const
kirby =
document.querySelector
(
"img"
);
// puis on réalise le dessin à l'aide de la méthode drawImage de l'objet de type context
// on dessine cette texture à partir des coordonnées x = 10 et y = 35
// la nouvelle largeur de la texture est de 200px et la nouvelle hauteur vaut 20px
context.drawImage
(
kirby,
10
,
35
,
200
,
20
);
// on restaure le contexte
context.restore
(
);
}
function
getContext
(
){
return
getCanvas
(
).getContext
(
"2d"
);
}
function
getCanvas
(
){
return
document.querySelector
(
"canvas"
);
}
window.addEventListener
(
"load"
,
init);
Ici, on dessine notre texture aux coordonnées x = 10px, y = 35px et on applique une transformation à cette texture afin qu’elle soit dessinée avec 200px de largeur et 20px de hauteur. Nous allons maintenant voir comment dessiner une portion de notre texture et pour cela, nous allons étudier la troisième et dernière signature possible de la méthode context.drawImage() :
context.drawImage
(
texture,
sx,
sy,
sw,
sh,
dx,
dy,
dw,
dh)
- le paramètre texture représente la texture que l’on souhaite dessiner ;
-
les paramètres sx, sy, sw et sh représentent un rectangle dont les dimensions correspondent à une portion de la texture originelle ;
- les paramètres dx, dy, dw et dh représentent les nouvelles dimensions de la portion de texture originelle au sein du canvas.
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
init
(
){
const
canvas =
getCanvas
(
);
const
context =
getContext
(
);
// on détermine les dimensions du canvas
canvas.
width =
640
;
canvas.
height =
480
;
// on sauvegarde le contexte
context.save
(
);
// on récupère l'élément html de type image qui nous sert de texture (ici kirby)
const
kirby =
document.querySelector
(
"img"
);
// puis on le dessine à l'aide de la méthode drawImage de l'objet de type context
// on dessine la portion de l'image originelle comprise entre les coordonnées x = 0, y = 0, x = 100, y = 100
// on dessine cette portion de façon un peu déformée
context.drawImage
(
kirby,
0
,
0
,
100
,
100
,
30
,
30
,
250
,
250
);
// on restaure le contexte
context.restore
(
);
}
function
getContext
(
){
return
getCanvas
(
).getContext
(
"2d"
);
}
function
getCanvas
(
){
return
document.querySelector
(
"canvas"
);
}
window.addEventListener
(
"load"
,
init);
Cette portion correspond à un carré de 100px de côté et dont le coin en haut à gauche est situé aux coordonnées x = 0px et y = 0px.
Cette portion d’image sera dessinée sur le canvas dans un carré de 250px de côté et dont le coin en haut à gauche est situé aux coordonnées x = 30px et y = 30px.
I-D. Ombres portées▲
Maintenant, nous allons pouvoir passer au dessin avec des ombres, nous allons donc nous intéresser aux propriétés : shadowColor, shadowBlur, shadowOffsetX et shadowOffsetY de l’objet context. Ces propriétés peuvent être utilisées avec les méthodes de dessin classiques, avec ou sans texture.
- La propriété shadowOffsetX sert à définir le décalage en x que l’ombre aura par rapport au dessin, le type de cette propriété est un entier.
- La propriété shadowOffsetY sert à définir le décalage en y que l’ombre aura par rapport au dessin, le type de cette propriété est un entier.
- La propriété shadowColor, comme son nom l’indique, définit la couleur de l’ombre, le type de cette propriété est une chaîne.
- La propriété shadowBlur, elle, sert à spécifier la netteté (ou plus spécifiquement le flou) que l’on souhaite appliquer à cette ombre, le type de cette propriété est un entier.
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.
function
init
(
){
const
canvas =
getCanvas
(
);
const
context =
getContext
(
);
// on détermine les dimensions du canvas
canvas.
width =
640
;
canvas.
height =
480
;
// on sauvegarde le contexte
context.save
(
);
// on récupère l'élément html de type image qui nous sert de texture (ici kirby)
const
kirby =
document.querySelector
(
"img"
);
// on définit les propriétés de l'ombre portée pour tous les dessins
// qui vont suivre.
context.
shadowBlur =
10
;
context.
shadowColor =
"#ff0000"
;
// l'ombre sera rouge
context.
shadowOffsetX =
10
;
// ombre décalée de 10px vers la droite
context.
shadowOffsetY =
10
;
// ombre décalée de 10px vers le bas
// puis on le dessine à l'aide de la méthode drawImage de l'objet de type context
// on dessine la portion de l'image originelle comprise entre les coordonnées x = 0, y = 0, x = 100, y = 100
// on dessine cette portion de façon un peu déformée
context.drawImage
(
kirby,
0
,
0
,
100
,
100
,
30
,
30
,
250
,
250
);
// on restaure le contexte
context.restore
(
);
}
function
getContext
(
){
return
getCanvas
(
).getContext
(
"2d"
);
}
function
getCanvas
(
){
return
document.querySelector
(
"canvas"
);
}
window.addEventListener
(
"load"
,
init);
I-E. Dessiner à travers un masque▲
Nous allons à présent apprendre à dessiner à travers un masque. Pour cela, nous allons avoir besoin de la propriété globalCompositeOperation de l’objet context. Cette propriété peut prendre plusieurs valeurs dont les résultats sont illustrés à l’aide du graphique ci-dessous :
Canvas autorise plusieurs modes de fusion. Le mode de fusion correspond à la façon dont la source interagit avec la destination. Ici, le carré bleu est ce qui a déjà été dessiné, il s'agit de la source. Le cercle rouge, quant à lui, correspond à la destination.
Comment interpréter ce graphique ? En premier lieu, il faut que je vous donne le code source qui va avec :
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.
48.
49.
50.
51.
52.
53.
54.
function
init
(
){
const
canvas =
getCanvas
(
);
const
context =
getContext
(
);
// on détermine les dimensions du canvas
canvas.
width =
640
;
canvas.
height =
480
;
// on sauvegarde le contexte
context.save
(
);
// on récupère l'élément html de type image qui nous sert de texture (ici kirby)
const
kirby =
document.querySelector
(
"img"
);
// on définit les propriétés de l'ombre portée pour tous les dessins
// qui vont suivre.
context.
shadowBlur =
10
;
context.
shadowColor =
"#ff0000"
;
// l'ombre sera rouge
context.
shadowOffsetX =
10
;
// ombre décalée de 10px vers la droite
context.
shadowOffsetY =
10
;
// ombre décalée de 10px vers le bas
// on va dessiner notre kirby à travers un masque circulaire
// commençons par dessiner le cercle en question
context.beginPath
(
);
context.
fillStyle =
"red"
;
// ici peu importe la couleur du moment que le cercle est plein
context.moveTo
(
225
,
225
);
context.arc
(
225
,
255
,
125
,
0
,
360
*
Math
.
PI /
180
);
context.fill
(
);
// une fois notre cercle dessiné, on change le mode de fusion
// de la balise canvas pour le définir à source-in.
// tous les dessins qui vont suivre seront dessinés à travers un masque
context.
globalCompositeOperation =
"source-in"
;
// puis on le dessine à l'aide de la méthode drawImage de l'objet de type context
context.drawImage
(
kirby,
0
,
0
);
// on restaure le contexte
context.restore
(
);
}
function
getContext
(
){
return
getCanvas
(
).getContext
(
"2d"
);
}
function
getCanvas
(
){
return
document.querySelector
(
"canvas"
);
}
window.addEventListener
(
"load"
,
init);
Il s’agit d’une opération en deux étapes :
- tout d’abord, on dessine le masque sur l’objet context (ici le cercle) ;
- ensuite, on spécifie la valeur de la propriété globalCompositeOperation de l’objet context (ici source-in) ;
- puis, on dessine le contenu que l’on souhaite voir apparaître à travers le masque (kirby).
Il suffit de changer la valeur de la propriété globalCompositeOperation pour pouvoir obtenir tous les résultats retranscrits sur le graphique. Pour dessiner un objet à travers un masque, la valeur qui nous intéresse est source-in. Voilà, les bases du dessin de texture ont été passées en revue !
II. Remerciements Developpez.com▲
Nous tenons à remercier Nicolas Legrand qui nous a aimablement autorisés à publier son tutoriel. Nos remerciements également à Yahiko pour la relecture technique, Malick pour la mise au gabarit et Escartefigue pour la relecture orthographique.