一个画布,多层内容

时间:2014-11-15 04:59:11

标签: canvas html5-canvas

我已经制作了一个带有多个画布的横幅(位置:绝对,不同的z-idexes)但是......但是我只能用一个画布重新创建整个画面而且它被证明是一个问题。横幅的动画非常复杂,所以这里有一个简短的问题,这将帮助我理解它是如何工作的。

我想" cut"在那个黑色矩形中的一个洞,所以红色的那个变得可见

以下是代码:

    red.beginPath(); 
    red.fillStyle = '#af0000';  
    red.fillRect(33, 33, 200, 60); // drawing red rectangle
    red.closePath();

    red.beginPath();
    red.fillStyle = '#000'; 
    red.fillRect(77, 66, 120, 60); // drawing black one
    red.clearRect(110, 80, 20, 20); // cutting 20X20 pixels rectangle
    red.closePath();

我知道为什么两个矩形都会受到影响。这只是为了说明我想要实现的目标。我可以用两个画布制作它 - 在一个画上红色矩形而在另一个上画黑色,然后剪下黑色 - 但我只想用一个画布来画它。 此外 - 我知道我可以重新绘制那个红色部分,但怀疑这是一个明智的解决方案。

这是小提琴: http://jsfiddle.net/hej11px9/

提前致谢!

我知道这是一个非常业余的问题,但是......无论如何 - 试图找到没有运气的解决方案。

1 个答案:

答案 0 :(得分:1)

答案并不那么容易:要画一个洞,你必须剪掉 out 你的矩形的一部分,当剪裁是为了剪辑。
但是有一个解决方法可以在整个画布中剪切出一个rect:clip,然后逆时针减去内部rect。

我还有您的代码'数据驱动',因此更容易进行更改。

http://jsfiddle.net/casemate/hej11px9/1/

enter image description here

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');

var redRect = {
    x: 33,
    y: 33,
    width: 200,
    height: 60,
    color: '#af0000'
};
var blackRect = {
    x: 77,
    y: 66,
    width: 120,
    height: 60,
    color: '#000'
};
var blackRectHole = {
    x: 110,
    y: 80,
    width: 20,
    height: 20
};
var cvRect = {
    x: 0,
    y: 0,
    width: canvas.width,
    height: canvas.height
};


function drawRect(rect) {
    ctx.beginPath();
    ctx.fillStyle = rect.color;
    ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
    ctx.closePath();
}

function drawRectClipped(rect, clipRect) {
    ctx.save();
   clipOut(clipRect);
    drawRect(rect);
    ctx.restore();
}

function clipOut(clipRect) {
    ctx.beginPath();
    rectPath(cvRect);
    ctx.lineTo(clipRect.x, clipRect.y);
    rectPath_ccw(clipRect);
    ctx.clip();    
}

function rectPath(rect) {
    ctx.moveTo(rect.x, rect.y);
    ctx.lineTo(rect.x + rect.width, rect.y);
    ctx.lineTo(rect.x + rect.width, rect.y + rect.height);
    ctx.lineTo(rect.x, rect.y + rect.height);
    ctx.lineTo(rect.x, rect.y);
}

function rectPath_ccw(rect) {
    ctx.moveTo(rect.x, rect.y);
    ctx.lineTo(rect.x, rect.y + rect.height);
    ctx.lineTo(rect.x + rect.width, rect.y + rect.height);
    ctx.lineTo(rect.x + rect.width, rect.y);
    ctx.lineTo(rect.x, rect.y);
}

drawRect(redRect);
drawRectClipped(blackRect, blackRectHole);