38

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

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

这是一种享受。但是,一个人怎么能填满对面的区域呢?现在它是带有黑色圆圈的白色,但我希望它沿着下图的线条(白色是背景色,黑色是填充色):

对面区域

我知道我可以只使用黑色背景并画一个白色圆圈,但背景可以是任何东西(以前在那里画过各种各样的东西,所以只交换颜色是不可能的)。

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

我在想一个,globalCompositeOperation但它似乎不符合我的需要,因为它们都没有按照我的需要行事。

那么,我怎样才能完成填充示例图像中的“对面”区域?

4

4 回答 4

57

在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 使用非零缠绕数规则——如果你仔细阅读它应该会变得更清楚。

于 2012-08-02T01:53:17.773 回答
22

您可以使用另一个画布作为掩码来做到这一点:

// 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">

演示在这里

于 2011-06-07T21:29:49.237 回答
5

The way this would typically be done is with a "clipping region", where you make an area mask for which the drawing operations apply. HTML5 canvas has the ability to make a clipping mask that is the circle itself...

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

...but it lacks the subtract() operation that's in Google Gears Canvas, which I spotted and they claimed is "from HTML5"...but apparently it is not.

Someone answered how to invert a clip() here, but it involves an off-screen canvas:

Canvas 'Clip' reverse action?

Hopefully someone else will have a better suggestion. :-/

于 2011-06-07T21:16:49.270 回答
0

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

于 2017-04-17T21:19:04.403 回答