代码之家  ›  专栏  ›  技术社区  ›  Dafen

将模糊滤波器应用于svg图像的特定区域

  •  10
  • Dafen  · 技术社区  · 12 年前

    我有一个非常复杂的动态创建的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>
    

    在这种情况下,被白色区域覆盖的所有内容都应该被模糊。然后应该是这样的: Example

    我发现了 this ,但这里使用的是静态背景图像,我没有。 为什么要使用svg、css和jQuery来实现这种效果?

    2 回复  |  直到 9 年前
        1
  •  12
  •   Michael Mullany    12 年前

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

    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>
    

    这更为棘手,因为过滤器应用于背景,而不是 <rect> 。要使其工作,您必须复制 x , y , width height 来自 <矩形> feGaussianBlur 原始的

        2
  •  3
  •   Michael Mullany    10 年前

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

    如果您的背景仅为图像,则有一种解决方法。您编写了一个过滤器,该过滤器使用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>
    

    enter image description here

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