Tutoriel canvas:Compositions
Un article de MDC.
Sommaire |
Dans tous les exemples précédents, nous avons toujours dessiné des formes les unes au dessus des autres. C'est plus qu'il n'en faut pour la plupart des situations. Cela nous limite par exemple dans la façon dont les formes composées peuvent être construites. Cependant, on peut changer ce comportement en définissant la propriété globalCompositeOperation.
[modifier] globalCompositeOperation
Il est non seulement possible de dessiner de nouvelles formes derrière des formes existantes, mais également les utiliser pour masquer certaines zones, effacer certaines parties du canevas (pas seulement des rectangles comme le fait la méthode clearRect) et bien plus.
globalCompositeOperation = type
type est une chaîne représentant l'une des douze opérations de composition. Chacun des types disponibles est décrit ci-dessous.
Note : Dans tous les exemples ci-dessous, le carré bleu est dessiné en premier et est appelé le contenu existant du canevas. Le cercle rouge est dessiné ensuite est est appelé une nouvelle forme.
|
source-over (default) |
destination-over | ||
|
source-in |
destination-in | ||
|
source-out |
destination-out | ||
|
source-atop |
destination-atop | ||
|
lighter |
darker | ||
|
xor |
copy |
Note : Actuellement, les réglages copy et darker ne font rien du tout dans les navigateurs basés sur Gecko 1.8 (Firefox 1.5, etc.)
[modifier] Chemins de découpe
Un chemin de découpe est comme une forme normale du canevas, mais qui agit comme un masque pour cacher les parties non désirées de l'image. On peut le visualiser dans l'image à droite. L'étoile rouge est notre chemin de découpe. Tout ce qui n'entre pas dans ce chemin ne sera pas dessiné sur le canevas.Si l'on compare les chemins de découpe à la propriété globalCompositeOperation vue plus haut, les réglages produisant plus ou moins le même effet sont source-in et source-atop. Les différences les plus importantes entre les deux sont que les chemins de découpe ne sont jamais réellement dessinés sur le canevas, et que les cehmins de découpe ne sont pas affectés par l'ajout de nouvelles formes. Ils sont donc idéaux pour dessiner plusieurs formes dans une zone restreinte.
Dans le chapitre à propos du dessin de formes géométriques, nous avions seulement mentionné les méthodes stroke et fill. Il y a cependant une troisième méthode que l'on peut utiliser, et il s'agit de clip.
clip()
La méthode clip est utilisée pour créer un nouveau chemin de découpe. Par défaut, l'élément canvas a un chemin de découpe qui a exactement la même taille que le canevas lui-même (c'est-à-dire qu'aucune découpe n'est faite).
[modifier] Un exemple d'utilisation de clip
Dans cet exemple, on utilise un chemin de découpe circulaire pour restreindre le dessin d'un ensemble d'étoiles dans une région particulière.
Dans les premières lignes de code, un rectangle noir est dessiné de la taille du canevas comme fond, et l'origine est déplacée vers le centre. Ensuite, le chemin de découpe circulaire est créé en dessinant un arc et en appelant la méthode clip. Les chemins de découpe font également partie de l'état du canevas lorsqu'il est enregistré. Si l'on voulait conserver la découpe initiale, on aurait pu enregistrer l'état du canevas avant d'en créer une nouvelle.
Après avoir créé le chemin de découpe, tout ce qui est dessiné par la suite n'apparaîtra qu'à l'intérieur du chemin. C'est clairement visible dans le cas du dégradé radial qui est dessiné ensuite. Après cela, un ensemble d'étoiles positionnées et dimensionnées aléatoirement sont dessinées (à l'aide d'une fonction personnalisée). Encore une fois, les étoiles apparaissent uniquement à l'intérieur du chemin de découpe spécifié.
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillRect(0, 0, 150, 150);
ctx.translate(75, 75);
// Crée un chemin de découpe circulaire
ctx.beginPath();
ctx.arc(0, 0, 60, 0, Math.PI*2, true);
ctx.clip();
// dessine le fond
var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
lingrad.addColorStop(0, '#232256');
lingrad.addColorStop(1, '#143778');
ctx.fillStyle = lingrad;
ctx.fillRect(-75, -75, 150, 150);
// dessine des étoiles
for (j = 1; j < 50; j++) {
ctx.save();
ctx.fillStyle = '#fff';
ctx.translate(75 - Math.floor(Math.random()*150),
75 - Math.floor(Math.random()*150));
drawStar(ctx, Math.floor(Math.random()*4) + 2);
ctx.restore();
}
}
function drawStar(ctx, r) {
ctx.save();
ctx.beginPath();
ctx.moveTo(r, 0);
for (i = 0; i < 9; i++) {
ctx.rotate(Math.PI/5);
if (i%2 == 0) {
ctx.lineTo((r/0.525731)*0.200811, 0);
} else {
ctx.lineTo(r, 0);
}
}
ctx.closePath();
ctx.fill();
ctx.restore();
}













