画布清除矩形,带透明度

15

我知道context.clearRect可以使像素透明,但是我想知道,是否有一种函数可以使像素半透明?

例如,假设我有一个带有以下颜色的画布(每个颜色中的第四个值代表alpha):

#ffff #feef #abff
#5f6f #000f #ffff

运行clearRect会得到以下结果(或类似的结果,仅将它们全部变为透明):

#fff0 #fee0 #abf0
#5f60 #0000 #fff0

我希望去除不透明度,但并不希望它变成完全透明(有点像clearRect的globalAlpha),这样可以得到如下效果(假设我将globalAlpha设置为0.5):

#fff8 #fee8 #abf8
#5f68 #0008 #fff8

这是可能的吗?或者直接在离屏画布上绘制所有内容,然后在屏幕画布上绘制该画布(设置 globalAlpha )会更简单?

如果有任何不清楚的地方,请告诉我。


你可以使用 context.fillColor = "rgba(0-255, 0-255, 0-255, 0-1)" 并使用 fillRect。第四个参数是 alpha 值。0 表示完全透明,1 表示完全不透明。 - Gustavo Carvalho
@gfcarv 是的,那差不多是我想要的,但我不需要颜色。我想要去掉透明度(我正在使用动态模糊,我需要背景是透明的)。 - MiJyn
1
请查看此线程:https://dev59.com/ilXTa4cB1Zd3GeqPzTa8。我认为使用离屏画布会更简单。您可以使用`getImageData`逐个更改像素颜色,然后使用`putImageData`在画布中反映这些更改,但是您不想这样做,因为它非常低效。 - Gustavo Carvalho
2个回答

28

上面的答案能够完成任务,但是getImageData非常缓慢,如果你有很多其他的事情要处理,它会极大地减慢你的动画。如果你创建第二个离屏canvas元素,你可以将它的全局alpha设置为0.9,并来回切换它们,以更高的速度获得相同的效果。

context2.clearRect(0,0,width,height);
context2.globalAlpha = .9;
context2.drawImage(canvas1,0,0);
context1.clearRect(0,0,width,height);
context1.drawImage(canvas2,0,0);
context1.the  rest of the drawing that you are doing goes here.

3
这是一个很好的解决方案,我建议任何来到这个帖子的人都要认真考虑它。 - Michael Bromley

4

我也曾试图弄清楚这个问题,最终决定通过逐像素计数并手动设置每个像素的alpha通道来解决。这样做需要更多的工作量,因为我不能只用一个矩形覆盖整个画布,但目前看来是有效的。

我这样做是为了在网页上设置背景图片,并将我的画布动画放在其上,而不必在画布元素中绘制背景。

var oldArray = context.getImageData(0,0,canvas.width,canvas.height);
//count through only the alpha pixels
for(var d=3;d<oldArray.data.length;d+=4){
    //dim it with some feedback, I'm using .9
    oldArray.data[d] = Math.floor(oldArray.data[d]*.9);
}
sw.context.putImageData(oldArray,0,0);

谢谢,虽然@gustavo-carvalho给了我一个我用过的替代方案,但这个直接回答了我的问题=) - MiJyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接