仅将canvas复合应用于两个操作

时间:2012-05-25 17:25:17

标签: javascript canvas composite

我需要绘制一个不透明的比萨饼,使其看起来“空”,然后使用画布以顺时针方式逐渐用完整的彩色图像填充披萨。

我开始绘制“空”披萨,使用globalAlpha低于1的相同图像。

然后我在它上方画了一个“完整”的比萨饼。

最后,我逐渐绘制一个圆弧作为披萨的遮罩,并在其上应用复合操作"destination-atop"。这有效地掩盖了我想要的披萨,但是还有掩盖第一个披萨的不利后果,即“空”披萨。我只想隐藏我正在画的第二个披萨。

所以基本上,我需要在两个操作之间进行复合,而不是在先前绘制的所有内容之后绘制的所有内容之间进行复合。这是我的代码:

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

我该怎么做?

1 个答案:

答案 0 :(得分:3)

您可以在绘制实际披萨图像之前创建剪裁区域,而不是绘制蒙版。代码几乎相同,您基本上将ctx.fill()的调用替换为ctx.clip(),然后向下移动第二个drawImage。您还需要save / restore上下文状态每次都重置剪切区域。

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);
};