如何用帆布创建重叠 - 而不是堆叠 - 形状?

Mat*_*arn 4 javascript html5 canvas

我正在尝试创建一个重叠的形状数组.但是我很难防止那些形状堆叠在一起.

我想我希望它们在一起啮合,如果这有意义的话?

这是代码:

var overlap_canvas = document.getElementById("overlap");
var overlap_context = overlap_canvas.getContext("2d");
var x = 200;
var y = x;
var rectQTY = 4 // Number of rectangles

overlap_context.translate(x,y);

for (j=0;j<rectQTY;j++){    // Repeat for the number of rectangles

// Draw a rectangle
overlap_context.beginPath();
overlap_context.rect(-90, -100, 180, 80);
overlap_context.fillStyle = 'yellow';
overlap_context.fill();
overlap_context.lineWidth = 7;
overlap_context.strokeStyle = 'blue';
overlap_context.stroke();

// Degrees to rotate for next position
overlap_context.rotate((Math.PI/180)*360/rectQTY);
}
Run Code Online (Sandbox Code Playgroud)

这是我的jsFiddle:http: //jsfiddle.net/Q8yjP/

这就是我想要实现的目标:

http://postimg.org/image/iio47kny3/

任何帮助或指导将不胜感激!

小智 6

您不能指定此行为,但可以实现使用复合模式的算法方法.

本演示所示,结果如下:

正方形有重叠

定义线宽和你想要绘制的矩形(你可以用你已经得到的循环来填充这个数组来计算位置/角度 - 为简单起见,我只是在这里使用硬编码的):

var lw = 4,
    rects = [
        [20, 15, 200, 75],
        [150, 20, 75, 200],
        [20, 150, 200, 75],
        [15, 20, 75, 200]
    ], ...
Run Code Online (Sandbox Code Playgroud)

我将解释下面的线宽.

/// set line-width to half the size
ctx.lineWidth = lw * 0.5;
Run Code Online (Sandbox Code Playgroud)

在循环中,为第一次绘制添加一个条件,这也是更改复合模式的位置.我们还用最后一个矩形清除画布:

/// loop through the array with rectangles
for(;r = rects[i]; i++) {
    ctx.beginPath();
    ctx.rect(r[0], r[1], r[2], r[3]);
    ctx.fill();
    ctx.stroke();

    /// if first we do a clear with last rectangle and
    /// then change composite mode and line width
    if (i === 0) {
        r = rects[rects.length - 1];
        ctx.clearRect(r[0] - lw * 0.5, r[1] - lw * 0.5, r[2] + lw, r[3] + lw);
        ctx.lineWidth = lw;
        ctx.globalCompositeOperation = 'destination-over';
    }
}
Run Code Online (Sandbox Code Playgroud)

这将绘制矩形,您可以灵活地更改大小而无需重新计算裁剪.

线宽分别设置为stroke从中间划线.为此,因为我们以后使用destination-over模式,这意味着该行的一半将是不可见的,因为我们首先要填写成为目标的一部分,这样的行程将只能够填补抚摸区域之外(你可以恢复秩序strokefill,但将始终遇到第一个矩形的调整).

我们还需要它来计算剪切,其必须包括(一半)外部的线.

这也是我们最初将它设置为一半的原因,因为第一次绘制整条线 - 否则第一个矩形将具有两倍厚的边框.