FIVe3D TextCloud: AS3 Tutorial and Source
Friday, May 23rd, 2008A few people have asked me to release the code to my FIVe3D Text Cloud example, so I’ve cleaned things up to the point where I wouldn’t be completely humiliated to release it into the wild. However, I thought I’d touch on a couple points and turn this post into something halfway between a tutorial and an exhibition.
If you just want the source code, you can download it at the bottom of the page. If you’d like the whole shebang, pray read on.
The (new and improved) example:
FIVe3D Basics
FIVe3D is ridiculously easy to set up. In this example, I used the following code to set up everything I needed:
// the Scene3D class is what contains and renders everything else // think of it as a 3D Stage class scene = new Scene3D(); scene.x = 375; scene.y = 200; addChild( scene ); // Sprite3D is, obviously, a 3D version of the standard Sprite class // it is an actual DisplayObject, so you can use normal positioning, filters, etc. on it container = new Sprite3D(); scene.addChild( container );
You’ll notice that the syntax is just like AS3 extended into the third dimension. You can nest Sprite3Ds just like Sprites. When you move or rotate the parent Sprite3D, the children will move and rotate with it. The reason I’ve created a container Sprite3D here is so I can rotate several children at the same time.
Now if I wanted to do this the easy way, I could just add my text in one big chunk with the DynamicText3D class that ships with FIVe3D. It works much like the AS3 TextField class, except that the fonts are actually ActionScript files (you’ll see what I mean when you crack open the FIVe3D source).
var txt:DynamicText3D = new DynamicText3D( HelveticaBold ); // HelveticaBold ships with FIVe3D txt.size = 30; txt.color = 0xD34328; txt.text = "Pixelwelders LLC" container.addChild( txt );
That’s it. The Scene3D class takes care of its own rendering, so you don’t have to trigger it yourself, Papervision-style. Even when a FIVe3D scene looks static, it is actually rendering at your current frame rate. Thus, this is enough code to render 3D text in FIVe3D. Add an ENTER_FRAME listener and increment the container.rotationX property every frame and you’ll see what I mean.
Moving On…
Now this is fine for your everyday run-of-the-mill 3D text, but not for the effect that I had in mind. If I had added my text this way, it would have behaved as a single block, each letter forever doomed to stay wedged firmly between its neighbors. No, I had bigger plans for this text.
For this effect, I created a class called MotifCollection3D. Not a very good name, but typography is not my strong suite and I wasn’t quite sure what else to call it. It’s an extension of the aforementioned FIVe3D Sprite3D class, and it contains one DynamicText3D instance for every letter of the word that it’s currently displaying. This is how you instantiate it:
var cloud:MotifCollection3D = new MotifCollection3D( "PIXELWELDERS LLC", HelveticaBold, 30, 0xD34328 ); container.addChild( cloud );
There’s nothing to it. You send the text, the font class (again, included with FIVe3D), the size, and the color. It creates and assembles all the DynamicText3D instances, and then you can treat it like any other Sprite3D. However, it also includes two methods: assemble(), and the thrillingly-named explode().
Calling either of these methods cycles through all the instances of DynamicText3D and tweens them each to a destination using TweenLite. The explode() method was easy: it just chooses a random destination and rotation for each letter. The assemble() function, on the other hand, was a bit trickier; it needs to know the exact width of every letter in order to place them next to each other.
Happily, that is one of the things that’s included with the FIVe3D typography classes. Each letter, number, and punctuation mark in HelveticaBold contains a __width property, accessible like so:
var letterWidth:Number = HelveticaBold.__widths[ "P" ]; // returns the width of the "P" glyph
That’s a start, but it returns the same width regardless of what size the font is being displayed at. After a little experimentation, I found that this code gives the correct glyph width no matter what size the font:
var letterWidth:Number = HelveticaBold.__widths[ "P" ] * ( size / 100 );
I think that pretty much covers anything novel that I may have done. There are additional comments in the code as well, and it’s only two classes anyway: it shouldn’t be too difficult to figure out anything not explicitly laid out here.
Download Source
Pixelwelders FIVe3D Text Cloud
NOTE: You’ll need to download TweenLite and FIVe3D from their respective sites to get this to run. But you probably already knew that.