说我在HTML5画布上有一个圆圈(圆弧)。我可以像这样填写:
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fill();
它是一种享受。但是,如何填补相反的区域?现在它是白色的黑色圆圈,但我希望它沿着下图的线条(白色是背景颜色,黑色是填充颜色):
我知道我可以使用黑色背景并绘制一个白色圆圈,但背景可以是任何东西(之前已经绘制过各种各样的东西,所以只能交换颜色)。
另一件事是,不应该填充完整的画布,而是取消圆圈的正方形。
我在考虑globalCompositeOperation
,但它似乎不符合我的需要,因为它们都没有根据我的需要行事。
那么,我如何完成填充'对面'区域,如示例图像?
答案 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">
答案 2 :(得分:4)
通常这样做的方法是使用“剪切区域”,您可以在其中创建应用绘图操作的区域蒙版。 HTML5画布能够制作一个圆圈本身的剪贴蒙版......
http://www.html5canvastutorials.com/tutorials/html5-canvas-clipping-region-tutorial/
...但它缺少Google Gears Canvas中的subtract()操作,我发现它们声称是“来自HTML5”......但显然它不是。
有人在这里回答了如何反转剪辑(),但它涉及一个离屏画布:
希望别人会有更好的建议。 : - /
答案 3 :(得分:0)
在画布蒙版上使用XOR功能仅适用于不透明填充(即与globalAlpha不兼容)。解决此问题的一种方法是使用.clip()函数并使用背景中的内容填充剪切区域。然后,您可以将剪裁的区域覆盖在原始画布的顶部,您可以在其上执行所需的任何填充。