Search code examples
jqueryhtmlcsssvgsvg-filters

Apply blur filter to certain area of svg image


I have an quite complex, dynamically created svg image, that has been created using jQuery SVG. I'd like to create a "popup" area that shows on top of all svg elements in the canvas. To create a modern translucent iOS7 like look I'd like to apply a blur filter to everything below the popup area. I want to be able to dynamically set the x,y and also width and height attributes of this popup area.

Have a look at 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>

In this case, everything that is covered by the white area should be blurred. It should then look like this: Example

I have found this, but here a static background image is used, which I don't have. Is there any why to accomplish this effect using svg, css and jQuery?


Solution

  • How about this approach? It's a bit harder to use, but it seems to work on all browsers.

    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>
    

    It is trickier because the filter is applied to the background rather than the <rect>. For it to work, you have to copy the x,y,width and height from the <rect> to the feGaussianBlur primitive.