Fancier SVG Effects

Though other useful and interesting effects exist within the SVG specification, I’ll illustrate a few of those that seem to be in more widespread usage: gradients; filters: blurring and distortion; masks, transparency and clippaths; reusing objects; and following paths with text or animation. As of September 2005, it appears that Firefox and Opera each support differing subsets of these.

A. Gradients

Basically, a gradient provides a way of filling a shape with a gradual blend between colors. In SVG this blend can be either linear or radial. Because the gradient is rendered by the display device, the gradient remains continuous in appearance regardless of magnification, or export to a different device. Consider the following example:

SVG code illustration
<svg>
<path d="M 20 150 L 260 150 L 140 10 z" 
stroke="black" stroke-width="2" fill="url(#g)" />
<linearGradient id="g">
<stop offset="0" stop-color="#880"/>
<stop offset=".3" stop-color="#ff8"/>
<stop offset=".6" stop-color="#f0f"/>
<stop offset="1" stop-color="#888"/>
</linearGradient> 
</svg>
a linear gradient

Firefox 1.5 - Yes      IE (w/Adobe) - Yes    Opera - Yes


The linear gradient (labeled “g”) defines a gradual transition from yellow-grey (at the start point, denoted by “offset=’0’”) to bright yellow (30 percent of the way across the transition) to magenta (60 percent of the way across) to the final color of grey. The gradient is later applied to a triangular path as a fill pattern through its local XML address using the fill attribute. See http://marble.sru.edu/~ddailey/svg/grademb.html in (5) as an example.

B. filters: blurring and distortion

A wide variety of interesting filters together with ways of combining them and applying them to other graphics allow for some very sophisticated effects. A simple illustration is provided here:

SVG code illustration
<filter id="A">
<feGaussianBlur stdDeviation="8" />
</filter>
<path filter="url(#A)" fill="#0f0" 
d="M 50 120 L 350 120, 200 10 z"/>
a blur filter

Firefox 1.5 - No      IE (w/Adobe) - Yes    Opera - Yes

This illustration draws a very blurry green triangle on the screen. Changing the stdDeviation value to a smaller integer reduces the magnitude of the blur.

C. masks and clippaths

Using clip-paths, masks and composite filters, numerous interesting effects may be produced. The following illustrates that we may combine vector based and raster based images using an ellipse, in this example, to clip a JPEG format image:

Three different  approaches to
clipping an image to a path

<clipPath>

SVG code illustration
<clipPath id="CP">
<ellipse cx="90" cy="65" rx="90" ry="60"/>
</clipPath>
<image xlink:href='../p78.jpg' y="-10"
width="200" height="160" clip-path="url(#CP)"/>

<clipPath>

<mask>

SVG code illustration

<mask id="Ma">
<ellipse cx="100" cy="80" rx="90" ry="70" fill="white"/>
</mask>
<image xlink:href='../p74.jpg' y="-20"
width="200" height="180" mask="url(#Ma)"/>

<mask>
<filter><feImage>
SVG code illustration
<ellipse filter="url(#B)" cx="90" cy="70"
rx="80" ry="60"/>
<filter id="B">
<feImage xlink:href='../thesoul2.jpg'
y="-20" height="200"/>
<feComposite operator="in" in2="SourceGraphic" />
</filter>

<filter><feImage>

D. reusing objects

The <use> tag can be employed to greatly simplify one’s code.

SVG code illustration
<g stroke="black" stroke-width="2" fill="none" >
<ellipse id="g1" cx="100" cy="100" rx="75" ry="40" />
<use xlink:href="#g1" transform="rotate(30 100 100)"/>
<use xlink:href="#g1" transform="rotate(60 100 100)"/>
</g>
re-using an ellipse

Firefox 1.5 - Yes      IE (w/Adobe) - Yes    Opera - Yes

In the above example, one ellipse has been drawn and labeled. The use command re-uses the previous definition applying rotation of 30 and then 60 degrees. The result is three ellipses in increasing rotation about a common center point.

Expanding on the above example, we can draw 24 ellipses, 6 each of colors red, green, blue and yellow and offset with different center points as follows:

SVG code illustration
<g fill="none" stroke="blue">
<g id="ggg">
<g id="g2">
<ellipse id="g1" cx="100" cy="100" rx="75" ry="40"/>
<use xlink:href="#g1" transform="rotate(30 100 100)"/>
<use xlink:href="#g1" transform="rotate(60 100 100)"/>
</g>
<use xlink:href="#g2" transform="rotate(90 100 100)"/>
</g>
</g>
<use xlink:href="#ggg" fill="none" stroke="red"
transform="translate(160,0)"/>
<use xlink:href="#ggg" style="fill:none;stroke:orange"
transform="translate(0,160)"/>
<use xlink:href="#ggg" fill="none" stroke="green"
transform="translate(160,160)"/>
multiple re-uses

Firefox 1.5 - Yes      IE (w/Adobe) - Yes    Opera - Yes

The outermost group tag has been defined with the color of blue so that the subordinate object “ggg” may be reused with its color being independently manipulated later. Note that style="fill:none;stroke:orange" instead of fill="none" stroke="orange" can be used, if one wishes to use CSS approaches.

E. following paths with text or animation

Suppose we draw a path such as shown here, and represented by the SVG code which precedes it:

SVG code illustration
<path d="M 10 150 C 200 80 300 300 350 100" 
stroke="black" fill="none" stroke-width="5" />
a simple path

Firefox 1.5 - Yes      IE (w/Adobe) - Yes    Opera - Yes

It is then quite easy to align text which follows the curve. The text is defined not only inside the <text> tag, but also inside a <textPath> tag as follows:

SVG code illustration
<defs>
<path id="curve" d="M 10 100 C 200 30 300 250 350 50" 
stroke="black" fill="none" stroke-width="5" />
</defs>
<text id="T" font-family="ariel" font-size="16">
<textPath xlink:href="#curve">
Hello, here is some text lying along a bezier curve. 
</textPath>
</text>
text following a simple path

Firefox 1.5 - No      IE (w/Adobe) - Yes    Opera - Yes

In the above code, the path has been defined within a <def> tag so that it may be defined, but not drawn, so that it can later be used in the <textPath>.

Foreshadowing the next topic a bit, the issue of how to animate movement along a curve is somewhat similar to the use of <textPath> that I introduce it here by way of transition into SMIL animation.

The code:

SVG code illustration
<defs>
<path id="curve" d="M 10 100 C 200 30 300 250 350 50" 
stroke="black" fill="none" stroke-width="5" />
</defs>
<ellipse cx="7" cy="-5" rx="20" ry="10" fill="#8888ff" stroke="#44aa88">
<animateMotion dur="2s"
rotate="auto" fill="freeze" repeatCount="indefinite" >
<mpath xlink:href="#curve"/>
</animateMotion>
</ellipse>
animation following a simple path

Firefox 1.5 - No      IE (w/Adobe) - Yes    Opera - Yes

This example uses the same path above (labeled “curve”), but instead, allows a small blue ellipse to traverse that curve every two seconds, keeping its orientation parallel to a tangent to the curve at that point.