如何在HTML5画布上绘制模糊的圆形?

35
我能在HTML5画布上绘制一个简单的圆,但我想在它周围添加一些模糊效果。
我找到了这个网站,它解释了可以派上用场的shadowBlur属性。
然而,我无法使圆本身模糊。 shadowBlur属性基本上是在绘制常规圆之后绘制一些模糊效果。 我迄今为止尝试过的是在jsFiddle上放置的内容。
可以看到,它是一个实心填充的圆,周围有一些模糊效果-两个部分根本不混合在一起。 我真正想要实现的是像这样完全模糊的圆:

blurred circle

有没有办法画一个模糊的圆形,就像这样,即圆形本身也具有模糊效果?

5个回答

55

我强烈建议不要使用模糊算法,除非你正在模糊一些已经存在复杂绘制的内容。

对于你的情况,只需使用径向渐变绘制一个矩形即可。

  var radgrad = ctx.createRadialGradient(60,60,0,60,60,60);
  radgrad.addColorStop(0, 'rgba(255,0,0,1)');
  radgrad.addColorStop(0.8, 'rgba(228,0,0,.9)');
  radgrad.addColorStop(1, 'rgba(228,0,0,0)');

  // draw shape
  ctx.fillStyle = radgrad;
  ctx.fillRect(0,0,150,150);

例子:

http://jsfiddle.net/r8Kqy/48/


3
使用 RGBA 来获取模糊区域中适当的透明度,这个做法值得点赞。干得好! - Phrogz
2
但请记住,这不是真正的(高斯)模糊!这种模糊是由一个带有直边的“锥形”制成的,真正的(高斯)模糊看起来会更柔和。您可以通过添加更多的colorStops来近似它。 - Ivan Kuckir
这很好。但在我的情况下,我需要直接使用imageData而不是context进行工作。有没有办法通过直接修改imageData来添加模糊圆形? - Niranth Reddy

6
您可能会发现 context.filter 属性很有用。

var canvas = document.getElementById('canvas');

var context = canvas.getContext('2d');

context.filter = "blur(16px)";

context.fillStyle = "#f00";
context.beginPath();
context.arc(100, 100, 50, 0, Math.PI * 2, true);
context.fill();
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>

<body>
  <canvas width=200 height=200 id='canvas'></canvas>
</body>

</html>

截至2017年4月,IE、Opera和Safari不支持此功能。


2
截至2020年7月,Safari仍不支持此功能。 - Crashalot

4

非常有趣。然而,由于我正在使用它作为渲染器(20fps),我想它会变得有点过于复杂和缓慢...但我会尝试一下,谢谢。 - pimvdb
@pimvdb 先将其模糊处理到离屏画布上,然后使用drawImage()将结果绘制到您的画布上。 - Phrogz
8
这是一个更好的、速度非常快的HTML5 Canvas模糊效果代码:StackBlur - Phrogz

1
您可以使用以下函数绘制模糊的圆形:
function drawblurrycircle(context, x, y, radius, blur)
{
     context.shadowBlur = blur;
     context.shadowOffsetX = 0;
     context.shadowOffsetY = 0;

     context.fillStyle="#FF0000";
     context.shadowColor="#FF0000"; //set the shadow colour to that of the fill

     context.beginPath();
     context.arc(x,y,radius,0,Math.PI*2,true);
     context.fill();
     context.stroke();
}

很抱歉,但我已经发布过我尝试了shadowBlur,问题是阴影没有融入圆形。不幸的是,你的解决方案也存在同样的问题。http://jsfiddle.net/r8Kqy/410/ - pimvdb
抱歉!我没有认真阅读你的帖子。为了让它看起来更好,你可以使用一个 for 循环来多次模糊它。 - starbeamrainbowlabs

0

如果您仍然有兴趣使用EaselJS实现此效果,这可能会有所帮助 JSFiddle EaselJS模糊

var stage = new createjs.Stage("test");
var s = new createjs.Shape();
var g = s.graphics;
g.f("#FF0000").dc(0, 0, 75);
s.x = 100;
s.y = 100;
s.filters = [new createjs.BoxBlurFilter(5, 5, 3)];
stage.addChild(s);
s.cache(-100, -100, 200, 200);
s.alpha = 0.5;
stage.update();

也许是因为已经过去了6年,但上面的JSFiddle似乎没有任何作用。 - Graham Lea
1
@GrahamLea 哎呀!你说得对,看看这个 http://jsfiddle.net/s0c9wndh/ 似乎 BoxBlurFilter 在最新版本中不再使用,改用 BlurFilter [code] var stage = new createjs.Stage("test"); var s = new createjs.Shape(); var g = s.graphics; g.f("#FF0000").dc(0, 0, 75); s.x = 100; s.y = 100; s.filters = [new createjs.BlurFilter(5, 5, 3)]; stage.addChild(s); s.cache(-100, -100, 200, 200); s.alpha = 0.5; stage.update(); [/code] - sebastian.derossi

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