Web Animation using JavaScript: Animating Text

Since textual animation is rarely employed in webpages, using it is an easy way to impress users. That's precisely what makes this topic so much fun to learn: the underlying techniques are simple to program, but the results feel incredibly rich and complex to the user.

This article introduces you to tools that remove the tedious aspects of textual animation and equip you with an efficient workflow. Read on to learn the nuances of this dark art.

The standard approach to text animation

The standard HTML elements we code sites with— div s, table s, anchor tags, and the like—are the lowest-level components of a webpage that can be styled. Consequently, these are the lowest-level components that can be animated.

Text does not constitute an element unto itself; a block of text is designated by the browser as a text node, which is an unstylable, lower-level component that must be contained by an element. Further complicating matters is the fact that the browser does not subdivide text nodes into grammatical components; there is no way to access individual letters, words, or sentences.

Consequently, to animate text on a letter, word, or sentence basis, you have to break each text node into separate text nodes, and then wrap each of these in a new element. You can then animate them. But manually wrapping text in span elements, for example, is tedious work that results in bloated HTML.

It's no surprise then that text animation on the web is uncommon; it's typically too much of a hassle to deal with. This puts the web at an aesthetic disadvantage to dedicated motion design software, such as Adobe After Effects, which allows for the fine-grained animation of text—the results of which are commonly seen in TV commercials and movie title sequences. These effects can look absolutely beautiful. Unfortunately, in addition to being difficult to integrate on the web, they're also widely considered bad practice. After all, the web is a medium that prioritizes function over form, and text animation is largely about form.

However, there is one textual animation use case that can carry over well to the web when used sparingly: if you pay close attention to the depictions of futuristic hardware interfaces in movies, you'll notice the common thread of text being animated into or out of view on a grammatical level. The future of computing, according to pop culture, consists of words and sentences animating with flickers, glitches, pops, and blurs. These effects look cool, and there isn't much downside to embracing them for the purposes of transitioning content into or out of view since the text had to undergo a visibility animation by one means or another. This concept of transitioning text visibility is precisely what you'll learn about in this article.

Preparing text elements for animation with Blast.js

The tool of choice for typographic animation is Blast.js, which handily breaks blocks of text into characters, words, and sentences. You can then animate the resulting parts using Velocity and its UI pack plugin.

NOTE: Get Blast.js at Julian.com/research/blast.

Blast.js has three delimiter types to define the grammatical components to be individually extracted: character, word, and sentence. Suppose you have a div that looks like this:

<div> Hello World </div>

If you call Blast on this div using the following syntax:

$("div").blast({ delimiter: "word" });

the div would turn into this:

<div class="blast-root"> <span class="blast">Hello</span> <span class="blast">World</span> </div>

As you can see, Blast separated the target div 's text into text parts that are individually wrapped in span elements. If you were to instead use the character delimiter, the result would have been:

<div class="blast-root"> <span class="blast">H</span> <span class="blast">e</span> <span class="blast">l</span> <span class="blast">l</span> <span class="blast">o</span> <span class="blast"> </span> <span class="blast">W</span> <span class="blast">o</span> <span class="blast">r</span> <span class="blast">l</span> <span class="blast">d</span> </div>

You can now animate these span elements independently. Before you dive into textual animation, however, you're going to learn more about how Blast works so you can take full advantage of its powerful features.

How Blast.js works

The goal of this section is to make you comfortable with the prospect of using Blast to break apart the text on your beloved page. Let's dive in!

divs , tables , and the other HTML elements that you're familiar with are called element nodes. An element node commonly consists of two types of children: additional element nodes and text nodes (raw text).

Take this element, for example:

<div> Hello <span>World</span> </div>

This div element is composed of two children: a text node ("Hello") and a span element node. The span element node contains a child of its own: another text node ("World").

When Blast is called, it traverses the entirety of the target element's descendant element chain to find text nodes. With each text node, Blast executes the RegEx query associated with the specified delimiter type ( character , word , or sentence ) to subdivide the node into new elements, each with its own text node part. Since Blast doesn't actually subdivide element nodes—only text nodes—you can safely apply it to the entire page without worrying about breaking elements' event handlers and other expected behaviors. This versatility is crucial when using Blast on user-generated content that is often dirtied with HTML. (Say, for example, you want to separate the words in a message posted to your site's comments section so you can highlight important passages. With Blast, you can safely do so without concern for breaking the user's embedded links.)

In addition to its robustness, Blast provides a high level of accuracy. It doesn't dumbly split words at spaces, nor does it split sentences at periods within words. It leverages UTF-8 character sets for Latin alphabet languages, meaning that you can accurately apply it to French, German, Spanish, English, Italian, and Portuguese content.

Suppose you used Blast's sentence delimiter on the following paragraph. (Note that bold and italic are used below to indicate the consecutive text matches that Blast detects.) Blast correctly identified six sentences in the paragraph:

¿Will the sentence delimiter recognize this full sentence containing Spanish punctuation? ¡Yes! « Mais, oui ! » "Nested "quotes" don't break the sentence delimiter!" Further, periods inside words (e.g. Blast.js), in formal titles (e.g. Mrs. Bluth, Dr. Fünke), and in "e.g." and "i.e." do not falsely match as sentence-final punctuation. Darn. That's pretty impressive.

Notice how punctuation is associated with its proper sentence, and how errant periods don't falsely demarcate sentence matches.

With these foundations covered, it's time to run through how to use Blast.

Installation

Blast is installed on a page like any other JavaScript plugin: embed the appropriate script link before your page's </body> tag:

<html> <head>My Page</head> <body> My content. <script src="jquery.js"></script> <script src="velocity.js"></script> <script src="blast.js"></script> </body> </html>

NOTE: Blast requires jQuery (or Zepto, a jQuery alternative), and therefore must be required after jQuery. It doesn't matter whether Blast is loaded before or after Velocity.

Once Blast is loaded, use it by calling .blast() on a jQuery element object. It accepts an options object as its sole argument:

$element.blast({ option1: value1, option2: value 2 });

Let's run through the available options.

Option: Delimiter

Blast's most important option is delimiter , which accepts "character" , "word" , or "sentence" . To separate the text within $element using the "sentence" delimiter, your code would look like this:

$element.blast({ delimiter: "sentence" });

Note that Blast returns the generated text wrapper elements to the jQuery selector chain so you can manipulate them, like this:

$element.blast({ delimiter: "sentence" }) .css("opacity", 0.5);

The .css() call is applied to the individual text elements, not the parent $element that you called Blast on.

Option: customClass

Blast provides two options to make text manipulation easier: customClass and generateValueClass . customClass behaves exactly as you would expect: supply a custom class (as a string value) to be assigned to the text node wrapper elements.

Suppose you had the following div and Blast call:

<div> Hi Mom </div>

$("div").blast({ delimiter: "word" , customClass: "myClass" });

The div would turn into the following (note how Blast automatically assigns every text part the "blast" class by default):

<div> <span class="blast myClass">Hi</span> <span class="blast myClass">Mom</span> </div>

The value in providing a custom class is in differentiating the elements generated by each Blast call. If, for example, you used Blast in two locations on your page—once in the header and once in the footer—it might be helpful to assign these two calls different classes so your subsequent JavaScript code and CSS styles can act on the text elements appropriately.

Option: generateValueClass

generateValueClass takes a Boolean value (true or false) indicating whether a unique class, in the form of .blast-[delimiter]-[textValue], should be assigned to the generated text elements.

NOTE: This option is applicable only to the character and word delimiters.

The [delimiter] placeholder represents the delimiter type used in the call, and the [textValue] placeholder represents the text contained within an individual element. Consider the following example: