【问题标题】:How to draw a blurry circle on HTML5 canvas?如何在 HTML5 画布上画一个模糊的圆圈?
【发布时间】:2011-07-25 10:45:58
【问题描述】:

我可以在 HTML5 画布上绘制一个简单的圆圈,但我想在它周围添加一些模糊。

我找到的是this website,它解释了可以在这里派上用场的shadowBlur 属性。

但是,我无法使圆圈本身变得模糊。 shadowBlur 属性的作用基本上是在绘制规则圆之后绘制一些模糊效果。到目前为止,我已经尝试了on jsFiddle

可以看出,它是一个实心圆,周围有一些模糊效果——这两个部分根本没有相互融合。我实际上想要实现的是圆圈本身完全模糊,如下所示:

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

【问题讨论】:

    标签: javascript html canvas geometry blur


    【解决方案1】:

    您可能会发现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 不支持此功能

    【讨论】:

    • 截至 2020 年 7 月,Safari 仍不受支持
    【解决方案2】:

    如果您仍然对使用 EaselJS 完成此效果感兴趣,这可能会有所帮助 JSFiddle EaselJS blur

    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好像没什么作用。
    • @GrahamLea 哎呀!你是对的,看看这个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;阶段.更新(); [/code]
    【解决方案3】:

    您可以使用以下函数绘制一个模糊的圆圈:

    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 的帖子,问题是阴影没有融入cicle。不幸的是,您的解决方案也遇到了同样的问题。 jsfiddle.net/r8Kqy/410
    • 对不起!我没有仔细阅读你的帖子。为了让它看起来更好,您可以使用for 循环多次模糊它
    【解决方案4】:

    我强烈建议不要使用模糊算法,除非您要模糊一些已经存在的复杂绘图。

    对于您的情况,只需绘制一个带有径向渐变的矩形。

      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/

    【讨论】:

    • +1 用于使用 RGBA 在模糊区域中获得适当的透明度。干得好。
    • 但请记住,这不是真正的(高斯)模糊!这种模糊是由带有直边的“锥形”制成的,真实(高斯)模糊看起来会更柔和。您可以通过添加更多 colorStops 来近似它。
    • 这很好。但就我而言,我需要直接使用 imageData 而不是上下文。有什么方法可以通过直接修改imageData来添加模糊圈??
    【解决方案5】:

    您可能可以获得位图像素数组并在其上应用一些模糊算法。例如:http://www.jhlabs.com/ip/blurring.html

    【讨论】:

    • 非常有趣。但是,由于我使用的是渲染器(20fps),我想它会变得有点过于复杂和缓慢......但我会试一试,谢谢。
    • @pimvdb 将其模糊一次到屏幕外画布上,然后使用drawImage() 将结果blit 到您的画布上。
    • 这是为 HTML5 Canvas 编写的更好、更快的模糊效果:StackBlur
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 1970-01-01
    • 2014-08-22
    相关资源
    最近更新 更多