CSS3滤镜:drop-shadow spread属性的替代方案

10

我正在尝试使用CSS3(webkit)drop-shadow过滤器在任何给定的透明PNG周围放置白色光晕,并且-webkit-filter: drop-shadow(0px 0px 22px rgba(255,255,255,0.8));对于实心图像效果非常好。但是问题在于,它会严重破坏主要为文本的图像。所有阴影混合在一起,而不是创建正确的紧密光晕效果。

输入图片描述

我需要能够使用spread而不是blur,以便阴影不仅成为某些文本后面的大型斑点,但显然,尽管标准说您应该能够指定spread属性,但仍然无法做到

我听说SVG投影滤镜可用于实现与drop-shadow相同的效果(事实上必须在Firefox中使用),但我还没有找到一种可以将spread属性应用于其的方法。

如果有的话,这个问题存在什么解决办法?


1
我建议不要使用图像来代替文本。使用实际的文本,然后使用text-shadow。这对于SEO也很有好处。 - Paulie_D
1
我需要为相当复杂的标志应用这些投影效果,通常是由几种不同字体组合而成,有时还会叠加其他图像。虽然重新在HTML中创建它们会更好,但这并不是一个选项。只是将阴影嵌入png文件中(尽管这是我的第一反应)也不是一个选项。 - rw-nandemo
我写了一个 CodePen 工具,以帮助人们使用 SVG 滤镜进行高级阴影操作 - 尽情享用 http://codepen.io/mullany/details/sJopz/ - Michael Mullany
实际上,这还不是标准的一部分,https://www.w3.org/TR/filter-effects-1/#funcdef-drop-shadow 请注意,此规范级别不接受扩展值或多个阴影。 - freeforall tousez
4个回答

11

另一种实现扩散感的方法是使用多个投影滤镜。

filter:  
  drop-shadow(1px 1px 2px white)
  drop-shadow(-1px -1px 2px white)
  drop-shadow(1px -1px 2px white)
  drop-shadow(-1px 1px 2px white)
  drop-shadow(1px 0px 2px white) 
  drop-shadow(-1px 0px 2px white)  
  drop-shadow(0px 1px 2px white) 
  drop-shadow(0px -1px 2px white);

这将导致硬的白色边框和普通柔和的阴影在其后面。叠加更多相同颜色可以产生期望的结果,就像原始问题一样。

White border using multiple dropshadows


这对于文本来说并不一定有效,但是它是展开属性的一个很好的替代品。请注意,每个过滤器必须用空格分隔,而不是逗号,不像box-shadow属性。我使用多个相同的投影来创建较重的阴影,但是您也可以将每个投影向上,向下,向左或向右偏移相同的量:5px 0-5px 00 5px0 -5px以获得更真实的展开效果。 - user5670895
我最终采用了这种方法,但由于过多地使用过滤器而遇到了性能问题。我通过另一个问题的这个答案解决了这些问题:https://dev59.com/KF0b5IYBdhLWcg3wJ-Uz#29577985 - Chris Newman

8

好的,我找到了用SVG滤镜替换非功能性传播属性的方法。非常感谢Michael Mullany的帮助,尽管他的答案并不完全符合我的需求。这是我使用的滤镜:

<filter id="drop-shadow">
    <feMorphology operator="dilate" radius="6" in="SourceAlpha" result="dilated"/>

    <feGaussianBlur stdDeviation="3" in="dilated" result="blurred"/>

    <feFlood flood-color="rgba(255,255,255,0.5)" in="blurred" result="flooded"/>

    <feMerge>
        <feMergeNode/>
        <feMergeNode in="SourceGraphic"/>
    </feMerge>
</filter>

feMorphology膨胀算子非常好地复制了我想要的功能,使得更容易给文本添加“发光”效果,并且更加严格地符合文本的轮廓。

enter image description here

(奇怪的是,feFlood什么都没有做,而且我无法得到白色的发光效果,但这是另一个问题。当它在最新版Chrome浏览器的标签页中打开时,滤镜会占用100%的单个核心。哦,好吧。)


3

是的,您可以使用SVG滤镜来自定义阴影扩散:

  <filter id="f1" x="-20%" y="-20%" width="160%" height="160%">
    <feGaussianBlur in="SourceAlpha" result="blurOut" stdDeviation="8"/>
    <feOffset in="blurOut" result="dropBlur" dx="0" dy="0"/>

  <feComponentTransfer in="dropBlur" result="dropBlur2">
    <feFuncA id="alphaFunc" type="gamma" amplitude="2" exponent="1.5" offset="0"/>
  </feComponentTransfer>

    <feComposite operator="over" 
     in="SourceGraphic" in2="dropBlur2"/>
</filter>

交互演示在这里:http://codepen.io/mullany/pen/sJopz

这对我正在尝试做的事情非常有帮助,但是你的链接出现了404错误:( - Anna
链接现在可用。 - Michael Mullany

0

在文本上添加阴影(使用22px)永远不会看起来很好,因为文本和字母间距更接近。如果要使用文本,应该使用text-shadow(或者也可以尝试使用text-stroke,请参见我的演示):

http://jsfiddle.net/fHzX7/


我很想这样做,但是我提供的图像只是使用简单文本作为占位符。实际上,“大部分文本图像”是复杂的标志,我无法轻松地重新创建它们。 - rw-nandemo
使用更小的距离怎么样(例如drop-shadow(0px 0px 5px white)而不是drop-shadow(0px 0px 22px white))?否则这是不可能的。有backface-visibility:hidden,但这只在Firefox中(对于drop-shadow)有效(正确)。 - Paranoia
我明白了。我想目前看起来并不是非常糟糕,但我确实希望能找到一些方法来强制实现类似于spread的属性。无论如何,谢谢你的帮助。 - rw-nandemo

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