I need to draw a pizza with opacity so that it looks "empty", and progressively fill the pizza with the full colored image in a clockwise manner using canvas.
I started out by drawing the "empty" pizza, using the same image with a globalAlpha
inferior to 1.
Then I drew the "full" pizza right above it.
Finally, I progressively draw an arc as the mask for the pizza and applied a composite operation on it, "destination-atop"
. This effectively masks the pizza like I want it to, but with the adverse consequence of also masking the first pizza, the "empty" one. I only want it to hide the second pizza I'm drawing.
So basically, I need to do a composite between only two operations, and not between everything drawn previously and everything drawn after. Here is my code:
var ratio = 0;
var image = new Image();
image.src = "http://www.pizza.la-recette.net/img/pizza-001.jpg";
image.onload = function() {
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext("2d");
setInterval(function() {
ratio += 0.01;
ratio = ratio % 1;
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Draw "empty" pizza image
ctx.globalAlpha = 0.6;
ctx.drawImage(image, 0, 0);
//Draw actual pizza image
ctx.globalAlpha = 1;
ctx.drawImage(image, 0, 0);
//Draw mask
ctx.globalCompositeOperation = "destination-atop";
ctx.beginPath();
ctx.moveTo(image.width / 2, image.height / 2);
ctx.arc(image.width / 2, image.height / 2, image.width / 2, -Math.PI / 2, (-Math.PI / 2) + ((Math.PI * 2) * ratio), false);
ctx.fill();
}, 100);
};
How can I do that?
Instead of drawing a mask, you can create a clipping region before you draw the actual pizza image. The code is almost the same, you basically replace the call to ctx.fill()
with ctx.clip()
and move the second drawImage
down. You also need to save
/restore
the context state to reset the clipping region each time.
var ratio = 0;
var image = new Image();
image.src = "http://www.pizza.la-recette.net/img/pizza-001.jpg";
image.onload = function() {
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext("2d");
setInterval(function() {
ratio += 0.01;
ratio = ratio % 1;
ctx.clearRect(0, 0, canvas.width, canvas.height);
//Draw "empty" pizza image
ctx.globalAlpha = 0.6;
ctx.drawImage(image, 0, 0);
ctx.save();
//Set the clipping region
ctx.beginPath();
ctx.moveTo(image.width / 2, image.height / 2);
ctx.arc(image.width / 2, image.height / 2, image.width / 2, -Math.PI / 2, (-Math.PI / 2) + ((Math.PI * 2) * ratio), false);
ctx.clip();
//Draw actual pizza image
ctx.globalAlpha = 1;
ctx.drawImage(image, 0, 0);
ctx.restore();
}, 100);
};