Canvas 一个画布,多层次内容

Canvas 一个画布,多层次内容,canvas,html5-canvas,Canvas,Html5 Canvas,我已经建立了一个多画布横幅(位置:绝对,不同的z-idex),但。。。但我想用一张画布来重新创作整个作品,结果证明这是个问题。横幅的动画非常复杂,所以这里有一个简短的问题,可以帮助我理解它是如何工作的 我想在那个黑色的长方形上“切”一个洞,这样红色的就可以看得见了 代码如下: red.beginPath(); red.fillStyle = '#af0000'; red.fillRect(33, 33, 200, 60); // drawing red rectan

我已经建立了一个多画布横幅(位置:绝对,不同的z-idex),但。。。但我想用一张画布来重新创作整个作品,结果证明这是个问题。横幅的动画非常复杂,所以这里有一个简短的问题,可以帮助我理解它是如何工作的

我想在那个黑色的长方形上“切”一个洞,这样红色的就可以看得见了

代码如下:

    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();
我知道为什么两个矩形都会受到影响。这只是为了说明我想要实现的目标。我可以用两块画布来画它——在一块画布上画红色矩形,在另一块画布上画黑色矩形,然后剪切黑色矩形——但我只想用一块画布来画。 另外,我知道我可以重新画红色部分,但我怀疑这是一个明智的解决方案

这是小提琴:

提前谢谢


我知道这是一个相当业余的问题,但……无论如何——试图找到解决办法却没有运气。

答案不是那么容易:要用洞画画,你必须把你的直肠的一部分剪掉,而剪掉的意思是剪掉。
但是有一种方法可以裁剪出一个矩形:裁剪整个画布,然后逆时针减去内部的矩形

我还让您的代码“数据驱动”,因此更容易进行更改


万分感谢,炼金术士,陛下!一小时内要分析代码。
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);