如何填充画布上的“对面”形状?

时间:2011-06-07 20:46:27

标签: html5-canvas

说我在HTML5画布上有一个圆圈(圆弧)。我可以像这样填写:

ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fill();

它是一种享受。但是,如何填补相反的区域?现在它是白色的黑色圆圈,但我希望它沿着下图的线条(白色是背景颜色,黑色是填充颜色):

opposite area

我知道我可以使用黑色背景并绘制一个白色圆圈,但背景可以是任何东西(之前已经绘制过各种各样的东西,所以只能交换颜色)。

另一件事是,不应该填充完整的画布,而是取消圆圈的正方形。

我在考虑globalCompositeOperation,但它似乎不符合我的需要,因为它们都没有根据我的需要行事。

那么,我如何完成填充'对面'区域,如示例图像?

4 个答案:

答案 0 :(得分:46)

在OP中绘制黑色形状 - 也就是说,绘制一个从中间切出一个圆形的矩形。

首先调用beginPath();然后顺时针画圈;然后逆时针绘制矩形(反之亦然);最后填写()。

var ctx = $('#cv').get(0).getContext('2d');

ctx.fillStyle = "grey";
ctx.beginPath();
ctx.arc(200, 200, 100, 0, 2 * Math.PI);
ctx.rect(400, 0, -400, 400);
ctx.fill();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="400" height="400" id="cv"></canvas>

从大多数文档中可能并不明显,但您可以在单个fill(),stroke()或clip()操作中组合多个子路径。要在形状上打孔,只需沿相反方向绘制孔的形状即可。 beginPath()方法重置当前路径。对于fill()和clip(),Canvas使用非零绕组数规则 - 如果你读到它应该变得更清晰。

答案 1 :(得分:16)

你可以使用另一个画布作为掩码:

// This is the canvas where you want to draw
var canvas = document.getElementById('your-canvas');
var ctx = canvas.getContext('2d');

// I'll use a skyblue background that covers everything
// Just to demonstrate
ctx.fillStyle = "skyblue";
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Create a canvas that we will use as a mask
var maskCanvas = document.createElement('canvas');
// Ensure same dimensions
maskCanvas.width = canvas.width;
maskCanvas.height = canvas.height;
var maskCtx = maskCanvas.getContext('2d');

// This color is the one of the filled shape
maskCtx.fillStyle = "black";
// Fill the mask
maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
// Set xor operation
maskCtx.globalCompositeOperation = 'xor';
// Draw the shape you want to take out
maskCtx.arc(30, 30, 10, 0, 2 * Math.PI);
maskCtx.fill();

// Draw mask on the image, and done !
ctx.drawImage(maskCanvas, 0, 0);
<canvas id="your-canvas">

Demo here

答案 2 :(得分:4)

通常这样做的方法是使用“剪切区域”,您可以在其中创建应用绘图操作的区域蒙版。 HTML5画布能够制作一个圆圈本身的剪贴蒙版......

http://www.html5canvastutorials.com/tutorials/html5-canvas-clipping-region-tutorial/

...但它缺少Google Gears Canvas中的subtract()操作,我发现它们声称是“来自HTML5”......但显然它不是。

有人在这里回答了如何反转剪辑(),但它涉及一个离屏画布:

Canvas 'Clip' reverse action?

希望别人会有更好的建议。 : - /

答案 3 :(得分:0)

在画布蒙版上使用XOR功能仅适用于不透明填充(即与globalAlpha不兼容)。解决此问题的一种方法是使用.clip()函数并使用背景中的内容填充剪切区域。然后,您可以将剪裁的区域覆盖在原始画布的顶部,您可以在其上执行所需的任何填充。