由globalCompositeOperation

时间:2015-10-07 04:19:52

标签: javascript html5 html5-canvas

我正在尝试编写一个Sierpinski Carpet的前几次迭代的简单演示,如下所示:

Sierpinski Carpet

我想要继续的方法是单击以在每个步骤中以较小的比例应用基本图案蒙版。在我看来,从黑色方块开始,然后使用" destination-in"的globalCompositeOperation。和一个源掩码就像第二张图像一样,我应该可以做我想做的事情,但是我很难把它放在一起。

这会绘制背景黑色方块:

context.globalCompositeOperation = "source-over";
context.fillStyle = 'black';
context.fillRect(0, 0, 500, 500);

然后我期望像下面这样的代码应该产生第一步。但它只是空白。

context.globalCompositeOperation = "destination-in";
var mask = [1, 1, 1, 1, 0, 1, 1, 1, 1];
for (var m = 0; m < 9; ++m)
{
    var x = 10 + m % 3 * 150;
    var y = 10 + Math.floor(m / 3) * 150;
    if (mask[m] > 0)
    {
        context.fillRect(x, y, 150, 150);
    }
}

我在http://jsfiddle.net/128gxxmy/4/放了一个小提琴来表示问题。

这似乎并不困难,所以我明显误解了一些重要的事情,并会对任何建议表示感谢。

感谢。

编辑:当然!我知道为什么它一片空白。第一个填充rect清除除左上角之外的所有内容,然后下一个擦除它。我需要一次性使用rect(...)然后fill()。如果我重新编写它以在一个步骤中绘制每个通道,它应该可以解决问题。

1 个答案:

答案 0 :(得分:0)

为了完整性,如果其他人陷入同一陷阱,请参阅相关代码。我最终使用了一个临时(不可见)画布,并用一个填充画了整个图层。

function drawLevel(k, fill, mask)
{
    tempContext.save();
    tempContext.clearRect(0, 0, canvas.width, canvas.height);

    // current canvas is destination
    tempContext.drawImage(canvas, 0, 0);
    // set global composite
    tempContext.globalCompositeOperation = "destination-in";

    // draw source
    tempContext.beginPath();

    // how many squares each row
    var n = Math.pow(3, k);

    var size = 450 / n / 3;
    for (var i = 0; i < n; ++i)
        for (var j = 0; j < n; ++j)
        {
            for (var m = 0; m < 9; ++m)
            {
                var x = 10 + i * size + m % 3 * size;
                var y = 10 + j * size + Math.floor(m / 3) * size;
                if (mask[m] > 0)
                {
                    tempContext.rect(x, y, size, size);
                }
            }
        }

    tempContext.fillStyle = fill;
    tempContext.fill();
    tempContext.restore();

    // copy drawing from tempCanvas onto visible canvas
    context.drawImage(tempCanvas, 0, 0);
}