Javascript 从HTML5画布清除圆形区域
从画布上清除区域的唯一方法似乎是使用clearRect()命令-我需要清除一个圆(我正在从填充的画布上屏蔽区域,在这种特定情况下是点光源),尽管进行了各种尝试,但这似乎是不可能的 我尝试绘制一个alpha值为0的圆,但除非alpha值更高(与点:p相反),否则什么也不会出现——我假设是因为contex.fill()将其绘制为添加而不是替换Javascript 从HTML5画布清除圆形区域,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,从画布上清除区域的唯一方法似乎是使用clearRect()命令-我需要清除一个圆(我正在从填充的画布上屏蔽区域,在这种特定情况下是点光源),尽管进行了各种尝试,但这似乎是不可能的 我尝试绘制一个alpha值为0的圆,但除非alpha值更高(与点:p相反),否则什么也不会出现——我假设是因为contex.fill()将其绘制为添加而不是替换 关于如何(快速)清除用于遮罩的圆圈,有什么建议吗?使用canvas.getContext(“2d”).arc(…)在带有背景色的区域上画一个圆圈 var ca
关于如何(快速)清除用于遮罩的圆圈,有什么建议吗?使用
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();
使用
.arc
创建圆形笔划,然后使用.clip()
使其成为当前剪裁区域
然后,您可以使用
.clearRect()
擦除整个画布,但只有剪裁区域会发生更改。如果您正在制作一个游戏或其他游戏,压缩每一点性能都很重要,请看看我是如何回答的:
具体而言,答案的编辑会导致:
这里的巨大优势是:
- 不使用路径(慢速)
- 不使用剪辑(慢速)
- 无需保存/还原(因为在不清除所有状态(1)的情况下无法重置剪辑区域,这意味着您还必须使用保存/还原)
var ctx=document.getElementById('canvas1').getContext('2d'),
环境光=0.1,
强度=1,
半径=100,
amb='rgba(0,0,0,'+(1-环境光)+')';
添加灯光(ctx、强度、amb、200、200、0、200、200、半径);//第一圈
添加灯光(ctx、强度、amb、250、270、0、250、270、半径);//第二圈
附加光(ctx,强度,电磁轴承,50,370,0,50,370,半径,50);//第三
ctx.fillStyle=amb;
ctx.globalCompositeOperation='xor';
ctx.fillRect(0,0500500);
功能添加灯(ctx、intsy、amb、xStart、yStart、rStart、xEnd、yEnd、rEnd、xOff、yOff){
xOff=xOff | | 0;
约夫=约夫| | 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);
}
画布{
边框:1px纯黑;
背景图像:url('http://placekitten.com/500/500');
}
您有几个选择
首先,这是一个用来填充圆的函数
var fillCircle = function(x, y, radius)
{
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fill();
};
clip()
看看这个
globalCompositeOperation
看看这个
两者都在屏幕上给出了期望的结果,但是在我的情况下,性能不够,因为我在每一帧中绘制并清除了许多圆圈以获得效果。最后,我找到了一种不同的方法,通过在圆弧上画较粗的线来获得与我想要的效果相似的效果,但上述方法可能对具有不同性能要求的人仍然有用。其中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 );
}
}
函数clearCircle(x,y,r){
for(var i=0;i
根据要求,这些答案很好。但假设你和我一样,你有额外的要求:
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
直径=射弹半径*2
console.log“”
explosionCanvas=$(“”)
explosionCanvasCtx=explosionCanvas[0]。getContext(“2d”)
explosionCanvasCtx.fillStyle=“红色”
绘图圈(explosionCanvasCtx,射弹半径,射弹半径,射弹半径)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation='destination out'#请参阅https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
持续时间百分比=(射弹.startDuration-射弹.duration)/射弹.startDuration
绘图圈(explosionCanvasCtx,射弹半径+20,射弹半径,射弹半径)
explosionCanvasCtx.fill()
explosionCanvasCtx.globalCompositeOperation='source over'#请参阅https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html
ctx.drawImage(explosionCanvas[0],射弹位置x-射弹半径,射弹位置y-射弹半径)#中心
出于性能方面的考虑,如果背景不透明,这是应该做的,而不是剪辑,但不幸的是,这不太可能。如果背景有任何透明度,这将不起作用。谢谢你花时间回答:)不幸的是,在这种情况下,背景不是不透明的,因此不会产生我想要的结果。
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()
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