从画布中清除区域的唯一方法是使用clearRect()命令 - 我需要清除一个圆圈(我在填充的画布中遮住区域,在这种特定情况下指向灯光)尽管如此所有尝试似乎都不可能。
我尝试绘制一个alpha值为0的圆圈,但除非alpha更高(这与点相反:P),否则不会出现任何内容 - 我假设因为contex.fill()将其绘制为添加而不是而不是替换。
有关如何(快速)清除圆圈以进行遮罩的任何建议吗?
答案 0 :(得分:37)
使用.arc
创建一个圆形笔划,然后使用.clip()
使其成为当前剪裁区域。
然后你可以使用.clearRect()
来删除整个画布,但只有剪裁的区域会改变。
答案 1 :(得分:15)
如果您正在制作游戏或其他会影响性能的内容,请查看我是如何做出这样的答案的:Canvas - Fill a rectangle in all areas that are fully transparent
具体而言,编辑导致此问题的答案:http://jsfiddle.net/a2Age/2/
这里的巨大优势:
(1)我实际上complained about this和resetClip()因为它已被放入官方规范,但是在浏览器实现它之前会有一段时间。
var ctx = document.getElementById('canvas1').getContext('2d'),
ambientLight = 0.1,
intensity = 1,
radius = 100,
amb = 'rgba(0,0,0,' + (1 - ambientLight) + ')';
addLight(ctx, intensity, amb, 200, 200, 0, 200, 200, radius); // First circle
addLight(ctx, intensity, amb, 250, 270, 0, 250, 270, radius); // Second circle
addLight(ctx, intensity, amb, 50, 370, 0, 50, 370, radius, 50); // Third!
ctx.fillStyle = amb;
ctx.globalCompositeOperation = 'xor';
ctx.fillRect(0, 0, 500, 500);
function addLight(ctx, intsy, amb, xStart, yStart, rStart, xEnd, yEnd, rEnd, xOff, yOff) {
xOff = xOff || 0;
yOff = yOff || 0;
var g = ctx.createRadialGradient(xStart, yStart, rStart, xEnd, yEnd, rEnd);
g.addColorStop(1, 'rgba(0,0,0,' + (1 - intsy) + ')');
g.addColorStop(0, amb);
ctx.fillStyle = g;
ctx.fillRect(xStart - rEnd + xOff, yStart - rEnd + yOff, xEnd + rEnd, yEnd + rEnd);
}
canvas {
border: 1px solid black;
background-image: url('http://placekitten.com/500/500');
}
<canvas id="canvas1" width="500" height="500"></canvas>
答案 2 :(得分:8)
鉴于要求,这些答案都很好。但是,让我们说你和我一样,你还有其他要求:
对于第一个要求,解决方案是使用context.globalCompositeOperation = 'destination-out'
蓝色是第一个形状,红色是第二个形状。如您所见,destination-out
从第一个形状中删除了该部分。
以下是一些示例代码:
explosionCanvasCtx.fillStyle = "red"
drawCircle(explosionCanvasCtx, projectile.radius, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'destination-out' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
drawCircle(explosionCanvasCtx, projectile.radius + 20, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
以下是潜在的问题:第二个fill()
会清除下面的所有,包括背景。有时您只想清除第一个形状但仍希望看到它下面的图层。
解决方法是在临时画布上绘制它,然后drawImage
将临时画布绘制到主画布上。代码如下所示:
diameter = projectile.radius * 2
console.log "<canvas width='" + diameter + "' height='" + diameter + "'></canvas>"
explosionCanvas = $("<canvas width='" + diameter + "' height='" + diameter + "'></canvas>")
explosionCanvasCtx = explosionCanvas[0].getContext("2d")
explosionCanvasCtx.fillStyle = "red"
drawCircle(explosionCanvasCtx, projectile.radius, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'destination-out' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
durationPercent = (projectile.startDuration - projectile.duration) / projectile.startDuration
drawCircle(explosionCanvasCtx, projectile.radius + 20, projectile.radius, projectile.radius)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation = 'source-over' #see https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
ctx.drawImage(explosionCanvas[0], projectile.pos.x - projectile.radius, projectile.pos.y - projectile.radius) #center
答案 3 :(得分:7)
您有几个选择。
首先,这是我们用来填充圆圈的函数。
var fillCircle = function(x, y, radius)
{
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
};
clip()
var clearCircle = function(x, y, radius)
{
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.clip();
context.clearRect(x - radius - 1, y - radius - 1,
radius * 2 + 2, radius * 2 + 2);
};
在jsFiddle上查看。
globalCompositeOperation
var clearCircle = function(x, y, radius)
{
context.save();
context.globalCompositeOperation = 'destination-out';
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
context.restore();
};
在jsFiddle上查看。
两者都在屏幕上给出了期望的结果,但是在我的情况下表现不够,因为我正在绘制并清除每帧的很多圆圈以获得效果。最后,我找到了一种不同的方法,通过在弧上绘制较粗的线条来获得与我想要的相似的效果,但上述对于具有不同性能要求的人来说仍然有用。
答案 4 :(得分:0)
使用canvas.getContext("2d").arc(...)
在具有背景颜色的区域上绘制圆圈?
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.arc(x, y, r, 0, 2*Math.PI, false);
context.fillStyle = "#FFFFFF";
context.fill();
答案 5 :(得分:0)
其中x =左侧位置,y =右侧位置,r =半径,ctx =您的画布:
function clearCircle( x , y , r ){
for( var i = 0 ; i < Math.round( Math.PI * r ) ; i++ ){
var angle = ( i / Math.round( Math.PI * r )) * 360;
ctx.clearRect( x , y , Math.sin( angle * ( Math.PI / 180 )) * r , Math.cos( angle * ( Math.PI / 180 )) * r );
}
}