Menu

SVG and Typography: Animation

June 30, 2004

Fabio Arciniegas A.

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

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.