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
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.
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>
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>
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.
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.
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.
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.
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