
Page 5 of 5
JT Paasch
This user is yet to take control of their account and provide a biography. If you are the author of this article, please contact us via support AT actionscript DOT org.
View all articles by JT Paaschpublic function getLength ():Number {
return typeArray.length;
} // end getLength () method
Thus far our whole class looks like this:
class Typeset {
private var typeString:String;
private var typeArray:Array;
function Typeset (_typeString:String) {
this.init.apply (this, arguments);
} // end constructor
public function init (_typeString:String):Void {
typeString = _typeString;
buildTypset ();
} // end init () method
private function buildTypeset ():Void {
// break up typeString,
// putting each character into its own clip
for (var i = 0; i < typeString.length; i++) {
// store the current character as 'thisChar'
var thisChar = typeString.charAt (i);
// create a movieclip in the array
typeArray[i] = _root.createEmptyMovieClip ("typeset_" + i, _root.getNextHighestDepth ());
// create a textfield inside that movieclip
typeArray[i].createTextField ("_txt", _root.getNextHighestDepth (), 0, 0, 100, 100);
// set the textfield's value to 'thisChar'
typeArray[i]._txt.text = thisChar;
} // end looping through typeString
} // end buildTypeset () method
public function setSpacing (spacing:Number):Void {
// set the space between each character to 'spacing'
for (var i = 0; i < typeArray.length; i++) {
typeArray[i]._x = i * spacing;
} // end looping through each character
} // end getLength () method
public function setTextFieldProperty (propertyName:String, propertyValue, startIndex:Number, endIndex:Number):Void {
// set a textfield property from startIndex to endIndex
for (var i = startIndex; i < endIndex; i++) {
typeArray[i]._txt[propertyName] = propertyValue;
} // end looping from startIndex to endIndex
} // end setTextFieldProperty () method
public function getLength ():Number {
return typeArray.length;
} // end getLength () method
} // end Typeset class
Before we finish this section, let me show you how to implement some standard TextField methods. In our Typeset class, it would be very useful to have some standard TextField methods. For example, it would be useful to have a setTextFormat () method so that we could apply TextFormats to the characters in our Typeset. We can implement this method for our Typeset class so that we can apply TextFormats to our Typeset just as we do to TextFields.
The first step is to implement the method with the same name. Here we can pass the TextFormat as a parameter just as we do with a TextField.
public function setTextFormat (format):Void {
// apply the TextFormat to the characters
} // end setTextFormat () method
To apply the specified TextFormat to our characters, we simply need to loop through each character and apply the TextFormat to each movieclip's TextField:
public function setTextFormat (format):Void {
// apply the TextFormat to the characters
for (var i = 0; i < getLength (); i++) {
typeArray[i]._txt.setTextFormat (format);
} // end looping through the characters
} // end setTextFormat () method
With that method in our class, we can then apply a TextFormat to our Typeset. For example, this applies a TextFormat to our 'Hello World' Typeset to make each character blue 14pt Arial:
// create an "Hello World" typeset
var type:Typeset = new Typeset ("Hello World");
// set the spacing to 20 pixels
type.setSpacing (20);
// create a TextFormat
var myFormat:TextFormat = new TextFormat ();
myFormat.font = "Arial";
myFormat.size = 14;
myFormat.color = 0x006699;
// apply the TextFormat to the Typeset
type.setTextFormat (myFormat);
The TextField's setTextFormat () method, however, lets you specify a start and end index to which the TextFormat should be applied. To implement that same feature in our method, we need to set up some if statements at the beginning of our method which determine if a start and/or end index have been specified. We can use the arguments array to tell how many arguments have been passed to the method:
public function setTextFormat (arg1, arg2, arg3):Void {
// set 'startAt' and 'endAt' depending on
// how many arguments have been passed to the method.
if (arguments.length == 1) {
var startAt = 0;
var endAt = getLength ();
var format = arg1;
} else if (arguments.length == 2) {
var startAt = arg1;
var endAt = arg1 + 1;
var format = arg2;
} else if (arguments.length == 3) {
var startAt = arg1;
var endAt = arg2;
var format = arg3;
} // end if (arguments.length = 1)
// apply the TextFormat to the characters
// from startAt to endAt
for (var i = startAt; i < endAt; i++) {
typeArray[i]._txt.setTextFormat (format);
} // end looping through the characters
} // end setTextFormat () method
Notice that there are now three arguments named arg1, arg2, and arg3. We chose generic names because the value of arg1 will be different depending on how many arguments are passed. For example, if the user is just specifying the TextFormat --
type.setTextFormat (myFormat);
-- then arg1 will be a TextFormat. But if the user is specifying a startIndex too --
type.setTextFormat (4, myFormat);
-- then arg1 will be the startIndex, and arg2 will be the TextFormat. The first thing our method tests then is how many arguments have been passed. If there is only one argument, then the argument is the TextFormat and it should be applied to all the characters. Thus the first if statement sets startAt to 0, endAt to the length of the Typeset, and it sets format to arg1. The second if statement sets startAt to arg1, endAt to one number higher (so it will only loop through one value), and it sets format to arg2. The third if statement sets startAt to arg1, endAt to arg2, and format to arg3.
Once startAt, endAt, and format are set according to how many arguments were passed to the method, the method then loops from startAt to endAt and applies format to each character's TextField. The result is a setTextFormat () method which works for our Typeset class exactly as it works for the TextField class. We now can use TextFormats with our Typesets with just as much precision as with TextFields.
Here is our class, in full, with everything documented:
// *********************************************************** //
// *********************************************************** //
//
// Typeset class
//
// *********************************************************** //
// *********************************************************** //
//
// This class takes a string, breaks it up into its individual
// characters, and places each of those characters in its own
// movieclip. The movieclips are stored in an array. Methods
// are then implemented to provide an interface to manipulate
// the character movieclips.
//
// Examples of use:
//
// var myType:Typeset = new Typeset ("Hello World");
// myType.setSpacing (20);
// var myFormat:TextFormat = new TextFormat ();
// myFormat.font = "Arial";
// myFormat.size = 32;
// myType.setTextFormat (myFormat);
//
// *********************************************************** //
class Typeset {
// ********************************************************* //
// Class variables
// --------------------------------------------------------- //
//
// typeString: the string comprising this Typeset
// typeArray: the array holding each character movieclip
//
// ********************************************************* //
private var typeString:String;
private var typeArray:Array;
// ********************************************************* //
// Constructor
// --------------------------------------------------------- //
//
// Takes one parameter: a string to be broken up so that
// each character is to be placed in its own movieclip.
//
// ********************************************************* //
function Typeset (_typeString:String) {
this.init.apply (this, arguments);
} // end constructor
// ********************************************************* //
// init
// --------------------------------------------------------- //
//
// Takes one parameter: a string to be broken up so that
// each character is to be placed in its own movieclip
// (this is passed from the constructor).
// The method then invokes the buildTypeset method.
//
// ********************************************************* //
public function init (_typeString:String):Void {
typeString = _typeString;
buildTypset ();
} // end init () method
// ********************************************************* //
// buildTypeset
// --------------------------------------------------------- //
//
// Takes no parameters.
// This function breaks up 'typeString' and places each
// character in its own movieclip. The movieclips are
// stored in 'typeArray' so that each character clip
// can be accessed by the character index number.
//
// ********************************************************* //
private function buildTypeset ():Void {
// break up typeString,
// putting each character into its own clip
for (var i = 0; i < typeString.length; i++) {
// store the current character as 'thisChar'
var thisChar = typeString.charAt (i);
// create a movieclip in the array
typeArray[i] = _root.createEmptyMovieClip ("typeset_" + i, _root.getNextHighestDepth ());
// create a textfield inside that movieclip
typeArray[i].createTextField ("_txt", _root.getNextHighestDepth (), 0, 0, 100, 100);
// set the textfield's value to 'thisChar'
typeArray[i]._txt.text = thisChar;
} // end looping through typeString
} // end buildTypeset () method
// ********************************************************* //
// setSpacing
// --------------------------------------------------------- //
//
// Takes one parameter: a number which specifies the
// distance between each character in the Typeset.
//
// ********************************************************* //
public function setSpacing (spacing:Number):Void {
// set the space between each character to 'spacing'
for (var i = 0; i < typeArray.length; i++) {
typeArray[i]._x = i * spacing;
} // end looping through each character
} // end getLength () method
// ********************************************************* //
// setTextFieldProperty
// --------------------------------------------------------- //
//
// Takes four parameters: (1) a string naming the property
// you wish to set for the characters between startIndex
// and endIndex. (2) the value of the property you wish to
// set. (3) the character index of the first character for
// which you want to set the property. (4) the character
// index of the last character for which you want to
// set the property. The method sets the value of the
// property (1) to the value specified (2) for characters
// between startIndex (3) and endIndex (4).
//
// ********************************************************* //
public function setTextFieldProperty (propertyName:String, propertyValue, startIndex:Number, endIndex:Number):Void {
// set a textfield property from startIndex to endIndex
for (var i = startIndex; i < endIndex; i++) {
typeArray[i]._txt[propertyName] = propertyValue;
} // end looping from startIndex to endIndex
} // end setTextFieldProperty () method
// ********************************************************* //
// getLength
// --------------------------------------------------------- //
//
// Takes no parameters. Returns the number of characters
// in the typeset.
//
// ********************************************************* //
public function getLength ():Number {
return typeArray.length;
} // end getLength () method
// ********************************************************* //
// setTextFormat
// --------------------------------------------------------- //
//
// This method follows the same interface as it does for
// the TextField object, so consult the entry for
// TextField.setTextFormat () in the AS Dictionary
// for documentation.
//
// ********************************************************* //
public function setTextFormat (arg1, arg2, arg3):Void {
// set 'startAt' and 'endAt' depending on
// how many arguments have been passed to the method.
if (arguments.length == 1) {
var startAt = 0;
var endAt = getLength ();
var format = arg1;
} else if (arguments.length == 2) {
var startAt = arg1;
var endAt = arg1 + 1;
var format = arg2;
} else if (arguments.length == 3) {
var startAt = arg1;
var endAt = arg2;
var format = arg3;
} // end if (arguments.length = 1)
// apply the TextFormat to the characters
// from startAt to endAt
for (var i = startAt; i < endAt; i++) {
typeArray[i]._txt.setTextFormat (format);
} // end looping through the characters
} // end setTextFormat () method
} // end Typeset class
You can implement any other methods you use with TextFields in the same way we have implemented setTextFormat () here (e.g. you might implement some CSS methods). Working with your Typesets can end up being just as easy as working with TextFields: you simply call the right methods, and the class does all the work for you. The hard work is wrapped up inside the class and you never need to touch it.
You can also implement your own methods to handle character spacing (vertical and horizontal), and maybe you even want to implement some methods which move, rotate, scale, and fade the characters in your Typesets. By wrapping up all the hard work inside the class, you can then easily manipulate characters individually simply by invoking the relevant methods. Using this technique, as well as other techniques, Flash can become an innovative new medium for typographic design. You can use such techniques to make your letters come alive on the page.
2.4 Some cautions
Before finishing this section, I should mention a few cautions when using actionscripted type design in the fashion described here. First of all, text strings can easily be fairly long, and trying to manipulate each character indepedently in long strings results in many movieclips. If you get too many movieclips on the stage, Flash can quickly bog down and move slowly. It is best to prevent this by using something like the Typeset class only for short text strings. However, this isn't too much a problem if we recall the principle mentioned earlier that typographic design should be subtle. Use something like the Typeset class to give your typographic design subtle life, but don't use it to dizzy your reader with spinning letters. Nobody can read spinning letters.
Subtle use of these techniques can help your site design mature substantially. You can be very creative and use these techniques in innovative ways to help communicate and more tightly control site coherence. For example, if you are building a site for an independent film about the breakdown of a character's identity, you might use the Typeset class to make blocks of text here and there subtly flicker and shift, bit by bit, until the text itself is threatened with losing its identity. You can implement the same idea with the lines, shapes, and colors throughout the rest of the site's design too. In this way you can design your type in a way consistent with the rest of the site, bringing to your work a more mature sense of coherence.
2.5 Conclusion
In this second part of the series, we have looked at some ways to use actionscript to drive our typographic design. The TextFormat and CSS objects give us relatively precise control over type formatting. Further, if we break a string up and put each character into a movieclip, we can then control each character just as a movieclip, and thus we expose the characters of the string to Flash's full animation powers. This allows us to integrate our type into the motion design of our movies. Consequently, type can be just as much a mover and shaker as lines and shapes. This opens our typographic design up to new considerations, guidelines, and principles typically applicable to motion design. Yet even though the techniques of motion design are now available to how we use type, always remember that it is still type. Thus, the principles and guidelines we discussed in part one of this series still apply, and good typographic style -- whether the text is moving or not -- will still 'follow the rules'. Nevertheless, actionscript opens up new and interesting arenas in which to explore how principles of sound typographic design can be worked out in the world of motion.
Spread The Word
1 Response to "Typography in Flash" 
|
said this on 10 Aug 2007 9:49:27 AM CST
Hey great article and tut
|



Author/Admin)