Dibujar un pajarito
o clip versus globalCompositeOperation
Vamos a practicar un poco lo que hemos aprendido hasta ahora, dibujando un pajarito regordete, que al inicio nos causará problemas en Google Chrome. Pero ¡no temáis! porque bien está lo que bien acaba.
Método | JavaScript | Descripción | Defecto |
---|---|---|---|
clip() | context.clip() | Recorta una región con la forma y tamaño del trazado dibujado previamente en el canvas. Cualquier cosa dibujada después, será visible solo dentro de la región de recorte ( clipping region ). | <canvas> |
globalCompositeOperation | context. globalCompositeOperation = "source-in" | Define la apariencia de nuevos trazados, y como estos afectan o están afectados por los trazados ya existentes en el <canvas> .posibles valores: source-over, source-in, source-out, source-atop, destination-over, destination-atop, destination-in, destination-out, lighter, darker, copy, xor |
source-over |
Vea la chuleta con las propiedades y metodos() de canvas.
Dibujar pajarito con clip()
Empezaremos dibujando la colita, el pico y las patas. Después esbozaremos un circulo con el radio de 70px
y, llamaremos el método clip()
para convertirlo en una nueva
región de recorte ( clipping region ), que representará el cuerpo del pajarito. Dentro dibujaremos barriguita, ala, y todo lo demás.
var canvas = document.getElementById("lienzo");
if (canvas && canvas.getContext) {
var ctx = canvas.getContext("2d");
if (ctx) {
//colita
ctx.beginPath()
ctx.fillStyle = "#fcc";
ctx.moveTo(165, 175);
ctx.lineTo(210, 168);
ctx.lineTo(180, 140);
ctx.fill();
// pico
ctx.beginPath()
ctx.fillStyle = "#f90";
ctx.moveTo(35, 95);
ctx.lineTo(70, 85);
ctx.lineTo(57, 110);
ctx.fill();
//patas
ctx.beginPath()
ctx.fillStyle = "#cc9";
ctx.moveTo(125, 185);
ctx.lineTo(125, 215);
ctx.lineTo(140, 180);
ctx.lineTo(140, 215);
ctx.lineTo(155, 177);
ctx.fill();
var cX = ctx.canvas.width / 2;
var cY = ctx.canvas.height / 2;
var r = 70;
// recortamos!!!
ctx.beginPath();
ctx.arc(cX, cY, r, 0, 2 * Math.PI);
ctx.clip();
// cuerpo
ctx.beginPath();
ctx.fillStyle = "#ccc";
ctx.arc(cX, cY, r, 0, 2 * Math.PI);
ctx.fill();
// barriguita
ctx.beginPath();
ctx.fillStyle = "#cc9";
ctx.arc(125, 180, r, 0, 2 * Math.PI);
ctx.fill();
// ala
ctx.beginPath();
ctx.fillStyle = "#fcc";
ctx.arc(180, 105, r, 0, 2 * Math.PI);
ctx.fill();
// ojo
ctx.beginPath();
ctx.fillStyle = "#000";
ctx.arc(90, 90, 4, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#eee";
ctx.arc(90, 90, 2, 0, 2 * Math.PI);
ctx.fill();
}
}
Todo parece funcionar muy bien, pero en Google Chrome el borde del cuerpo ( la región de recorte ) aparece pixelado y muy feo ( por culpa del Anti Aliasing ) y NO lo podemos arreglar con un borde, ya que de esta manera el borde aparecería entre el cuerpo y la colita y las demás cosas.
Dibujar pajarito con "source-atop"
Borramos las líneas de código que definen la región de recorte ( las lineas 34-37 del ejemplo anterior ), y enseguida después de dibujar el cuerpo del pajarito escribimos esta línea de código:
ctx.globalCompositeOperation = "source-atop";
Utilizando "source-atop"
haremos que todos los trazados dibujados después ( source ) sean visibles solo encima del cuerpo del animal ( destination ).
var canvas1 = document.getElementById("lienzo1");
if (canvas1 && canvas1.getContext) {
var ctx1 = canvas1.getContext("2d");
if (ctx1) {
//colita
ctx1.beginPath()
ctx1.fillStyle = "#fcc";
ctx1.moveTo(165, 175);
ctx1.lineTo(210, 168);
ctx1.lineTo(180, 140);
ctx1.fill();
// pico
ctx1.beginPath()
ctx1.fillStyle = "#f90";
ctx1.moveTo(35, 95);
ctx1.lineTo(70, 85);
ctx1.lineTo(57, 110);
ctx1.fill();
//patas
ctx1.beginPath()
ctx1.fillStyle = "#cc9";
ctx1.moveTo(125, 185);
ctx1.lineTo(125, 215);
ctx1.lineTo(140, 180);
ctx1.lineTo(140, 215);
ctx1.lineTo(155, 177);
ctx1.fill();
var cX = ctx1.canvas.width / 2;
var cY = ctx1.canvas.height / 2;
var r = 70;
// cuerpo
ctx1.beginPath();
ctx1.fillStyle = "#ccc";
ctx1.arc(cX, cY, r, 0, 2 * Math.PI);
ctx1.fill();
//globalCompositeOperation en lugar de clip
ctx1.globalCompositeOperation = "source-atop";
// barriguita
ctx1.beginPath();
ctx1.fillStyle = "#cc9";
ctx1.arc(125, 180, r, 0, 2 * Math.PI);
ctx1.fill();
// ala
ctx1.beginPath();
ctx1.fillStyle = "#fcc";
ctx1.arc(180, 105, r, 0, 2 * Math.PI);
ctx1.fill();
// ojo
ctx1.beginPath();
ctx1.fillStyle = "#000";
ctx1.arc(90, 90, 4, 0, 2 * Math.PI);
ctx1.fill();
ctx1.beginPath();
ctx1.fillStyle = "#eee";
ctx1.arc(90, 90, 2, 0, 2 * Math.PI);
ctx1.fill();
}
}
Et voila!... podría decirse que tenemos un pajarito perfecto.