【问题标题】:Apply blur filter to certain area of svg image将模糊滤镜应用于 svg 图像的特定区域
【发布时间】:2013-10-21 08:09:11
【问题描述】:

我有一个非常复杂的动态创建的 svg 图像,它是使用 jQuery SVG 创建的。我想创建一个“弹出”区域,显示在画布中所有 svg 元素的顶部。为了创建一个现代的半透明 iOS7 外观,我想对弹出区域下方的所有内容应用模糊过滤器。我希望能够动态设置此弹出区域的 x、y 以及宽度和高度属性。

看看this example:

<svg width="500" height="500">
    <rect x="10" y="10" height="235" width="235" fill="red" />
    <rect x="255" y="10" height="235" width="235" fill="green" />
    <rect x="10" y="255" height="235" width="235" fill="blue" />
    <rect x="255" y="255" height="235" width="235" fill="yellow" />

    <rect x="50" y="50" height="400" width="400" fill="rgba(255,255,255,0.8)" />
</svg>

在这种情况下,所有被白色区域覆盖的东西都应该被模糊掉。然后它应该看起来像这样:

我找到了this,但这里使用的是静态背景图片,我没有。 有什么理由用svg、css和jQuery来完成这个效果吗?

【问题讨论】:

    标签: jquery html css svg svg-filters


    【解决方案1】:

    这种方法怎么样?它使用起来有点困难,但它似乎适用于所有浏览器。

    http://jsfiddle.net/J3X4p/2/

    <svg x="0px" y="0px" width="500px" height="500px" viewbox="0 0 500 500">
      <defs>
        <filter id="blurry" x="0%" y="0%" height="100%" width="100%" primitiveUnits="userSpaceOnUse">
          <feGaussianBlur x="50" y="50" width="400" height="400" stdDeviation="40" in="SourceGraphic" result="blurSquares"/>
          <feComponentTransfer in="blurSquares" result="opaqueBlur">
            <feFuncA type="linear" intercept="1"/>
          </feComponentTransfer>
          <feBlend mode="normal" in="opaqueBlur" in2="SourceGraphic"/>
        </filter>
      </defs>
    
      <g id="squares" filter="url(#blurry)">
        <rect x="10" y="10" height="235" width="235" fill="red" />
        <rect x="255" y="10" height="235" width="235" fill="green" />
        <rect x="10" y="255" height="235" width="235" fill="blue" />
        <rect x="255" y="255" height="235" width="235" fill="yellow" />
      </g>
    
        <rect x="50" y="50" height="400" width="400" fill="rgb(255,255,255)" fill-opacity="0.8" />
    </svg>
    

    这比较棘手,因为过滤器应用于背景而不是&lt;rect&gt;。要使其工作,您必须将xywidthheight&lt;rect&gt; 复制到feGaussianBlur 原语。

    【讨论】:

    • 嘿太棒了!这很好用!非常感谢你,我的团队会对这个结果感到非常满意! =)
    • 只是另一个问题:如果过滤器下面没有元素,它就会变成黑色。有没有办法使用 svg 元素背后的背景? (css background-image 设置为 html 标签)如果没有,我将尝试在过滤器下显示 html 背景图像的副本,但在其他 svg 元素上方。
    • 仅当浏览器支持 enable-background 和 BackgroundImage 时。但大多数人都没有,正如迈克尔已经指出的那样。如果他们这样做了,您将使用他的解决方案而不是我的解决方案。
    【解决方案2】:

    这只有在单个浏览器(Internet Explorer 10)中使用内联 SVG 才能直接实现——您使用“启用背景”属性并使用内置的“背景图像”源。这是您链接到的教程文本中显示的方法。

    如果您的背景完全是图像,则有一种解决方法。您编写了一个过滤器,该过滤器使用 feImage 过滤器拉入背景中的相同图像,对它们进行模糊处理,然后将模糊合成到您想要在顶部显示的任何内容下。这是您链接到的教程的实际代码中使用的方法。

    如果您的背景是其他 SVG 内容(文本、路径等),则没有跨浏览器的方式来实现您的效果,因为 Firefox 不支持将 SVG 对象作为 feImage 过滤器原语的输入。如果您不关心 Firefox,则可以使用该教程用于图像的相同解决方法。

    这是后者的一个例子 - 它非常接近你想要的,但我只在 Chrome/Windows 中测试过它(我知道它在 Firefox 中不起作用)

    <svg x="0px" y="0px" width="500px" height="500px" viewbox="0 0 500 500">
      <defs>
        <filter id="blurry" x="-20%" y="-20%" height="140%" width="140%" primitiveUnits="userSpaceOnUse">
          <feImage x="0" y="0" width="500" height="500" xlink:href="#squares" result="mySquares"/>
          <feGaussianBlur stdDeviation="40" in="mySquares" result="blurSquares"/>
          <feComponentTransfer in="blurSquares" result="morealpha">
            <feFuncA type="linear" intercept=".8"/>
          </feComponentTransfer>
          <feComposite operator="in" in="morealpha" in2="SourceGraphic" result="clipBlur"/>
          <feFlood x="10%" y="10%" width="80%" height="80%" flood-color="white" flood-opacity="0.6" result="whitesquare"/>
          <feBlend mode="screen" in="clipBlur" in2="whitesquare"/>
        </filter>
      </defs>
    
      <g id="squares">
        <rect x="10" y="10" height="235" width="235" fill="red" />
        <rect x="255" y="10" height="235" width="235" fill="green" />
        <rect x="10" y="255" height="235" width="235" fill="blue" />
        <rect x="255" y="255" height="235" width="235" fill="yellow" />
      </g>
    
        <rect filter="url(#blurry)" x="50" y="50" height="400" width="400" fill="rgb(255,255,255)" />
    </svg>
    

    更新: 最近的发现 - 您可以使用 javascript 将您想要提供给 feImage 的任何内容编码为 svg+xml 编码数据 URI - 然后跨浏览器工作。超级丑陋。)

    【讨论】:

    • 感谢您的回答!我使用 BigBadaboom 方法,因为 Firefox 对我们来说非常重要。 =)
    猜你喜欢
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 2014-11-21
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    相关资源
    最近更新 更多