SVG and Typography: Animation
June 30, 2004
In the last part of our exploration of SVG and Typography, we turn our attention to effects with animated type, exploiting SVG declarative animation features.

Instead of just using individual samples showcasing each technique, I decided to finish these series with a summarizing work. I recommend that before we start you take a look of the whole animation here.
As we create the animation piece by piece, we will explore the following techniques, a basic canon of type animation for the Web:
- Animating color
- Animating opacity
- Animating position and size
- Animating through a path
- Other elements
The central piece is based on a Westvaco Illustrations work by designer visionary Bradbury Thompson, a remarkable man who preferred not to make empty praise of an idea, but rather make sure every opinion was expressed through compelling work, making the idea's value evident by itself, not by adjectives attached to it.
I hope some of Thompson's pragmatism is reflected in this series. It is certainly needed when technologies like SVG are artificially inflated by adjectives ("paradigm-shifting-ground-breaking-replaces-your-dog-and-then-some"), which is a certain recipe for disappointment.
Animating Color
In
the very beginning of our animation we animate the color and opacity of the title
"SVG
and Type: Animation" to make it blend with the background. In order to give a subtle
complexity to the animation, we mix two different techiques: The word "and" varies
from a light gray (#797979) to a final, darker gray (#888888), while the rest of the
title
just changes its opacity from 1 (100%) to 0.
Varying the color of text over time is a simple process that can be achieved by including
an animate
sub-element of the text (or tspan) element as shown in Listing 1.
Attributes are truly self-documenting: the animation takes one second, starts one
second
after the element with id "startmeup" is clicked, and varies the attribute
fill
(which as you remember from installment 1 of this series controls color
of the text). The values used are the two grays needed.
<tspan style="font-size:40;fill:#797979">and <animate attributeName='fill' values='#797979;#888888' dur='1s' fill='freeze' begin="startmeup.click+1"/> </tspan"
Listing 1. Animating Color
Note that the values
element could contain any number of steps, or
intermediate colors, and the SVG interpreter would cycle through them; for example,
it could
have been values='#797979;#08FF21;#FF0000;#FFFF13'
to make a rainbowy effect.
However, it is important to keep in mind that just because it is easy to do, it doesn't
necessarily mean it is a good idea. As with so many things, when animating color,
subtlety
is best most of the time.
All animate attributes are straight-forward except perhaps for the fill
attribute. Note this does not refer to the fill of the SVG (color) element but to
what
happens once the duration of the animation is over. By specifying the freeze
value, we declare the last stage of the animation is held and visible (i.e. the animation
simply stops at the end, instead of dissapearing or restarting).
Animating Opacity
Animating opacity is just as simple as animating color or any value of an SVG element
for
that matter: include an animate
element, specify the attribute/CSS property you
want to animate on the parent, and specify your stop values. See Listing 2.
<text x="400" y="274" style="font-size:72;fill:#CCCCCC">SVG <animate attributeName='opacity' values='1;0' dur='1s' fill='freeze' begin="startmeup.click"/> </text>
Listing 2. Animating Opacity
We can use this technique to animate not only an element (the text) but a complex
group of
objects (e.g one of our fishes), as shown in Listing 3. Similarly, we can set the
beginning
of the animation to be anything, from a set value in time (e.g. begin="20s"
) to
an user event (e.g. startme.click) to a relative event on another element (e.g. bait.end)
to
a mixture of them (e.g. bait.end+3)
<g> <code> <animate attributeName='opacity' values='0;1' dur='2s' fill='freeze' begin="bait.end"/> </code> ... </g>
Listing 3. Animating Opacity on a group/relative start
Apart from the animate
element, another option available is to actually set a
property to a particular value on any given time. For example, if we wanted a text
to
dissapear instantly, twenty seconds after we click the start button we use the following
code (Listing 4):
<set attributeName="opacity" to="0" begin="startmeup.click+20"/>
Listing 4. set element
Color and opacity effects with type are a common design element on the Web, especially for decorative purposes. However, this doesn't mean that the only place for animation and type is brochureware featuring the much-exhausted company name tweening from black to white. On the contrary, type animation can be a unique art tool and a compelling touch in user interfaces. In the present example you can see it at use for artistic purposes, in previous articles (and surely on future ones) you can see the techniques applied as UI enhancements.
Animating Position
One positive aspect of SVG's XML nature is the ability to play well with your open
source
hacking skill-set. Even as a beginner developer it is easy to create programs that
output
text such as the one needed for our next trick, a typewriter effect.
The typewriter effect we will use is based on animating references to text, which
as you
may remember, is achieved via tref
. Using tref
you populate your
text
element with a predefined piece of text.
Usually, using tref is helpful to encapsulate all text at the top of the SVG so it
can be
easily changed to other languages or edited. In this case we will use it a little
differently: we will define many text elements and make one tref
go through all
of them. We will animate through strings like "A", "An",
"Ani", "Anim" and so on, creating the illusion of adding a letter at a
time.
First, we describe at the top of our SVG document, the definitions of the strings we will animate through (Listing 5):
<defs> <text id='t-1'> </text> <text id='t0'>A</text> <text id='t1'>An</text> <text id='t2'>Ani</text> <text id='t3'>Anim</text> <text id='t4'>Anima</text> <text id='t5'>Animat</text> <text id='t6'>Animati</text> <text id='t7'>Animatio</text> <text id='t8'>Animation</text> <text id='t9'>Animation </text> <text id='t10'>Animation i</text> <text id='t11'>Animation in</text> <text id='t12'>Animation in </text> <text id='t13'>Animation in S</text> <text id='t14'>Animation in SV</text> <text id='t15'>Animation in SVG</text> <text id='t23'>Animation in SVG, </text> <text id='t24'>Animation in SVG, s</text> ... </defs>
Listing 5. Typewriter (defs)
Then, we use the animate
element to cycle through each definition, by varying
the xlink:href
attribute through each of the ids.
<text x="40" y="110"> <tref> <animate attributeName='xlink:href' values='#t0;#t1;#t2;#t3;#t4;#t5;#t6;#t7;#t8;#t9;#t10;#t11;#t12; #t13;#t14;#t15;#t24;#t25;#t26;#t27;#t28;#t29;#t30;#t31; #t32;#t33;#t34;#t35;#t36;#t37;#t38;#t39;#t40;#t41;#t49; #t50;#t51;#t52;#t53;#t54;#t55;#t56;#t57;#t58;#t59;#t60; #t61;#t62;#t63;#t64;#t65;#t66;#t67;#t68;#t69;#t70;#t71; #t72;#t73;#t74;#t75;#t76;#t77;#t78;#t79;#t80;#t81;#t82; #t83;#t84;#t85;#t86;#t87;#t88;#t89;#t90;#t91;#t92;#t93; #t94;#t95;#t96;#t97;#t98;#t99;#t100;#t101;#t102;#t103;#t104' dur='10s' fill='freeze' begin="startmeup.click"/> <animate id="a1" attributeName='x' values='40;0' dur='4s' fill='freeze' begin="startmeup.click+8"/> </tref> </text>
Listing 6. Typewritter (animate)
At first it may be surprising that you can animate something like this, but as you
can
see, it is an interesting source of flexibility. I suggest you try animating other
traditionally "static" attributes such as the text's font for fun, as well as for
getting a better appreciation of the generality of SVGs animation model (<animate
attributeName='font-family' values='Arial;Verdana;Times' dur='10s'
begin="startmeup.click"/>
)
We also have animated the position of the text by varying the x
attribute of
the text element, but this animation only starts a little later (8 seconds later actually)
so the overall effect is initially only that of typewriting and then it gets mixed
with
sliding.
Now, typing a hundred strings for the typewriter animation is tedious, but that is where the text nature of SVG comes in handy. The following Perl script produces the necessary definitions for replicating this effect with any string:
$s = "Put your string here."; $a = "<animate id='a1' attributeName='xlink:href' values='"; for($i=0; $i < length $s; $i++) { print "<text id='t".$i."'>".substr($s,0,$i+1)."</text>\n"; $a .= "#t" .$i. ";"; } $a .= "' dur='5s' fill='freeze' begin='YOUR_START_BUTTON.click'/>\n"; print $a;
Listing 7. Perl code to generate typewriters
Of course, by pointing out this solution, I don't mean to suggest SVG is unique in its capacity to make easy typewriter effects, or even that Listing 6 is the best way to make them in SVG (actually Stefan Goesnner and Michel Hirtzler have very general javascript-based SVG components to do this).
What I do mean to suggest is a certain consistency between SVG's XML nature and the hacking mechanisms so valued in the open source community: open the hood, reuse your knowledge of open technologies to figure how things are working, and then slap in a quick solution using other known OS tools.
Animating through a Path
A less common effect used in the first half of our animation is making text move over a path. We use it to make the second line of text follow the same wave as a fish.
As you may remember from previous articles in these series, putting text on a path
is
achieved by using a textPath
element as shown in Listing 8:
<text> <textPath xlink:href="#wave1"> but animation is more, says the artist: it's the fish in the water. Motion creates emotion. </textPath> </text>
Listing 8. Text on a Path
Another property we discussed previously when analyzing characters was the
startOffset
, a value that alters the position of the text by modifying where
should it start. In this case a startOffset of 0 would mean the text starts at the
beginning
of the path.
Putting these two elements of past articles (textPath
and
startoffset
) together with our animate
element we can make text
flow across the path by animating its offset, as illustrated in Listing 9:
<textPath xlink:href="#wave1" startOffset="-610"> but animation is more, says the artist: it's the fish in the water. Motion creates emotion. <animate id="a2" attributeName='startOffset' values='-610;25' dur='5s' fill='freeze' begin="a1.begin"/> </textPath>
Listing 9. Moving text accross a Path
In the interest of honesty, it must be pointed out that the other half of this effect,
the
definition of the path itself (<path id="fishfloat" d="M0 0 C11.145 12.2554 11.224
13.7919 13.333 12.6364z"/>
), is not something you can comfortably expect to code
by hand. To draw the paths you will have to use either a commercial tool like Adobe
Illustrator 10, Jasc WebDraw, or try one of the emerging online SVG drawing tools.
At the
end of the animation we use the effect again, to move the fishing string that reads
"use animation for bait". Only this time we use a different path, and combine it
with a decaying opacity to convey the notion of a time lapse (Listing 10).
<text x="600" y="60" style="opacity:0"> <set attributeName="opacity" to="1" begin="rowing1.end+3"/> <animate id="dissapearRod" attributeName='opacity' values='1;0' dur='4s' fill='freeze' begin="rowing1.end+4"/> <textPath xlink:href="#rod1" startOffset="0"> use animation for bait.use animation for bait.use animation for bait.use animation for bait. <animate attributeName='startOffset' values='610;-80' dur='5s' fill='freeze' begin="rowing1.end+3"/> </textPath> </text>
Listing 10. Moving fishing string text
Other elements
There are many other elements of this animation that I have not described directly
in the
article. The reason for this is that they are either outside the core of the discussion
(e.g. "how to draw the fish") or because their theory is explained in the three
previous articles of these series.
Among the elements based on previous articles are
- The letter J as a hook, and the string attached to it: Direction and Orientation, discussed in part 2
- The combination of adjacent colors and the contrast of compliments: discussed in part 1
- Embedding the Arial font so it looks consistent in all systems: font embedding, discussed in part 2
- Color Gradients and other static effects discussed in part 3
- Orientation and alignement of the two paragraphs, discussed in part 1
Conclusion
In this series we have explored the relationship of typography and SVG from a variety of perspectives, from purely technical issues related to characters and portability, to creative issues dealing with color, composition, and effects.
I hope you find these articles useful. Please feel free to drop me a line with questions any time.