
SVG and Typography: Bells and Whistles
by Fabio Arciniegas A.
June 02, 2004
In this installment of our discussion of SVG and typography, we make a
departure from the sobriety of the typographic strategies we've been
discussing so far and go for the other half of the fun: the bells and
whistles of effects, distortions, coloring, and other unusual
treatments of type.
We will create reusable code (basically a cookbook) of common
typographic treatments implemented in SVG. The idea is to recreate
some of the most famous effects you would expect from a design book in
SVG:
- Blur
- Outer Shadow
- Image within Type
- Type within Image
- Stroke
- Dilate
- Bevel
- Gradients
- Spacing
- Skew
- Mixing
This article is intended as a little arsenal of typographic
treatments implemented in SVG, not as a tutorial on filters, which is
something I will do in future columns. However, for some techniques we
take the opportunity to briefly discuss some relevant aspect of SVG
style and syntax.
Blur
Figure 1. Blur
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" version="1.1">
<defs>
<filter id="blur" x="0" y="0" width="150" height="150">
<feGaussianBlur in="SourceGraphic" stdDeviation="2" />
</filter>
</defs>
<rect x="0" y="0" width="150" height="150" style="fill:#F1B813;" />
<text filter="url(#blur)"
x="40" y="85"
style="font-family:Arial; font-size: 30pt; fill:red;">blur</text>
</svg>
Listing 1. blur.svg
Blur is a good starting point because it is based on just one
primitive filter, predefined in SVG. As you can see from the code
above, we define filters inside the defs element. Inside each
filter we can define series of operations and their combinations; in
our case we are doing only one operation, a gaussian blur identified
by the primitive feGaussianBlur.
Then, on the text element itself, we apply the defined filter by
providing its location as the value of the filter
attribute. Note that because of the way they are defined, in order to
use any of the effects in this page all you have to do is copy and
paste its definition in your document.
Drop Shadow
Figure 2. Drop Shadow
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="150" version="1.1">
<defs>
<filter id="dropShadow" x="0" y="0" width="150" height="150">
<feOffset in="SourceGraphic" dx="0" dy="0" result="topCopy" />
<feGaussianBlur in="SourceAlpha" stdDeviation="2" result="shadow" />
<feOffset in="shadow" dx="3" dy="3" result="movedShadow" />
<feMerge>
<feMergeNode in="topCopy" />
<feMergeNode in="movedShadow" />
</feMerge>
</filter>
</defs>
<g filter="url(#dropShadow)" >
<text x="10" y="45"
style="font-family:Verdana; font-size: 20pt; fill:green;">Shadows</text>
<text x="10" y="65"
style="font-family:Verdana; font-size: 20pt; fill:green;">and</text>
<text x="10" y="85"
style="font-family:Verdana; font-size: 20pt; fill:green;">Tall Trees</text>
</g>
</svg>
Listing 2. outershadow.svg
For the drop shadow effect we use a slightly more elaborate
filter. This time we use three operations: first we create a copy of
the source graphic, then we blur the source, and then we move the
result of the blur 3 pixels to the right and 3 pixels down.
Note that in order to specify the result of a primitive as
the input of another we use the result and in
attributes.
At the end of the description of our filter we merge the
two layers (copy and shadow) to create the final output. Finally, the
filter can be applied not only to individual elements but also to
groups.
Type Within Image
For the type-within-image effect we use a mask, not a filter. Masks
allow you to define a region through which other elements are
visible.
Figure 3. type within Image
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="300" height="300" version="1.1">
<defs>
<mask id="star">
<polygon points="155.5,45.6146 181.334,119.935 260,121.538 197.3,169.074
220.085,244.385 155.5,199.444 90.9154,244.385 113.7,169.074
51,121.538 129.666,119.935"
transform="matrix(1 0 0 1.04643 1.9873e-014 -6.73254)
translate(-52.381 -37.9218)"
style="fill:rgb(255,255,255);stroke:rgb(0,0,0);stroke-width:1" />
</mask>
</defs>
<g mask="url(#star)" style="font-family:Verdana; font-size: 10pt; fill:red;">
<text x="80" y="80"
style="font-size:24pt; fill:pink;">the</text>
<text x="0" y="130"
style="font-size: 60pt; fill:pink;">Girlie</text>
<text x="20" y="190"
style="font-size: 60pt; fill:pink;">Show</text>
<g>
<text x="30" y="20" >Bye bye baby bye bye</text>
<!-- other text -->
</g>
</svg>
Listing 3. typeinimage.svg
As you can see, in the defs element we define a mask, in
this case a polygon (the star). We give it a name which we use later
on in the g element to refer to the mask.
[1] [2] [3] Next