如何使用SVG在矩形周围创建“发光”效果?

32

我有一个类似以下结构的东西:

<svg id="svgLogo1" style="left:0; top:0; position:absolute"
        width="980" height="80" viewBox="0 0 980 80" 
        xmlns="http://www.w3.org/2000/svg">
    <rect x="0" y="5" width="980" height="54" rx="6" ry="6" 
            style="stroke-width:2; xstroke:#FFF; fill:#555"/>
</svg>
我想在这个矩形周围创建一个白色的发光效果。
是否可以用SVG实现这个效果?我查找了一些资料,但是只找到了“shadow”的效果,这并不是我要寻找的,因为我希望矩形的四周都有一个阴影(发光)。

你是否可以添加两个阴影选项?一个用于右侧和底部,另一个用于顶部和左侧? - Matijs
https://dev59.com/r2025IYBdhLWcg3wT0Hq - Dagg Nabbit
感谢您的建议。问题在于我不知道如何创建白色阴影。我在创建黑色方面取得了很多成功,但在白色方面却没有。 - Jessica
没有 x、y 偏移的阴影看起来像是发光... - Alnitak
4个回答

62

这里有一些提供不同类型效果的滤镜:

  • 投影 (带有轻微偏移的透明黑色阴影)
  • 黑色辉光(固定颜色)
  • 物体颜色辉光(采用所应用对象的颜色)

示例:

这里有一个演示

代码:

<!-- a transparent grey drop-shadow that blends with the background colour -->
<filter id="shadow" width="1.5" height="1.5" x="-.25" y="-.25">
    <feGaussianBlur in="SourceAlpha" stdDeviation="2.5" result="blur"/>
    <feColorMatrix result="bluralpha" type="matrix" values=
            "1 0 0 0   0
             0 1 0 0   0
             0 0 1 0   0
             0 0 0 0.4 0 "/>
    <feOffset in="bluralpha" dx="3" dy="3" result="offsetBlur"/>
    <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="SourceGraphic"/>
    </feMerge>
</filter>

<!-- a transparent grey glow with no offset -->
<filter id="black-glow">
    <feColorMatrix type="matrix" values=
                "0 0 0 0   0
                 0 0 0 0   0
                 0 0 0 0   0
                 0 0 0 0.7 0"/>
    <feGaussianBlur stdDeviation="2.5" result="coloredBlur"/>
    <feMerge>
        <feMergeNode in="coloredBlur"/>
        <feMergeNode in="SourceGraphic"/>
    </feMerge>
</filter>

<!-- a transparent glow that takes on the colour of the object it's applied to -->
<filter id="glow">
    <feGaussianBlur stdDeviation="2.5" result="coloredBlur"/>
    <feMerge>
        <feMergeNode in="coloredBlur"/>
        <feMergeNode in="SourceGraphic"/>
    </feMerge>
</filter>

1
透明的光芒会呈现出所应用对象的颜色。有着霓虹灯般的氛围。这对我来说是完美的发光效果。谢谢! - mihca

19

颜色矩阵实际上不能用来让物体发出不同颜色的光,只能以某种方式转换现有的颜色。

但我们可以尝试做另外一件事情...

<filter id="white-glow">
    <feFlood result="flood" flood-color="#ffffff" flood-opacity="1"></feFlood>
    <feComposite in="flood" result="mask" in2="SourceGraphic" operator="in"></feComposite>
    <feMorphology in="mask" result="dilated" operator="dilate" radius="2"></feMorphology>
    <feGaussianBlur in="dilated" result="blurred" stdDeviation="5"></feGaussianBlur>
    <feMerge>
        <feMergeNode in="blurred"></feMergeNode>
        <feMergeNode in="SourceGraphic"></feMergeNode>
    </feMerge>
</filter>

请看我创建的这个代码片段,基于Drew的答案

以下是滤镜的作用:

  • 将泛洪效果与源图像组合以填色(使用feFloodfeComposite)。
  • 稍微扩展这个已着色的对象(使用operator="dilate"feMorphology
  • 应用旧有的模糊效果使其发光!(feGaussianBlur
  • 将这个着色、扩展、发光的对象放在源图像下方(feMerge

如果矩形的填充使用了像"rgba(3,3,3,0.9)"这样的alpha通道,阴影会修改矩形的颜色。有没有办法可以避免这种情况? - user3526
1
你可以添加另一个 'feComposite' 步骤,以消除原始对象下面的任何发光像素。我为你准备了一个 fiddle :) https://jsfiddle.net/4nz8o1p8/ - Jack
将鼠标悬停在那个小工具上以应用发光效果-您会发现它们的颜色不会改变 :) - Jack
尽管如此,额外的“feComposite”在Firefox和Safari中似乎无法工作。 - user3526
啊,那真是烦人!恐怕我不知道该如何修复它 :/ - Jack

8

试试这个:

<svg id="svgLogo1" style="left: 0px; top: 0px;
  position: absolute;" width="980" height="80" viewBox="0 0 980 80"
  xmlns="http://www.w3.org/2000/svg" version="1.1" >
    <defs>
        <filter id="dropGlow" width="1.5" height="1.5" x="-.25" y="-.25">
            <feGaussianBlur id="feGaussianBlur5384" in="SourceAlpha" stdDeviation="15.000000" result="blur"/>
            <feColorMatrix id="feColorMatrix5386" result="bluralpha" type="matrix" values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 0.800000 0 "/>
            <feOffset id="feOffset5388" in="bluralpha" dx="0.000000" dy="0.000000" result="offsetBlur"/>
            <feMerge id="feMerge5390">
                <feMergeNode id="feMergeNode5392" in="offsetBlur"/>
                <feMergeNode id="feMergeNode5394" in="SourceGraphic"/>
            </feMerge>
        </filter>
    </defs>
    <rect x="0" y="5" width="980" height="54" rx="6" ry="6"
        style="stroke-width: 2; xstroke: #FFFFFF; fill: #555555; filter:url(#dropGlow)"/>
</svg>

我在Inkscape中创建了原始过滤器,但无论应用到什么地方都能很好地发挥作用。


3
谢谢您提到Inkscape。我尝试了提供的SVG文件,但它无法正常工作。 - Lzh

1

如果您正在使用模糊滤镜,请小心谨慎。特别是模糊可能会消耗大量的CPU资源,因此也可能更快地消耗电池。使用工具(例如OS X活动监视器)观察您的滤镜效果,特别是涉及动画或视频时。


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