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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何填充画布上的“对面”形状?相关的知识,希望对你有一定的参考价值。

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

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

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

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

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

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

那么,如何在示例图像中完成填充“对面”区域?

答案

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

// 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">
另一答案

在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>
另一答案

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

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

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

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

Canvas 'Clip' reverse action?

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

另一答案

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

以上是关于如何填充画布上的“对面”形状?的主要内容,如果未能解决你的问题,请参考以下文章

可拖动图像上的画布绘图

在画布中使用 globalCompositeOperation 屏蔽多个形状

更改画布形状

重新填充画布擦除区域的区域

在哪里以及如何使用片段填充我的标签

光栅化形状上的光线行进