Code and Stuff

Jan 16, 2013

Miniature Effect with single SVG Filter (Firefox)

In a previous attempt to create a minuature filter for firefox I used multiple DIVs each showing a different level of blur. This works fine, especially if Webkit support is needed, but it is a little complicated to implement when needed multiple times.

When firefox support alone is ok, the whole effect can be implemented in one single SVG filter. We just have to combine the correct ones.

This new implementation uses merging of multiple filter steps. Currently this only works in Firefox. The filter is:

<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
  <filter id="svgFilter3153195357290276084">
    <feGaussianBlur y="0" height="100%" in="SourceGraphic" stdDeviation="8" result="b1"/>
    <feGaussianBlur y="5%" height="90%" in="SourceGraphic" stdDeviation="7" result="b2"/>
    <feGaussianBlur y="10%" height="80%" in="SourceGraphic" stdDeviation="6" result="b3"/>
    <feGaussianBlur y="15%" height="70%" in="SourceGraphic" stdDeviation="5" result="b4"/>
    <feGaussianBlur y="20%" height="60%" in="SourceGraphic" stdDeviation="4" result="b5"/>
    <feGaussianBlur y="25%" height="50%" in="SourceGraphic" stdDeviation="3" result="b6"/>
    <feGaussianBlur y="30%" height="40%" in="SourceGraphic" stdDeviation="2" result="b7"/>
    <feGaussianBlur y="35%" height="30%" in="SourceGraphic" stdDeviation="1" result="b8"/>
    <feGaussianBlur y="40%" height="20%" in="SourceGraphic" stdDeviation="0" result="b9"/>
    <!-- the center needs to be unblurred (identity component transfer) -->
    <feComponentTransfer x="0" y="45%" width="100%" height="10%" in="SourceGraphic" result="a"/>

    <feMerge x="0" y="0" width="100%" height="100%" >
      <feMergeNode in="SourceGraphic"/>
      <feMergeNode in="b1"/>
      <feMergeNode in="b2"/>
      <feMergeNode in="b3"/>
      <feMergeNode in="b4"/>
      <feMergeNode in="b5"/>
      <feMergeNode in="b6"/>
      <feMergeNode in="b7"/>
      <feMergeNode in="b8"/>
      <feMergeNode in="b9"/>
      <feMergeNode in="a"/>
    </feMerge>
  </filter>
</svg>

In the first part of the filter a set of 8 gaussian blurs, of always smaller section of the source image, are created. In the second one, they are composed with the simple alpha composition.

As in the original post the filter is applied using CSS with something like:

img, video {
   filter: url(#filterId);
}
This time there is no need for a container DIV nor a positioning one. The filter can be applied to any DOM element.

No comments: