Apply canvas composite to only two operations
canvas, composite, javascript
Solution
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);
};
Problem
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); }; ``` jsFiddle How can I do that?