SVG Filter Effects in IE10

Scalable Vector Graphics (SVG) provides Web developers with a declarative, markup-based language for building rich, interactive content as part of their Web sites. With SVG Filter Effects, supported in IE10 in the Windows Developer Preview, developers have a collection of powerful, image-based effects that apply to all SVG elements. Like all Web page content in IE9, SVG Filter effects in IE10 are built with hardware-accelerated rendering, resulting in stunning performance and opening up new opportunities for Web developers to create exciting content for end-users.

SVG filters demo on IE Test Drive site
SVG filters demo on IE Test Drive site

Introduction to SVG Filters

SVG Filter Effects expand the graphic capabilities of the Web. An SVG Filter defines an operation on a graphical input. Just like other HTML elements, filters are declarative in nature and have a supporting DOM for dynamic manipulation. A filter is applied to an SVG element via the filter attribute, in the form of filter="url(#filterId)", or it can be applied as a CSS property filter:url(#filterId). Each filter is composed of one or more filter primitives, which are the basic building blocks for creating nifty effects. Each applies a fundamental effect to a graphic. To form more complex effects, filter primitives can be chained together, feeding the output of one to the input of another. When a filter is applied to an SVG element, that SVG element is used as the source graphic for the filter or the first filter in a chain.

a pink pig   a pig with an SVG filter applied
An image of an SVG pig before (left) applying an SVG filter and after (right) applying an SVG filter

There are 16 different filter primitives. They enable effects ranging from providing light sources to applying matrix transformations to adding a Gaussian blur and much more. SVG Filters make it easy to manipulate and apply Photoshop-like effects to SVG elements. Akin to the rest of SVG, the results are scalable, retaining high quality at any resolution. The filter definition is completely reflected in the DOM as is the original SVG element. Effects can easily be removed by removing the filter attribute. The original, unfiltered image can be attained in this manner. ilter primitives vary widely to cover a large scope of possibilities but there are commonalities between them. Most filter primitives take one or two input parameters. These inputs typically reference the source element, the source element’s alpha channel, or the output of another filter primitive. Having a choice of inputs increases the range of possible effects.

All filter primitives let you specify an identifier for its output so that output can be referenced later. Although filter primitives use the output of the previous filter primitive by default, filter chains don’t have to be completely linear. In fact, more complex filter chains, especially ones that use filter primitives with multiple inputs, often aren’t.

Here’s a simple filter primitive in action:

The feColorMatrix filter primitive applies a matrix transform on the RGBA values of every pixel on the input. A custom matrix can be defined, or a keyword can be used. With it, SVG elements can easily be given a greyscale look or otherwise have their colors altered. Below is an example of the hueRotate keyword being used, and shifting the pixel hues 180 degrees to the opposite side of the color wheel.

<filter id="myHueRotate">

<feColorMatrix type="hueRotate" values="180"/>

</filter>

<g id="myPig" filter="url(#myHueRotate)">

<!-- ... -->

</g>

a pink pig   a green pig
An image of an SVG pig before (left) applying an feColorMatrix filter and after (right) applying the feColorMatrix filter

Examples of Common SVG Filter Primitives

Below is an example of a lighting effect. There are two light filter primitives to choose from: feDiffuseLighting and feSpecularLighting. There are also three light sources available: feDistantLight, fePointLight, and feSpotlight.

<filter id="lighting_filter">

<feDiffuseLighting>

<feSpotLight x="0" y="0" z="50" pointsAtX="300" pointsAtY="300" pointsAtZ="0" limitingConeAngle="20" specularExponent="5"/>

</feDiffuseLighting>

</filter>

 

<g id="myPig" filter="url(#lighting_filter)">

<!-- ... -->

</g>

a pink pig   a black and grey rectangle in a partial silhouette of a pig
An image of an SVG pig before (left) applying an lighting filter and after (right) applying the lighting filter

As you can see, the lighting filter alone produces a greyscale image of a light map. A spotlight filter is located in the upper left hand corner at coordinate (0, 0, 50) and is shining towards the lower right hand corner, creating the grey shape on the black rectangle. The light filter becomes much more useful when it is used in conjunction with another filter:

<filter id="lighting_filter">

<feDiffuseLighting result="result1">

<feSpotLight x="0" y="0" z="50" pointsAtX="300" pointsAtY="300" pointsAtZ="0" limitingConeAngle="20" specularExponent="5"/>

</feDiffuseLighting>

<feComposite operator="arithmetic" k1="1" k2="0" k3="0" k4="0" in="SourceGraphic" in2="result1"/>

</filter>

An feComposite filter primitive is tacked onto the end of the filter chain. You’ll notice that it takes two inputs: SourceGraphic, the original image of the pig to which the filter is applied, and the result of the lighting filter. The feComposite filter primitive performs a compositing operation on the two inputs. It’s very useful for compositing multiple filter primitive outputs together, such as creating a more complex light map from multiple light sources. In this case, the result of the lighting filter is multiplied with the pig graphic, resulting in the below graphic: a spotlight on a pig.

a pink pig covered by a portion of black   a black rectangle with part of a pig visible.
An image of an SVG pig after applying the lighting filter and multiplying it with the original image. Left: transparent background. Right: filter is applied to the SVG pig and a white <rect> behind it.

With the feComposite filter, an ‘over’ compositing operation is easy to achieve. That is, it is easy to the composite the results of several filter primitives on top of each other to form a single image. The <feMerge> element is a key filter primitive, as it achieves this exact behavior – compositing the results of several filter primitives on top of each other. <feMerge> simplifies this process with <feMergeNode> child elements, enabling more than just two filter primitive results to be composited with the ‘over’ operation at a single time.

Another important filter primitive to point out is the feImage filter primitive, as it makes it possible to bring additional images into the filter. It can be used to reference an external image or other svg elements. The image can then be used as an input to another filter primitive.

a pig colored like the sky
An image of an SVG pig after applying a filter that multiplies the image with a photo of the sky

These were just a few examples of SVG filter primitives. A complete list of filter primitives can be found in the SVG Filter Effects specification.

When to Use SVG Filters

First, SVG Filters can be used within image and design tools to make SVG elements more interesting. They can provide a sense of depth or create appearances that are otherwise not possible with SVG. It can also be used to achieve a variety of scenarios outside of illustrating tools.

A commonly desired effect on the Web is the CSS3 text-shadow effect. Although text-shadow doesn’t apply to SVG text, the effect can be replicated using SVG Filters.

<filter id="myShadowFilter">

<feOffset dx="5" dy="5"/>

<feGaussianBlur stdDeviation="3"/>

<feColorMatrix type="matrix" values="0 0 0 0 .2, 0 0 0 0 1, 0 0 0 0 .75, 0 0 0 1 0" result="shadow"/>

<feMerge>

<feMergeNode in="shadow"/>

<feMergeNode in="SourceGraphic"/>

</feMerge>

</filter>

This filter creates a drop shadow effect by taking the pig graphic, offsetting it by 5 units in the x and y directions, applying a Gaussian blur, changing the color of the shadow to a bluish green, then compositing the original pig image with the shadow. It’s easy to create a shadow effect for text or images within SVG.

a pig with the text 'Pig' with a light green shadow
An image of an SVG pig with a shadow effect applied

In addition to adding dimension to SVG’s flatness, the filter effects can easily be applied to raster images by bringing them into an <svg> element via the <image> element. It’s great for client-side, dynamic image effects. Replacing the image with another one is simple. It’s also easy to remove, intensify, or modify a filter effect through the DOM.

a shiny and blurry looking pig
An image of an SVG pig with an Inkscape-generated SVG filter applied

If your browser supports SVG Filters, you can click here to see the light changing on the pig above with a single attribute change:

light1.setAttribute("elevation", currentValue);

The filter attribute is a presentation attribute, which means it can be applied to elements through CSS and has all the benefits of styling through CSS, including being able to apply effects using the hover pseudoselector.

Try Them Now

We continue to improve the SVG Filters implementation in IE10. For example, there is a known issue that filters applied to text within <tspan> or <textPath> elements do not work in the Windows 8 Developer Preview. This is an issue that will be remedied in future builds. You can try out SVG Filters in IE10 now with the Windows Developer Preview and provide your feedback on Connect.

Try the SVG Filter Effects demo on the IE Test Drive site to get a feel for how filters work or read more about it in the IE10 Developer Guide. You can even write your own stack of filter primitives to create a custom effect! Writing complex filters can be a daunting task. Developers familiar with graphics or having a strong background in math might enjoy trying that for yourself. Others may prefer using applications like Inkscape, which have preset SVG Filters that can be toggled and configured. With the right combination of filters, a myriad of desirable effects can be achieved. We look forward to seeing what you build!

—Jennifer Yu, Program Manager, Internet Explorer