WebReference.com - Scalable Vector Graphics: The Art is in the Code (6/8)
[previous] [next] |
SVG: The Art is in the Code
Filter Effects
Having gone through the basics of creating shapes we can now begin to make the graphics more appealing. In SVG there exists the ability to add effects directly to shapes and text. The best way to think of filters is to think of the filters used by a graphics editing and creation program like Adobe Photoshop or Macromedia Fireworks. In these programs you have the option to apply a Drop Shadow effect or Gaussian Blur effect on a graphic. SVG has the same capabilities, thus bringing with it the same features typically associated with bitmap images (gif, jpg, png, etc).
The available filters are:
- feBlend
- feColorMatrix
- feComponentTransfer
- feComposite
- feConvolveMatrix
- feDiffuseLighting
- feDisplacementMap
- feFlood
- feGaussianBlur
- feImage
- feMerge
- feMorphology
- feOffset
- feSpecularLighting
- feTile
- feTurbalance
In addition to these filters there are also some lighting filters available. These are:
- feDistantLight
- fePointLight
- feSpotLight
Filter effects can consist of any combination of the above. In other words it is possible to use multiple filters on a vector image. It doesn't take a PhD to realize the many possible permutations involved when using filter effects and it is beyond the scope of this tutorial to cover them all. We can, however, gain an appreciation for some of the possibilities by first understanding how to use filter effects and then looking at some examples.
An SVG filter effect must be nested within the <defs>
element. The
<defs>
tag is short for definitions, and, as the name suggests, its purpose is to allow
for the definition of special elements, such as a filter. The filter itself is defined through the
<filter>
tag. A requirement of the filter
tag is that it also must
contain an id
attribute. With SVG filters, the id
attribute is used to
identify which filter will be applied to the graphic. Let's take a look at an example to better
understand these concepts:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"https://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="400" height="400">
<defs>
<filter id="Gaussian_Blur1">
<feGaussianBlur in="SourceGraphic" stdDeviation="2"/>
</filter>
</defs>
<rect x="59" y="77" width="163" height="34"
style="filter:url(#Gaussian_Blur1);fill:rgb(128,128,0);stroke:rgb(128,0,128);stroke-width:5;" />
</svg>
View example 14 in a new window.
In the above example, the filter id
value is set to
Gaussian_Blur1
as demonstrated with this tag: <filter id="Gaussian_Blur1">
.
The purpose of giving a filter a unique id is then to be able to use that same filter repeatedly
on many elements. In other words, the <filter id="Gaussian_Blur1">
acts as a
template that can be repeatedly used throughout a SVG document. To apply the filter to an
element an xlink
is used. An xlink
is just an expression used in SVG that
is the equivalent of a link in HTML e.g., <a href="#">
. In fact
the syntax to link to other files at another url is very similar to HTML and should not present too
many problems:
<a xlink:href="https://dhtmlnirvana.com/"> some stuff would be here </a>
To link the element to a filter, the filter:url(#Gaussian_Blur1);
property is
used. You will note the use of the #
character in the parentheses; this character must be used
when linking back to the filter's id. Linking is an important concept to understand in SVG as it will save
many hours of repetitive coding and development.
The filter effect itself is defined with the
<feGaussianBlur in="SourceGraphic" stdDeviation="2"/>
tag. The fe
prefix
is employed in all filters and is shorthand for filter effect. In this instance, the filter effect
is a Gaussian Blur. The stdDeviation
part of the tag defines the amount of the blur. For
example, having a value of 12 instead of 2 dramatically increases the blur effect. The
in="SourceGraphic"
part defines whether the effect is created from the whole image, or an
alternative would be to use SourceAlpha
, which creates the affect from a single alpha
channel of the image. These are the only two options available for the in
property, except
in the instance of result outputs, which will be explained shortly. All filters work on the same
underlying principles.
Valid Gaussian Blur Attributes:
- stdDeviation: The standard deviation is used to define the amount of the blur to be applied to elements. If two numbers are provided, the first number represents a standard deviation value along the x-axis and the second value represents a standard deviation along the y-axis. If one number is provided, then that value is used for both x and y.
I mentioned earlier that multiple filters can be applied to a SVG image. To better understand this concept, let us take a look at a turbulence effect.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"https://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="100%" height="100%">
<defs>
<filter id="Turbulence">
<feTurbulence baseFrequency="0.03 0.02" numOctaves="2" type="turbulence" result="turbulenceOutput"/>
<feComposite in="turbulenceOutput" in2="SourceAlpha" operator="in"/>
</filter>
</defs>
<path
d="M193.1 79.292 C224.16 88.7968 242.127 121.499 232.627 154.414 C223.127 187.328 239.995 220.003 271.913 229.504 C303.83 239.006 336.35 218.61 345 188.876 C323.124 264.909 248.755 285.576 198.994 270.349 C149.231 255.12 98.1789 196.096 120.144 119.992 C129.376 88.0081 162.039 69.7869 193.1 79.292 zM167.341 136.242 C167.341 141.144 170.673 145.311 176.03 145.311 C181.386 145.311 184.242 140.899 184.242 136.242 C184.242 131.584 180.796 127.762 175.91 127.785 C171.025 127.809 167.341 131.339 167.341 136.242 z"
style="fill:rgb(192,192,255);stroke:rgb(130,0,61);stroke-width:1;filter:url(#Turbulence);" />
</svg>
View example 15 in a new window.
In the above example, two filter effects are applied. The feTurbulence
filter
and the feComposite
filter. A very important concept is that filters can be nested
within each other through the use of the result
and the in
attributes. For
example, on the turbulence filter we have used result="turbulenceOutput"
. In practice the
result is an output, similar to a dynamically named element which can then be accessed by other filters.
To hook back into that filter from another filter, we use in="turbulenceOutput"
. An intuitive
linking mechanism even if I do say so myself!
Because the in
attribute has now been used, we need to create another
in
attribute. SVG provides the in2
attribute designed for this purpose and
demonstrated here: in2="SourceAlpha"
, which allows us to define a single channel for this
filter. The operator
attribute is specific to the composite
effect (see table
below) and designates what type of composition should occur: operator="in"
. To better
understand this last concept remove the operator="in"
from the above code.
Each filter has a set of attributes where values for that attribute can be altered to create different effects.
Frequency Attributes:
baseFrequency
: The base frequency controls the frequency of the noise function. If two numbers are provided, the first number represents a standard deviation value along the x-axis and the second value represents a standard deviation along the y-axis. If one number is provided, then that value is used for both x and y.numOctaves
: ThenumOctaves
parameter for the noise function. An octave is an interval between 1-8. If the attribute is not specified, then a value of 1 is used.seed
: The starting number for the pseudo random number generator. If the attribute is not specified, then the effect is as if a value of 0 were specified.StitchTiles
: IfstitchTiles="noStitch"
, no attempt is made to achieve smooth transitions at the border of tiles which contain a turbulence function. IfstitchTiles="stitch"
, then an attempt is made to achieve a smooth transition at the border of tiles.Type
: Indicates whether the filter primitive should perform a noise or turbulence function.
Composite Attributes
Operator
: Designates what type of composition should occur. Valid values areover
,in
,out
,atop
,xor
,arithmetic
.k1
: Only applicable ifoperator="arithmetic"
. Any numeric value is valid. If the attribute is not specified then a value of "0" will be employed.k2
: Only applicable ifoperator="arithmetic"
. Any numeric value is valid. If the attribute is not specified then a value of "0" will be employed.k3
: Only applicable ifoperator="arithmetic"
. Any numeric value is valid. If the attribute is not specified then a value of "0" will be employed.k4
: Only applicable ifoperator="arithmetic"
. Any numeric value is valid. If the attribute is not specified then a value of "0" will be employed.in2
: The second input image to the compositing operation. This attribute can take on the same values as thein
attribute.
Let's take a look at a couple of other filter effects just to demonstrate the myriad of
possibilities that exist with SVG. In the next example, we create a dilation effect by using the
morphology
filter.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"https://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="100%" height="100%">
<defs>
<filter id="Dilate">
<feMorphology in="SourceGraphic" radius="5" operator="dilate"/>
</filter>
</defs>
<path
d="M258.642 285 C274.9 262.728 343 228.266 343 192.613 C343 130.896 272.069 145.581 257.993 169.957 C243.041 144.832 174 134.805 174 192.613 C174 229.135 244.429 262.911 258.642 285 z"
style="fill:rgb(198,38,38);stroke:rgb(0,0,128);stroke-width:1;filter:url(#Dilate)"/>
</svg>
View example 16 in a new window.
To finish of this section on filters lets apply a number of different filters including some lighting effects to create a metallic looking element.
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"https://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="100%" height="100%">
<defs>
<filter id="metallic">
<feGaussianBlur result="blurredAlpha" in="SourceAlpha" stdDeviation="3"/>
<feOffset result="offsetBlurredAlpha" in="blurredAlpha" dx="2" dy="1"/>
<feDiffuseLighting result="bumpMapDiffuse" in="blurredAlpha" surfaceScale="5" diffuseConstant="0.5" style="lighting-color:rgb(255,255,255)">
<feDistantLight azimuth="135" elevation="60"/>
</feDiffuseLighting>
<feComposite result="litPaint" in="bumpMapDiffuse" operator="arithmetic" k1="1" k2="0" k3="0" k4="0" in2="SourceGraphic"/>
<feSpecularLighting result="bumpMapSpecular" in="blurredAlpha" surfaceScale="5" specularConstant="0.5" specularExponent="10" style="lighting-color:rgb(255,255,255)">
<feDistantLight azimuth="135" elevation="60"/>
</feSpecularLighting>
<feComposite result="litPaint" in="litPaint" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" in2="bumpMapSpecular"/>
<feComposite result="litPaint" in="litPaint" operator="in" in2="SourceAlpha"/>
<feMerge>
<feMergeNode in="offsetBlurredAlpha"/>
<feMergeNode in="litPaint"/>
</feMerge>
</filter>
</defs>
<path
d="M233.642 288 C249.9 265.728 318 231.266 318 195.613 C318 133.896 247.069 148.581 232.993 172.957 C218.041 147.832 149 137.805 149 195.613 C149 232.135 219.429 265.911 233.642 288 z"
style="filter:url(#metallic);fill:rgb(198,38,38);stroke:rgb(11,11,13);stroke-width:1;" />
</svg>
View example 17 in a new window.
Now that's a bit of code to digest! What's important here, is to not get overwhelmed by
the code but take it one filter at a time so to speak. For example, let's take the feOffset
filter. A good way to learn about this filter is to go to the W3C
and look up all the attributes associated with it and then play with it to gain an appreciation of what
they all do. Then take the next filter and do exactly the same thing.
[previous] [next] |
Created: November 21, 2001
Revised: November 21, 2001
URL: https://webreference.com/authoring/languages/svg/intro/6.html