logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
Apr 27, 2012 Posted on Apr 27, 2012 in Hints and Tips | 10 comments

Quick Tip: Configuring Sublime Text 2 for Dart Coding

Sublime Text 2 is a powerful text editor, popular due to its cross-platform availability and its knack for leveraging pre-existing TextMate capabilities. Combine Sublime Text 2 with Google’s new Dart language, and power coders can be very happy.


Prerequisites

In order for this to go quickly, I’ll assume that you have some foundational knowledge. You should be familiar with the following for this tip:

  • A working knowledge of Sublime Text 2 packages. Most of this tip centers on the steps required to build our own Dart package, but if you’ve never used a snippet before you might want to back up for a second and go learn more about Sublime Text first.
  • A working knowledge of Dart will also help. We won’t really be coding any Dart in this tip, but having a few Dart files around with which to test things will help greatly.
  • We’ll be checking code out of a Subversion repository, and while I’ll feed you the command to use, hopefully this isn’t your first time using Subversion.
  • Finally, a general knowledge of your particular OS is in order. We’ll need to do a small amount of configuration and if you’re comfortable, say, modifying a .bash_profile file via the Terminal, then you’ll be fine.

If you need some prior reading material, I refer you to the following:

  • Sublime Text 2 documentation (however unofficial) is kept at sublimetext.info/docs. The pages on Packages, Syntax Definitions, and Snippets were particularly useful in the writing of this tip.
  • Dart information can be found at the official site, or by following along Activetuts’ Introduction to Dart tutorial
  • Much has been written about Subversion, not to mention a complete online book. That’s a bit more than you need, as you simply need to have Subversion installed and to checkout a single folder
  • Google will be your friend when it comes to learning more about configuring your system.

Step 1: Install Dart Editor

We won’t really be using the Dart Editor (the point of this tutorial is to use Sublime Text for Dart development, after al), but the download includes the Dart SDK, which is really what we’re after. Even if you’re a hardcore Sublime Text 2 fanatic, it’s still not a terrible idea to have the “official” Dart Editor installed and handy.

On the official Dart site, you can download the Dart Editor from the following link:

http://www.dartlang.org/docs/getting-started/editor/

Under “Step 1″ of that page, you’ll find a link to a ZIP file containing the Dart Editors. It’s around 70-100 MB, depending on your OS, so it’s not a terribly heavy download. But get it started!

The Dart Editor is based on Eclipse, so if you’ve used that you’ll be right at home with the Dart Editor. I won’t be getting into details on using it in this tutorial, but feel free to play around with it. The Activetuts+ introductory Dart tutorial (currently exclusively available through Facebook) takes you through the basic usage of the Dart Editor.

Note that if you don’t want to install the Dart Editor, you can download just the Dark SDK for your OS at this URL (it’s only 2 or 3 MB):

http://www.dartlang.org/docs/getting-started/sdk/index.html


Step 2: If You Have 64-Bit Linux

If you don’t have a 64-bit Linux installation, you can skip this step. (Yep, that includes you, Windows and Mac users; scroll down for your instructions.)

If you are on a 64-bit Linux installation, you’ll need to install a 32-bit library in order to run the Dart compiler, even if you’ve downloaded the 64-bit Dart Editor. I’m not a Linux guru by any stretch, but this worked for me, on my Ubuntu 11 installation.

Go to the Software Center and search for “lib32stdc++6″ or “GNU Standard C++ Library 32 bit”. Install it. You can continue on with the next few steps while it installs – just be sure this library has successfully installed before attempting to run the build system.

Install this library if you're running 64-bit Linux

Step 3: Download Google’s Dart TextMate Language File

The TextMate language file is hosted on Google Code here (web-based view into the repository):

http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.tmLanguage

This is actually part of a larger TextMate bundle (but not that much larger), but we’re only interested in the language grammar.

Before we grab that file, create a location for it to live on your system. You’ll need to create a folder named Dart in the following location, depending on your OS:

  • Mac OS: ~/Library/Application Support/Sublime Text 2/Packages/Dart
  • Windows 7: C:\Users\Administrator\AppData\Roaming\Sublime Text 2\Packages\Dart
  • Linux: ~/.config/sublime-text-2/Packages/Dart

Then open up your command line interface and navigate to inside of that newly-created Dart folder.

Subversion doesn’t make it easy to checkout a single file, but we can export a single file. Enter this command:

svn export http://dart.googlecode.com/svn/branches/bleeding_edge/dart/tools/utils/textmate/Dart.tmbundle/Syntaxes/Dart.tmLanguage

After a moment you should have the Dart.tmLanguage file in your Dart folder.

Go ahead and try it out (you may need to restart Sublime Text). Open up a Dart file and check out the colorful syntax:

A simple Dart file in Sublime Text 2, showing off syntax highlighting
A simple Dart file in Sublime Text 2, showing off syntax highlighting

Step 4: Locate your frogc Executable

frogc is the Dart-to-JavaScript compiler. It’s a command line tool, but it’s thankfully easy to use. We’ll be using it in a Sublime Build System later to turn our Dart file(s) into JavaScript, so we don’t even need to use it on the command line anyway.

To make the Build System, we need the path to our frogc executable. This was downloaded with the Dart SDK (which you either downloaded with the Dart Editor or by itself). It will be located at dart-sdk/bin/frogc. “dart-sdk” will either be where you downloaded and unzipped the SDK by itself, or nested just inside the dart folder which also contains the Dart Editor application, which will be where you placed it.

We need a command-line-compatible path to frogc. On Mac OS, you can do this:

Open up a Terminal window and drag frogc into it. The window will contain the text of the path of the file you dropped.

For Windows:

Click in the address bar of the window. It should turn into a plain text path for the folder, which you can then copy. You’ll need to add “\frogc.bat” at the end to get the path to frogc, not just the bin folder.

If you’re on Linux, you probably already know how to do this.

Make sure the path is absolute, and readily available. Place it on your clipboard or in a scratch text file for the next step.


Step 5: Create a Dart Build System to Compile JavaScript

To make this language package really useful, we should set up a Build System, which lets us run files through a shell build command.

In Sublime Text, choose the Tools > Build System > New Build System… menu. You’ll be presented with a new file with the following default contents:

{
    "cmd": ["make"]
}

This is just a JSON object that describes a very basic build command. We’ll add much more to this to make it useful for Dart development.

With that path you determined in the last step readily available, we can edit our sublime-build file.

If you’re on Mac or Linux, change the contents of the file to:

{
    "cmd": ["/Applications/dart/dart-sdk/bin/frogc", "$file"],
    "file_regex": "^(.+\\.dart):(\\d+):(\\d+):.+\\[0m(.+)$",
    "selector": "source.dart"
}

The above is what I have on my Mac system. Where it says /Applications/dart/dart-sdk/bin/frogc, add in your own frogc path.

If you're on Windows, the file will look rather similar, but you should change the "cmd" line to:

{
    "cmd": ["cmd", "/C", "C:\\insert path here\\frogc.bat", "$file"],
    "file_regex": "^(.+\\.dart):(\\d+):(\\d+):.+\\[0m(.+)$",
    "selector": "source.dart"
}

To briefly explain what this does, the cmd property is basically just what to run on the command line. frogc is simple to use: just invoke the command and feed it a file. The $file part of that line is a variable that gets expanded automatically to the page of the current file.

On Windows, things are a little funkier by default (at least in this scenario; that's not a dig at Microsoft, I swear!). What we have will run the Windows command line (cmd) with the "don't keep the terminal window up" parameter (/C, though even the "keep the terminal window up" /K parameter doesn't show it either), and run frogc.bat, passing it the full file path. This is the quick way to get it working, but does seem to produce errors in the current build. This is probably a temporary problem, as at the time of this writing these errors are produced with the standard SDK and not the latest SDK. See the next step for an alternate route.

The file_regex line is for error reporting purposes. If a line in the output of the command matches this regular expression pattern, it's recognized as an error and pressing F4 will highlight them for you in the output panel.

Unfortunately frogc uses text-styling codes to make parts of the error message a different color and/or bold. When piped into Sublime Text, these style codes are presented as regular text, so the output can be a little hard to read, with [0m and similar codes peppered amongst the human-readable text. I'm not aware of any way around this, sadly.

The final line, selector, specifies the scope in which this Build System should take place. With this set to source.dart, Dart files should automatically choose this Build System. Sublime Text 2 knows that a ".dart" file is a, well, a Dart file thanks to the language grammar we installed.

Save this file as Dart-frogc.sublime-build in [Sublime Data]/Packages/User/Dart/


Optional Power-User Step for Windows

To avoid the aforementioned errors on Windows, and also make your build system fit more in line with the Mac and Linux versions, we can add the dart-sdk bin folder to the Windows environment, so that Sublime Text knows to look there for frogc.

To add the path, click Start, then right-click Computer, and select Properties. (Alternatively: Control Panel > System and Security > System.) Click "Advanced system settings", then on "Environment Variables."

Now, find the "path" variable, in either User Variables or System Variables (it works with either). If it doesn't exist, you can click New to create it, but if it does exist, then clicking New will overwrite it, so be careful.

Append the correct path to the end of what's already there, using a semicolon to separate it from everything else. No need to escape slashes or replace spaces with underscores or anything like that. Mine looks like:

C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Users\Administrator\Downloads\dart-win32-latest\dart-sdk\bin

(Scroll the above box to the right.)

That'll let you run frogc c:\whatever\source.dart from the command window, but it still won't work within Sublime Text 2. For some reason, ST2 on Windows requires you to specify the file extension in your build system file, like so:

"cmd": ["frogc.bat", "$file"]

At this point, you should have a usable build system on Windows that's less likely to break.


Step 6: Using the Build System

Go ahead and try our new Build System out. Open up a Dart file, and press F7 or Control-B (on the Mac, Command-B). "B" for Build.

You should see the output panel open up at the bottom, and if the Dart is error-free, you'll just see [Finished].

The Build System is successful

If you have errors, you'll get much more complex output. For example:

The Build System showing errors

When this happens, press F4 to move forward through the various lines of error, and Shift-F4 to move backward. The error line will highlight in the output panel, and your cursor will be placed at the line and column identified by the error.

The Build System highlighting an error

Step 7: Start Building Snippets

There are potentially many useful snippets to be added to a Dart bundle. Let me get you started by adding a snippet that creates a new method.

From the Sublime Text menu, choose Tools > New Snippet... You'll again be presented with a default file, this one in XML format. Change its contents to:

<snippet>
    <content><![CDATA[
${1:void} ${2:methodName}(${3:arguments}) {
    $0${1/void|(.+)/(?1:\n\treturn null;)/}
}
]]></content>
    <tabTrigger>method</tabTrigger>
    <scope>source.dart</scope>
</snippet>

Feel free to change the contents of the <tabTrigger> node from method to something else that you'll find more useful. This is what you type before pressing Tab in order to get the snippet.

Save the file as method.sublime-snippet (the extension is crucial; the base name is what your snippet will show up as in the menus), in the following location relative to your Sublime Text 2 Packages folder:

/Dart/method.sublime-snippet

You should already have the "Dart" folder from the installation of the language grammar file.

Now try out your new snippet (you may need to restart Sublime Text, but I think this is no longer an issue).

In a Dart file, type "method" (or whatever you specified, if you forged your own tab trigger), press Tab, and watch it expand. You can tab through the various stops, starting at the return type, then to the method name, and finally in between the parentheses if you want to add arguments. The last tab will drop you at the first line of the method.

The cool part is that if you change the return type from void, you get an automatic return null statement at the end of your method body. Naturally you'll want to adapt this to your needs, but hopefully it's a feature that saves a little typing. The magic happens in the unwieldy second line of the snippet; if you've never seen this before, then it's somewhat difficult to explain concisely, but it looks at the contents of the first tab stop (the return type) and if it's anything other than "void", it adds the return null. It might make sense if you've ever used Regular Expressions, particularly with the substitution syntax of /pattern/substitute/ found in Perl.

The field's wide open for the creation of time-saving Dart snippets. Feel free to post your snippets in the comments.


That's All

And there you have it; those of use who prefer a certain text editor over anything else can continue to do so, even with this new Dart language. Thanks for reading, and I hope you learned something about Sublime Text 2's extensibility along the way.



View full post on Activetuts+

Mar 28, 2012 Posted on Mar 28, 2012 in Hints and Tips | 10 comments

Quick Tip: Create a Typewriter Text Effect Class

In this Quick Tip, we’ll create a static, re-usable ActionScript class that will produce a Typewriter effect with a single line. Read on!


Step 1: Brief Overview

We’ll split a user defined string into an array, and then add the resulting letters to a TextField one by one using the Timer class.


Step 2: Typewriter Class

Our class will be static, which means it doesn’t need to be instantiated using the new keyword. To access a static class member, use the name of the class instead of the name of an instance.

Create a new ActionScript file and write the following code:

package
{
	import flash.text.TextField;
	import flash.utils.Timer;
	import flash.events.TimerEvent;

	public final class Typewriter
	{
		/* Declare the variables and methods as static */

		private static var chars:Array; //the characters in the string
		private static var tf:TextField; //textfield to which the string will be written
		private static var timer:Timer; //pauses between writing each character
		private static var i:int = 0; //variable used to count the written characters

		public static function write(txt:String, txtField:TextField, time:Number):void
		{
			chars = txt.split(""); //split the string into an array of characters
			tf = txtField; //assign tf to the text field passed to the function
			timer = new Timer(time); //set time according to parameter

			timer.addEventListener(TimerEvent.TIMER, writeChar);
			timer.start(); //start writing function
		}

		private static function writeChar(e:TimerEvent):void
		{
			if (i < chars.length)
			{
				tf.appendText(chars[i]); //writes a char every time the function is called
				i++; //next char
			}
			if (i >= chars.length) //check whether string is complete
			{
				timer.stop();
				timer.removeEventListener(TimerEvent.TIMER, writeChar); //clear timer
				timer = null;
			}
		}
	}
}

Step 3: Usage

The usage couldn’t be easier – just add the Typewriter.as class to your project folder and use the following code:

import Typewriter;

Typewriter.write('Text to Write', targetTextfield, 50);

That’s it, test your movie and you’ll see your TextField using the Typewriter effect.


Step 4: Example

I used the class in on this example swf so you can see the effect:


Conclusion

Use this class to create your own effects!

Thank you for reading. If you’d like a more advanced version of this effect for use in your projects, take a look at Rasmus Wriedt Larsen’s Letter By Letter Animation.



View full post on Activetuts+

Dec 19, 2011 Posted on Dec 19, 2011 in Hints and Tips | 10 comments

Easily Create Souped-Up Flash Text Fields With TextArea

In this tutorial I’ll walk you through the steps required to install and use the TextArea component as an alternative to Flash’s native TextField class, and show you how to detect mouse roll over/out events on hyperlinks. I’ll also talk about how you can call custom functions and pass different data types as arguments.


Background

The native TextField class was the first to support text scripts in Flash projects. With TextField, you could support dynamic and static text, as well as the input type to allow user interactivity. It also supported a (very limited) selection of HTML tags for styling your scripts – but when comparing this narrow availability of HTML support in TextField to what is possible with regular HTML files being used within browsers, Flash developers felt the extreme lack of flexibility when dealing with text.

In 2009 when TLFTextField was introduced, developers were hoping to see some solutions – but these didn’t appear. Today, with the TextArea class, you can do what you always wanted with your text blocks. Functionalities like detecting roll over/out on href links, calling custom functions from text blocks, creating anchor links, loading custom created tags like video players, slideshow, and buttons: these are all now possible with TextArea.


Final Result Preview

The following simple no-frills demo will present how custom functions are called on hyperlinks. This is what you’ll build in the next 30 minutes:


Step 1: Set Up the Environment

TextArea can be used in any IDE that compiles AS3 – like Flash Builder, CS pro versions and FlashDevelop – which means it’ll work across Flash platform (in Flex, AIR and AS3-only web projects). Different IDEs each have a somehow similar but unique approach to how you compile your project, and due to this diversity it’s sometimes frustrating, especially for beginners, to work with AS3 tutorials because the author may prefer Flash Builder while the learner is accustomed to work with the CS IDE.

To solve this problem, I will try to explain the usage of TextArea independent of the IDE. So, the first step is to set up your environment. No matter which IDE you’re using, just open it and create a new AS3 project, then save it somewhere on your computer.

Create a document class, name it Main.as, and add a trace call to output Hello World.

package
{
	import flash.display.MovieClip

	public class Main extends MovieClip
	{

		public function Main():void
		{
			trace("Hello World")
		}
	}
}

Step 2: Download TextArea

TextArea is free to download and to use but be sure to read the license agreements here. Head to doitflash.com and find the download button at the bottom of the home page to download TextArea classes.

Extract the zip file you downloaded, TextArea.zip, to your computer, go to the folder TextArea/Src, and copy the com folder then to the same directory as your document class, Main.as.

By copying the com folder to where you have your project document class, you are letting the IDE find TextArea classes only in this specific project. Alternatively, you could copy the classes to your global class path so that it will always be available to all your projects – to find out more, read How To Use an External Library in Your Flash Projects.


Step 3: Initializing TextArea

After downloading and installing the TextArea, it’s time to initialize it. First you need to import the required classes to the Main class.

import com.doitflash.text.TextArea;

Then remove the hello world trace function and enter the following instead.

var _textArea:TextArea = new TextArea();
_textArea.wordWrap= true;
_textArea.multiline = true;
_textArea.htmlText = "Initialize TextArea just like you used to initialize TextField.";
this.addChild(_textArea);

Test your movie and this time instead of outputting hello world, you’ll see a text field (but not a TextField!) created for you:

simple initialization of TextArea

As you can see, TextArea works exactly like the native TextField class. All the different settings that you could apply to TextField are true for TextArea also; it’s basically an extension to TextField so it will do everything TextField does, plus more. I’ll talk about these extra features in the next sections.


Step 4: Feeding TextArea With an XML File

To make this tutorial as informative as possible and to make it useable for real world practices, let’s try to feed the TextArea instance with data from an external XML file.

This procress will again be similar to how you load XML data into TextField. First, create your XML file and place it where you have the published SWF file from the previous steps. Make the XML look like the below and save it as “data.xml”:

<?xml version="1.0" encoding="UTF-8"?>
<data>
<![CDATA[
<p align="left"><font face="Tahoma" size="13" color="#333333">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam cursus. Morbi ut mi.
Nullam enim leo, egestas id, condimentum at, laoreet mattis, massa.
</font></p>
]]>
</data> 

(So that XML contains HTML in a CDATA section.)

Now get back to your Main.as, which should look like the following:

package
{
	import flash.display.MovieClip
	import com.doitflash.text.TextArea;

	public class Main extends MovieClip
	{

		public function Main():void
		{
			var _textArea:TextArea = new TextArea();
			_textArea.wordWrap = true;
			_textArea.multiline = true;
			_textArea.htmlText = "Initialize TextArea just like you used to initialize TextField.";
			this.addChild(_textArea);
		}
	}
}

Add the required imports for xml loading process.

import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;

Then replace the whole Main() function with this.

		public function Main():void
		{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, onXmlLoaded);
			loader.load(new URLRequest("data.xml"));

			function onXmlLoaded(e:Event):void
			{
				var xml:XML = new XML(e.currentTarget.data);

				var _textArea:TextArea = new TextArea();
				_textArea.wordWrap = true;
				_textArea.multiline = true;
				_textArea.width = 400;
				_textArea.height = 200;
				_textArea.condenseWhite = true;
				_textArea.htmlText = xml.text();
				addChild(_textArea);
			}
		}

The above code loads data.xml – there’s no difference from how you would have done it with a TextField so far.


Step 5: Detecting Mouse Rollover/Rollout

To use the specific features of TextArea, you need to specify a few extra settings when initializing it.

The first and the most important thing to remember about using TextArea is that you should use the fmlText method for sending text scripts into the instance rather than using the classic htmlText. The fmlText method will parse scripts using a different approach than htmlText; it stands for Flash Markup Language Text.

So, in your test project, replace htmlText with fmlText like below.

_textArea.fmlText = xml.text();

The next thing to do is create two custom functions in your document class, Main.as, which will be called when you rollover or rollout a hyperlink (which we will build later in data.xml). For the sake of this tutorial, these two functions will just trace some outputs, but in the real world, you could do anything you want with these functions – like, say, opening a tooltip window.

public function funcOnOver():void
{
	trace("rollOver");
}
public function funcOnOut():void
{
	trace("rollOut");
}

You should also set some settings while initializing the TextArea instance. Add these lines just after you initialize TextArea.

_textArea.holder = refToThis; // indicates the location where you are adding TextArea to stage
_textArea.client = refToThis; // must be the location where you have your "allowedFunctions" saved
_textArea.mouseRollOverEnabled = true; // enables mouse rollover detection
_textArea.funcSecurity = true; // makes sure only function names in "allowedFunctions" are accessible
_textArea.allowedFunctions(funcOnOver, funcOnOut);

Also add the following line to the beginning of the Main() function.

var refToThis:Object = this;

To make sure you have written the code in Main.as correctly, below is how your file should look up to now.

package
{
	import flash.display.MovieClip
	import com.doitflash.text.TextArea;

	import flash.events.Event;
	import flash.net.URLLoader;
	import flash.net.URLRequest;

	public class Main extends MovieClip
	{

		public function Main():void
		{
			var refToThis:Object = this;

			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, onXmlLoaded);
			loader.load(new URLRequest("data.xml"));

			function onXmlLoaded(e:Event):void
			{
				var xml:XML = new XML(e.currentTarget.data);

				var _textArea:TextArea = new TextArea();
				_textArea.holder = refToThis; // indicates the location where you are adding TextArea to stage
				_textArea.client = refToThis; // must be the location where you have your "allowedFunctions" saved
				_textArea.mouseRollOverEnabled = true; // enables mouse rollover detection
				_textArea.funcSecurity = true; // makes sure only function names in "allowedFunctions" are accessible
				_textArea.allowedFunctions(funcOnOver, funcOnOut);
				_textArea.wordWrap = true;
				_textArea.multiline = true;
				_textArea.width = 400;
				_textArea.height = 200;
				_textArea.condenseWhite = true;
				_textArea.fmlText = xml.text();
				addChild(_textArea);
			}
		}

		public function funcOnOver():void
		{
			trace("rollOver");
		}
		public function funcOnOut():void
		{
			trace("rollOut");
		}
	}
}

That’s pretty much everything you need to do in your .as file; and the rest will be done in the XML but before we go to XML and create a hyperlink, let’s talk a bit about the above settings.

First we have the holder property which is something that you won’t use in this article but when you go deeper into TextArea to create custom html tags you will need this a lot; for the sake of this tutorial, it’s sufficient for you to know that this property saves the location where you are adding the TextArea instance into the stage.

Then we have the client property. This is the location of – or better to say, this is a reference to – a class where you save all your allowed functions. In this example we use Main.as as the client, but if you have a long list of functions that want to give them the permission to be called from your text scripts, you may prefer creating a separate class for that purpose.

We also have the mouseRollOverEnabled property which is set to false by default for performance reasons. If you want to detect mouse roll over/out on your hyperlinks, you must make sure you enable this property.

Then we have two security properties: allowedFunctions and funcSecurity. These properties will let you restrict the called functions to the specific ones mentioned in the allowedFunctions method.

Okay, to see the magic, get back to data.xml and and add the following line somewhere inside the CDATA section:

Here's a <u><a href='onMouseOver:funcOnOver();onMouseOut:funcOnOut()'>SAMPLE LINK</a></u>.

As you see you have created two function calls (one on mouse rollover, one on mouse rollout) and you can do whatever you like with these functions inside your AS3 project.

But this is not all! In the next section I’ll talk about how you can call custom functions and pass different types of data as arguments.


Step 6: Pass Arguments to Functions

Up to now, you have learned how to set the TextArea instance ready for accepting function calls from HTML content which can be placed in external sources like XML. Now we’re going to send different types of arguments along with the calls.

We can send array, object and simple string types. Try adding the following hyperlink somewhere inside the CDATA tag in your XML file:

<u><a href='event:func1()'>SIMPLE CALL</a></u>.<br />
<u><a href='event:func2(some string)'>SEND STRING</a></u>.<br />
<u><a href='event:func3([0,1,2,3,4])'>SEND ARRAY</a></u>.<br />
<u><a href='event:func4({var1:val1;var2:val2})'>SEND OBJECT</a></u>.<br />
<u><a href='event:func5(string,[0,1,2],{var1:val1;var2:val2})'>SEND MIXED ARGUMENTS</a></u>.<br />

This will create five function calls in your AS3 project; each function demonstrates how you can send different types of arguments. But remember that this will not work until you actually create these functions inside your AS3 project. To do that, simply add these functions along with the funcOnOver() and funcOnOut() functions that you had previously:

		public function func1():void
		{
			trace("no arguments sent");
		}
		public function func2($str:String):void
		{
			trace("arguments >> " + $str);
		}
		public function func3($arr:Array):void
		{
			trace("arguments >> " + $arr);
		}
		public function func4($obj:Object):void
		{
			trace("arguments >> " + $obj);
		}
		public function func5($str:String, $arr:Array, $obj:Object):void
		{
			trace("arguments >> " + $str);
			trace("arguments >> " + $arr);
			trace("arguments >> " + $obj);
		}

Now you have the calls in XML and the functions are also available in the AS3 project; all that’s left is to give the usage permission to the TextArea instance. Modify the allowedFunctions method of TextArea as so:

_textArea.allowedFunctions(funcOnOver, funcOnOut, func1, func2, func3, func4, func5);

Now publish and test your project and try clicking the hyperlinks you created.

Congratulations, you have now learned how to enable mouse rollover and rollout in your text fields, and you know how to create custom functions and call them from within your text blocks.


Conclusion

TextArea extends TextField, adds only 6kb to your project, and can be used as an alternative to TextField. In this tutorial you learned how to initialize TextArea to create simple hyperlinks which can call custom functions inside your AS3 project, and you also learned how to enable mouse rollover and rollout detection on hyperlinks that can call custom functions.

There are many things you can do with these features, like open a tooltip when rolling over a certain hyperlink or create links which call a custom function in your project to navigate through your application pages easier.

I hope you find this tutorial (and TextArea itself) useful!



View full post on Activetuts+

Jun 16, 2011 Posted on Jun 16, 2011 in Hints and Tips | 2 comments

Flash Tips and Best Practices for Designers: Symbols & Text

For most newbies, the concept of symbols in Flash can be pretty confusing. I’ve known enough designers who – even after working with Flash for years – are pretty clueless about the best way to use symbols in their work. Let’s take a closer look at symbols and text.

Welcome to the second part of our Flash Tips and Best Practices series for designers. In the first part we looked at drawing, which is usually the first thing one would tackle when starting with Flash. Once you’ve mastered the creation tools though, it does not take too long to realize that the shapes by themselves are pretty useless. Sure, you can apply colors and strokes and manipulate them any way you want, but you’re probably in there to make things move. And the best way to start with that is to convert the shapes to symbols.

Another critical aspect of design in Flash that we will cover today, is text. Over the years, Flash’s ability to create and render text has taken some pretty big leaps. I still remember the days when there was no ‘anti-alias for animation’ setting and the thought of having blocks of text was nothing short of a nightmare. That’s all gone now and with the ability to apply filters directly to text, it’s a much less painful routine now. Yet, there’s a lot one can do with the text tool in Flash today. We will look at some such tricks.

Although this post was written for Flash Professional CS5, most of the tips should work just fine in older versions. I will try and make it a point to highlight wherever something is very specific to the latest version of Flash.


Choose Your Symbols

For starters, there are three types of symbols you can create in Flash: graphic, button, and movie clip. Although the names should be pretty self-explanatory, it is not always obvious what the difference is between the three. Please bear with me if this sounds too basic, but I know a lot of Flash designers who are not entirely sure what’s what. So here goes:

  • Graphic: The most basic type of symbol in Flash, and probably the most useless. You can’t have an animation inside a graphic (well, technically you can, but Flash will simply ignore it), and you can’t really assign much in the name of functionality to graphic using ActionScript. For me, it’s only one step above simply grouping elements.
  • Button: As the name suggests, this is an interactive element. A button is automatically converted to an active element – on that you can click, like a link in an HTML page. Every button has three states – up (or normal), overand down . You can assign ActionScript to button to make it start the animation, for example.
  • Movie Clip: This is by far the most used symbol type in Flash, and for good reason. To start with, you can have an animation within a Movie Clip. An instance of a Movie Clip placed on the stage will animate irrespective of the main timeline. It is also the only symbol type that you can apply blending modes and filters (more on those in a minute).

Note: You can set the behavior of an instance of any symbol individually. Placed a Movie Clip on the stage but don’t want it to animate? Simply select the instance and change the behavior in the ‘Properties’ panel.


Blending Modes

Blending modes bring one of the much loved features from image editing applications to Flash’s vector workspace. Like Photoshop, Fireworks, Illustrator and others, you can alter how elements look by overlapping them and choosing different transparency modes. For example, you might want to darken a part of an object based on what’s on top of it, or maybe lighten it. One common way to use this is when you have an imported raster logo image with a white background that would like to show through. Simply change the blending mode to ‘Multiply’ in the ‘Display’ section of the Properties panel.

Blending modes in Flash

Note that blending modes can only be applied to Movie Clip and button symbols. For more on Blend Modes in Flash checkout this screencast.


Case study: Apply lighting effects to boring flat textures

Let’s say you need a realistic wooden background for your design. There are tons of free textures available out there, but one common problem is that they all tend to look flat. Now if you’re trying to re-create a tabletop, there needs to be some semblance of a light source from one of the sides, right? Let’s try and re-create that effect in Flash using Blending modes.

  1. Import your texture on the stage and position it as required.
  2. Draw a rectangle on top of the image, matching its size and x & y co-ordinates. Use the Primitive Rectangle tool here; a normal rectangle shape will always appear behind the image unless you draw it on a new layer.
  3. Remove any strokes from the rectangle and add a default white-to-black radial gradient fill. Adjust the fill so that the white center is close to the corner you need the light source to be in, and the black edges are close to the diagonally opposite corner.
  4. Now convert this rectangle to a Movie Clip symbol and change its blending mode to ‘Overlay’. You may need to adjust the ‘Alpha’ a bit to get effect just right.

Color Effects

One of the first things one learns about animation in Flash is how to fade stuff in and out. And the default technique to do that is to change the ‘Alpha’ value of a symbol. But there is much more to the other items in that dropdown list, together known as Color Effects.

Color Effects

Although Alpha sounds like the best way to fade stuff in and out, it is not always the most suitable option. For example, if your symbol is a drawing with a bunch of overlapping shapes, Alpha reduces the transparency of each shape individually which brings up artifacts in the semi-transparent states. In such cases, if your artwork is on a white background, changing the Brightness values works much better to get the fade effect. If the background is some other flat color, you can also use Tint and fill the artwork with the background color. Unfortunately, if the background is a gradient, pattern or anything else, your only option is to go into the symbol, break apart all shapes and groups and bring them on a single layer to make a object.

Alpha vs. Brightness

Note that unlike Blending Modes, Color Effects can be applied to any symbol – movie clips, buttons, and graphics.


Case Study: Create multiple colored buttons from one symbol

When designing interfaces in Photoshop or Fireworks, one technique I use very often is to create a base interface element – like a button – and make color variations of it using the Hue-Saturation filters. Recently I figured out a way to do something similar in Flash. The idea is to create a single neutral symbol and then use the Advanced color effects to create variations of it.

Using the Advanced color effect

To start with, create a symbol with whatever gradients, highlights, shadows and overlays you want. You can make it in any color, but I tend to prefer using only grey shades. So the result is a button that’s as matte, plastic or any style you want, but in grey. Next, place a couple of instances of the symbol on the stage. Then simply select an instance, apply the ‘Advanced’ color effect and start playing around with the RGB color values. If you are struggling to get it right, one way is to select Tint, pick the color you need, and then go to the Advanced panel to tweak it to your satisfaction. Rinse and repeat for the other symbols.


Filters

For a very long time, Flash designers were stuck with the strictly vector creation tools in Flash. Soft shadows and motion blurs were things you hacked together using awkward gradients or raster images imported from Photoshop. Then along came the Filters in Flash 8 and everything changed. Today, pretty much any snazzy effect is possible right inside Flash with a decent amount of control over all aspects of the filter. Let’s look at some ways you can use Filters to add some jazz to your designs.


Curved box shadows

Sure, there are drop shadows for when you want an element to stand out from the background or just differentiate it from everything else around it. But for occasions when a simple drop shadow is just not enough, you can play around with the fall-off a bit to add that extra bit of style. One way to do this, is to create a copy of your shape and tweak it around to get the curvature you need. Then convert it to a symbol, add a 100% black tint color effect and a gaussian blur. Then simply adjust the alpha value to get the intensity you need from the shadow. Check out a couple of samples below.

Different ways to add shadows

Remember to set the quality to ‘High’ whenever you use a filter. The effect is much much better. It totally beats me why ‘Low’ is set as the default quality setting. I’ve used filters in seriously complex animations and the impact on performance is barely noticeable.


Letterpress

When it comes to big text, the letterpress effect is pretty popular. With the ability to add multiple filters of the same type (something even Photoshop doesn’t have yet), the letterpress effect is pretty easy to achieve in Flash. All you need to do is simply add two drop-shadow filters – one with a white 1px shadow at 90 degrees and one black at 270 degrees. Check out the image below for all the details.

A letterpress effect using multiple drop shadows

9-Slice Scaling

Another feature that was introduced in Flash 8 is 9-slice scaling – the ability to scale an object without affecting certain parts of it. The best example where this works is rounded rectangles. If you’ve every tried to create rounded rectangles and then scale them, you know how the corners tend to go out of shape if the scaling is not proportionate. 9-slice scaling solves that problem. Let’s see how.

  1. Draw the shape you want and open the "convert to symbol" dialog.
  2. Select Movie Clip in the Type dropdown list. 9-slice scaling can only be applied to a movie clip symbol.
  3. Click the ‘Advanced’ link at the bottom-left of the dialog box and check "Enable guides for 9-slice scaling".
  4. Now double-click the symbol to edit it.
  5. You should see two vertical and two horizontal dotted lines on top of the shape. Move these outwards so that they are just inside the curves on all four corners.
9-slice scaling

Here’s how it works. I’ve labeled each of the 9 sections we now have, divided by the dotted lines. When you go back to the stage and scale the object – proportionately or otherwise – A, C, E & G will not scale at all. They will retain their size and shape. B & F will only scale horizontally, while D & H will only scale vertically. This way, no matter what you do, the rounded rectangle retains its core personality. This technique can work wonders when you need a bunch of similar elements at different sizes – like buttons, popups or speech bubbles.

Note that 9-slice scaling will not work in every context. If your artwork has complex shapes or very round corners with curved reflections, or even pattern fills, the scaling may not be consistent.


Text

If there was one complaint about Flash that overpowered everything else in the past, it was the way Flash handled text. In older versions, especially before the Adobe takeover, text rendering in Flash sucked, to put it nicely. So much so that it had spurned an entire cottage industry of pixel fonts that were designed to work around Flash’s inability to render small text smoothly. Thankfully, with the addition of ‘anti-alias for readability’ things became much much more bearable. The one tip I give anyone I who has ever had anything to do with Flash is to avoid anything but ‘anti-alias for readability’ like plague. In fact, I don’t even know why they have that option any more since text rendering in the player has now been optimized enough to smoothly render ‘readable’ text in any scenario.

Different text rendering modes in Flash

A very new and potentially ground-breaking phenomenon is the Text Layout Framework (or TLF), Adobe’s high level API for the new Flash Text Engine that was introduced in Flash Player 10. Starting with the CS5 version, you have the choice of making any block of text be ‘Classic Text’ or ‘TLF Text’. I know, as if there already weren’t too many choices to make, right!? Well, although TLF is clearly the future of text in Flash, it is not compatible with older versions of the Flash Player or with AS2 and below. So if you want backward compatibility, Classic Text is your best bet.

The TLF text properties

TLF basically adds a boatload of features to good old text in Flash. Want to maintain tight control over the leading and tracking in your text? Need vertical orientation for the text? How about multiple columns? Heck, do you just need your text to display nicely in an Indian language (or most non-latin scripts, for that matter)? TLF is the answer. There are way too many options to tweak how a block of TLF text renders, way more than what we can cover here. I would say go ahead and play around with it a bit. Just remember that this hasn’t been around too long – neither in the authoring tool nor the player – and there are bound to be some issues with the way it works at the moment.


Helpful Hints

Here are some quick hints and suggested best practices to make the best use of the text tools in Flash:

  • The shortcut keys for bold and italic in Flash are different than most other applications – Ctrl+Shift+B is for bold, and Ctrl+Shift+I is for italic.
  • With the text tool selected, click once on the stage to create a single line text field. Click and drag to create a paragraph.
    • To convert a paragraph to a single line, click anywhere inside the text block and double-click the hollow square handle at the top-right of the selection.
    • To convert a single line to a paragraph, simply drag any of the four selection handles.
    • A hollow square at the top-right indicates that the selected block is a paragraph, while a hollow circle represents a single line.
  • A text block can be of three types:
    • Static: A static block of text that is hardcoded in the FLA and nothing more.
    • Dynamic: If you need to replace the contents of a text block on the fly during run time, this one is way to go.
    • Input: The name says it all, really. Use this for when you need the user to enter text – like in forms, etc.
  • If you need to embed a font in your Flash file and the text is going to be simple alphabets, numbers and everyday punctuations, choose ‘Basic Latin’ in the Embed dialog. There’s a good chance you won’t need anything else from that font.
  • Filters can be applied directly to a block of text in Flash. You don’t need to convert it to a movie clip as with everything else. Go ahead and go crazy with those 1 pixel text shadows, already!

Conclusion

And that’s how you do symbols and text in Flash. Of course, there’s a ton more to these than we have covered, but the attempt was to try and compile some of the best tips and best practices when working with symbols and text. Please feel free to add your own tips and shortcuts in the comments section. Or challenge anything I’ve said. I’ll be the first to acknowledge that I don’t know everything there is to know about Flash, so anything new or different is always welcome.

Next time we will get into the core functionality and unique selling point of Flash: animation. Stay tuned!



View full post on Activetuts+

Apr 9, 2011 Posted on Apr 9, 2011 in Hints and Tips | 0 comments

Go Round the Bend With Text on a Path in Flash

Flash’s text formatting capabilities are really great, but the only transformations we can perform are the usual MovieClip examples. If your designer asks you to place well-formatted text on a circular path, there’s no built-in transformation tool to get the job done…

We will see how to explode the TextField and place all the characters along such a curve, preserving the text formatting and character spacing. Finally, we’ll take a look at how to draw text along a spiral.


Final Result Preview

Let’s take a look at the final result we will be working towards:

Alter the text in the textfield and toy around with the parameters..

Imagine this fictional scenario: Monday morning, you’re drinking your coffee, and then your graphic designer comes and wakes asks you “Hey, I’m designing the game loading animation, and I’d like to have the loading progress text fit this circle; I guess you have something I can copy and paste to do the job ?”

And the fact is that you don’t have already something to easily lay out the text in this way. So you come here and read this article. We will go step by step to build what you’re after, starting with the basic mathematics knowledge to place a point along a circle, find which place to put it, according to its original position in a container, how to preserve the character formatting and spacing (otherwise your designer would never accept your solution) and then compile all these parts into a generic class that will make it easy to set up and transform any dynamic text to apply this circular layout.

The font used in the demo is the free Elegan Tech font you can download and freely use from dafont.com

The first steps will show in detail how to create the test Flash movie. If you are already familiar with the usage of Flash components and their event handling, you might want to jump directly to Step 10 where the real work begins, once the starting points are set.


Step 1: Demo Interface Demo Flash File

Start by creating a new CircularTextTest.fla file with Flash Professional, then open the Components window and drag a slider, a label and a checkbox to your Flash library.

In the Flash file, create a large text field, then set it as an input TextField and give it the name: tfTemplate. For this demo we have chosen to use the EleganTech font, so set the TextField’s font value to this, then import the font and make sure the necessary characters range are imported.

Drag and drop the checkbox from the library to your stage, then copy and paste it 3 times. Each checkbox will be used to set a demo parameter: show/hide anchors, turn text outside/inside, trim (or not) the empty space.

The label and selected values are up to you, to set the initial values of the demo. The important thing is to set the instance names of the checkboxes to be able to use them. The first one will be chkShowAnchors, the second one chkTxtOutside and the third one chkTrimWhite.

Finally we will need one slider to set the value of the circle radius, and another to adjust the character offset from the anchors we will place. Each slider will come with a label in which we will display the actual value. So you can drag and drop a label and a slider from the library to the stage, then set their names and parameters like on this screenshot.

Apart from the instance names which are mandatory, the important parameters are the slider value, which we will be used as the initial default value, the min and max values. The liveDragging parameter will make the slider send an event while it is being dragged, so that we will update the circle in real time when the user moves the slider. If liveDragging isn’t checked, the update will only occur when the user release the slider.

Now you can create the second slider and its associated label, respectively named sliderCharOffset and labelOffset. For the demo I have used the default value of 7, min and max values from -50 to 50, but this is up to you, you can set it to fit your needs.
At last you can set the document class to be CircularTextTest, which will host all the demo code. The class isn’t yet created, this is the next step, right now you just have to set the class name in the Flash file, as explained in the How to Use a Document Class in Flash Quick Tip.

The Flash file is now complete. If you have any doubt you might check the file from the downloadable sources.


Step 2: Demo Interface Demo Class

In this step we create the class, associate it with the Flash file and write down its basic content: an addedToStage handler function and the basic createCircularText routine that we will call to transform the text.

Let’s create the CircularTextTest.as Class file alongside your Flash file. The very first steps will be to import the classes we need, to declare the assets we have put on the stage and to prepare the routine we will call to do the work.

package  {

	import fl.controls.CheckBox;
	import fl.controls.Label;
	import fl.controls.Slider;
	import fl.events.SliderEvent;

	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TextEvent;

		public class CircularTextTest extends MovieClip
		{
			/* ----- Assets defined in the Flash timeline for the demo ----- */
			/** The editable TextField */
			public var tfTemplate:TextField;
			/** Checkbox:  show character anchors */
			public var chkShowAnchors:CheckBox;
			/** Checkbox: text orientation */
			public var chkTxtOutside:CheckBox;
			/** Checkbox: trimWhite/condenseWhiteSpace */
			public var chkTrimWhite:CheckBox;
			/** Slider : the value of the circle radius */
			public var sliderRadius:Slider;
			/** The label to display the current radius value */
			public var labelRadius:Label;
			/** Slider : the offset of the characters from the circle */
			public var sliderCharOffset:Slider;
			/** The label to display the current offset value */
			public var labelOffset:Label;

			public function CircularTextTest() {
				stop();
				addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			}

			protected function onAddedToStage(evt:Event):void
			{
				createCircularText();
			}

			protected function createCircularText():void
			{
				// Here will comes all the interesting code
			}

		}

}

This is the basic structure, now we will have to fill the blanks to make sure we use the values from the input field, checkboxes, and sliders.


Step 3: Demo Interface Input TextField

We need to make sure we know when the content of the TextField is modified, so we will complete the initSwf initialization handler to add event listeners to the change and textInput events. These events will call their own callback, which will in turn call the createCircularText() routine. This extra step is there for if you want to perform some validation stuff depending of the event type; to give an example, you might want to add some code to make sure the text is valid, or to perform some special stuff when the text is empty, before calling the createCircularText() method.

protected function onAddedToStage(evt:Event):void
{
	tfTemplate.addEventListener(TextEvent.TEXT_INPUT, onTextInputHandler, false,0,true);
	tfTemplate.addEventListener(Event.CHANGE, onTextChangeHandler, false,0,true);

	createCircularText();
}

protected function onTextInputHandler(evt:TextEvent):void
{
	createCircularText();
}
protected function onTextChangeHandler(evt:Event):void
{
	createCircularText();
}

Step 4: Demo Interface Text Direction Checkbox

The checkbox is already set up and ready in Flash, so we just need to listen for updates to the chkTxtOutside checkbox. Exactly like for the input field, we update our initialization routine to add an event listener for the change event from the checkbox. This time we will use only one generic onCheckBoxChange event callback for all the checkboxes, that we will create right now.

protected function onAddedToStage(evt:Event):void
{
	// ...
	// Previous code still here
	// ...

	chkTxtOutside.addEventListener(Event.CHANGE, onCheckBoxChange, false, 0, true);
	//stage.addEventListener(MouseEvent.CLICK, onCheckBoxChange); // Lazy-man listener to update the circle after every click on any component.

	createCircularText();
}

protected function onCheckBoxChange(event:Event):void
{
	createCircularText();
}

If you read the comments you might notice I have left commented a very lazy implementation that you might find useful when creating a quick and dirty test: adding a click event listener on the stage to call the update will generate more updates than are really needed, but when your goal is only to make sure the update routine is called to test your code, this might be a time-saver.


Step 5: Demo Interface Show Anchors Checkbox

I guess you have understood how it works, so the next steps will sound very familiar: we will continue to add event listeners to the change/update events of the components the user will interact with.

protected function onAddedToStage(evt:Event):void
{
	// ...
	// Previous code still here
	// ...

	chkShowAnchors.addEventListener(Event.CHANGE, onCheckBoxChange, false, 0, true);

	createCircularText();
}

Step 6: Demo Interface Radius Slider

Listening for the update of the slider will work like the checkboxes, but we will also update the label contents to display the value to the user, editing the label text to display the slider value.

protected function onAddedToStage(evt:Event):void
{
	// ...
	// Previous code still here
	// ...

	sliderRadius.addEventListener(SliderEvent.CHANGE, onRadiusChange, false,0,true);

	createCircularText();
}

protected function onRadiusChange(evt:SliderEvent):void
{
	labelRadius.text = "Radius : " + sliderRadius.value;
	createCircularText();
}

Step 7: Demo Interface Text Offset Slider

Obviously this is almost the same story as the radius, but with a different label and a different slider.

protected function onAddedToStage(evt:Event):void
{
	// ...
	// Previous code still here
	// ...

	sliderCharOffset.addEventListener(SliderEvent.CHANGE, onCharOffsetChange, false,0,true);

	createCircularText();
}

protected function onCharOffsetChange(evt:SliderEvent):void
{
	labelOffset.text = "Character offset from the circle : " + sliderCharOffset.value;
	createCircularText();
}

Step 8: Demo Interface Generate Circle

Right now we have done all the work to make sure the createCircularText routine is called every time something has changed, to create the text circle. Now it is time to create the text circle in this routine.

To transform the text, we will call CircularText.generateText(templateTextField, targetHostClip, options), with all the options being stored in a CircularTextOptions instance. The inner working of these classes will be the matter of the next steps, right now we have to read the values from our components and send them to these objects that will do the job for us. These classes will be stored in the utils.clips package, so we have to make sure we add these contents in the import statements.

We will need a clip in which to place the circle of individual character MovieClips; this will be called animHost.

package  {

	// ....
	// Previous import still here
	import utils.clips.*;	//for the classes we will later create

	public class CircularTextTest extends MovieClip
	{
		/** The movieclip that will 'host' all the created character clips */
		public var animHost:MovieClip;

		protected function createCircularText():void
		{
			// For the purpose of the demo we create a movieclip at the center of the stage
			if (animHost == null)
			{
				animHost = new MovieClip();
				animHost.x = 275;
				animHost.y = 200;
				addChild(animHost);
			} else {
				// We make sure the previous character clips are removed
				for (var i:int = animHost.numChildren; i>0; i--) {
					animHost.removeChildAt(0);
				}
			}

			var options:CircularTextOptions = new CircularTextOptions();
			if (chkTxtOutside.selected) {
				options.characterOrientation = CircularTextOptions.CHARACTER_ORIENTATION_OUTSIDE;
			} else {
				options.characterOrientation = CircularTextOptions.CHARACTER_ORIENTATION_INSIDE;
			}
			options.radius 		 = sliderRadius.value;
			options.radiusOffset = sliderCharOffset.value;
			options.trimWhite 	 = chkTrimWhite.selected;
			options.showAnchors  = chkShowAnchors.selected;
			CircularText.generateText(tfTemplate, animHost, options);

		}

Step 9: Demo Interface Turning Circle

To complete the demo, let’s make the circle turn! To do this we just need to create a Timer object, make it tick 25 times a second, and call an update handler every time it does so. The update function simply increments the circle’s host MovieClip’s rotation property by a small amount. That’s it — you have made it turn.

package  {

	// ....
	// Previous import still here
	import flash.events.TimerEvent;
	import flash.utils.Timer;

		public class CircularTextTest extends MovieClip
		{
			/** A Timer object to call an update callback and spin the circle */
			protected var rotationTimer:Timer;

			protected function createCircularText():void
			{
				// ...
				// Previous code still here

				// We create a timer to turn the movieClip
				if (rotationTimer == null)
				{
					rotationTimer = new Timer(1/25, 0);
					rotationTimer.addEventListener(TimerEvent.TIMER , onTimer, false,0,true);
					rotationTimer.start();
				}
			}

			protected function onTimer(event:TimerEvent):void
			{
				animHost.rotation += 0.1;
			}

Step 10: Main Code Linear Position to Angle

We’ll now convert a linear position to an angle. We will know the linear x position of the text, and we need to transform this to a position on a circle. To convert a point on a segment to a point on a circle, we need a few things:

  • The segment size, which will be the template TextField‘s width. Let’s call this xMax.
  • The x position on the segment, which will be the character position in the template.
  • The circle radius, which we will set.
  • The alpha angle to plot the point on the circle. This angle will be computed from x and the segment size. We will consider adding a phase, which is an offset.

To make things simple: when x will be 0, alpha will also be 0. On the other side when x equal xMax, then alpha = 360° (or in radians: 2*PI).

For all the intermediate positions, alpha = 2*PI * x/xMax (in radians).

We will need this value both in radians – because Math.sin() and Math.cos() ask for it – and in degrees – because we will have to turn our MovieClip to make the character ‘look’ at the center, and MovieClip rotations are in degrees. But we will come back to this in the next part.

If we choose to add an offset (or a phase, at it’s often called for angular values), then it’s just a simple addition to do.

Finally, to get the position of the character on the circle from its center, it’s very basic trigonometry:

clip.x = radius * Math.cos(angleInRadians);
clip.y = radius * Math.sin(angleInRadians);

Step 11: Main Code Common Pitfall

Let’s look at a common pitfall in getting the character positions. The most obvious values that come to mind for xMax is to use the number of characters in your text, and for x, to use the current character’s position. But this is really over-simplified and will lead us to unaesthetic results. If you’re using a monospace font, it will be okay. But if you’re using a more common font, then the offset between two successive values of x will always be the same, whether the character is a small one like a dot or a wide one like w. This means that either some letters will be squashed together or some letters will be spread very far apart.

If our source TextField has complex text formatting, mixing different fonts and font sizes, it becomes obvious that the tenth character out of 20 will almost never be at the center of the TextField.


Step 12: Main Code Spacing and Formatting

We’re going to use the character boundaries to take care of the character spacing and text formatting.

ActionScript provides us with the sourceTf.getBounds(sourceTf.parent); method to get the exact dimensions of the TextField (this method is available for any DisplayObject). The getBounds method requires a target coordinate space. The most common usage of our transformation will be to create the circle at the same level as the template TextField, so we’ll use the template TextField’s parent coordinate space to take care of any higher level transformations.

Using the character position in the source string is too limited, so we won’t use such a basic measure. We will call sourceTextField.getCharBoundaries(nthCharacter) to get the position and size of any character. This will return a Rectangle, so we will know the width of the character and its exact position.

We might want to trim the extra white space before and after the real text, so that you could use a wide dynamic TextField, but only compute the really used text width to place the characters on the circle without extra white space. To do so, we will have to get the actual position of the first and last characters. There’s one caveat: if you’re trying to get the boundaries of a control character, like carriage return, it will return null. Therefore we will loop the latest characters to find the last one which does have boundaries:

var i:int;
var charCnt:int = sourceTf.length;
var charBounds:Rectangle;

// the default 'source' bounds are the whold textFields bounds
var templateBounds:Rectangle = sourceTf.getBounds(sourceTf.parent);

// If we trim the 'extra' white, then the boundaries of the last visible character
if (options.trimWhite)
{
	charBounds = sourceTf.getCharBoundaries(0);
	templateBounds.left = charBounds.left;
	charBounds = null;
	i = 1;
	do {
		charBounds = sourceTf.getCharBoundaries(sourceTf.length-i);
		i++;
	} while (charBounds == null);
	templateBounds.right = charBounds.right;
}

After this code block, the templateBounds variable will have the desired width (as we will see later, option.trimWhite is a Boolean, specifying whether we ignore the extra white space of the TextField).

We now have a correct xMax value, and I guess you’ve understood that we will use the same getCharBoundaries method to get the accurate x position of each character in the source TextField, giving us the x values to use in our formulas above.


Step 13: Main Code Formatting our Parameters

Before going further in coding, we will formalize the options we will handle, and put them all in a parameter class. We will use this “options container” in the next steps to easily cover different variations of circular transformation. This option class could be a simple generic Object, but using predefined constants and values makes the usage of the CircularText class easier, enables strong typing – therefore making it easier to find errors at compile time – and enables us to set default values.

package utils.clips
{
	public class CircularTextOptions
	{

		static public const CHARACTER_ORIENTATION_INSIDE:Number = 90;
		static public const CHARACTER_ORIENTATION_OUTSIDE:Number = -90;

		/** Radius of the circle */
		public var radius:Number = 100;
		/** Angular offset to apply (to make the text spin around the circle */
		public var phase:Number = 0;

		/** Character orientation, can be
		 * CircularTextOptions.CHARACTER_ORIENTATION_INSIDE or
		 * CircularTextOptions.CHARACTER_ORIENTATION_OUTSIDE */
		public var characterOrientation:Number = CHARACTER_ORIENTATION_INSIDE;

		/** Useful for debugging, this option enables the display of the
		 * character anchor points (might help to fine-tune offests, ...) */
		public var showAnchors:Boolean = false;

		/** Offset in pixel from the circle to the character. By setting both
		 * the radius and this offset, you can control the character spacing. */
		public var radiusOffset:Number = 0;

		/** This option sets whether the circle is based on the with of the source
		 * textField or the width of its contents. ('white space' characters
		 * are still computed; this is not a condenseWhite-like option) */
		public var trimWhite:Boolean = true;

		public function CircularTextOptions()
		{
		}
	}
}

Step 14: Main Code Character Placement

We’ve already gone through the math to convert a position on the x axis to a position on the circle. Now we will create new MovieClips for each character and place each one according to its x position, and set its text formatting to match the source format and reproduce the same appearance.

We will need a few local variables to store the intermediate values :

var degrees:Number;
var radians:Number;
var charContainer:MovieClip;
var radius:Number = options.radius;

Then we will start looping through all the source characters

for (i = 0; i < charCnt; i++)
{
	charBounds = sourceTf.getCharBoundaries(i);
	if (charBounds != null) // special chars, like carriage return, do not have bounds, hence this test
	{
		//...
	}
}

As this snippet tells you, some characters don’t have boundaries, so we need to take care of them. We don’t need to display invisible characters.


Step 15: Main Code Character Orientation

Before converting the original x to its angular position, we need to take care of the character orientation: if the character will look ‘inside’ the circle, then the angle grow with the x value. If we decide to make the characters look to the ‘outside’ of the circle, then it will be read like with a mirror, and we need to invert the angle growth, otherwise it would not really be readable.

If the text is looking ‘inside’, we will arrange the characters clockwise. If the text is facing ‘outside’, we need to turn counter-clockwise while placing the characters.

If this is still not clear, just change the minus in options.phase - (charBounds.right - 0.5*charBounds.width) * 360/templateBounds.width to a plus and publish it to see immediately how it would look if you do not take care of the character orientation. Finally we convert the degrees to radians, as the sin() and cos() need angles in radians for their arguments.

// Compute the angular offset of the char based on its metrics
if (options.characterOrientation == CircularTextOptions.CHARACTER_ORIENTATION_INSIDE)
{
	degrees = options.phase  + (charBounds.left + 0.5*charBounds.width) * 360/templateBounds.width;
} else {
	degrees = options.phase  - (charBounds.right - 0.5*charBounds.width) * 360/templateBounds.width;
}
radians = degrees*(Math.PI/180);

Now we can create the container for the character and place it in our host, taking care of the angle we have just computed:

charContainer = new MovieClip();
if (options.characterOrientation == CircularTextOptions.CHARACTER_ORIENTATION_INSIDE)
{
	charContainer.rotation = Math.round(degrees)+ options.characterOrientation;
	charContainer.x = radius * Math.cos(radians);
	charContainer.y = radius * Math.sin(radians);
} else {
	charContainer.rotation = Math.round(degrees)+ options.characterOrientation;
	charContainer.x = radius * Math.cos(radians);
	charContainer.y = radius * Math.sin(radians);
}
host.addChild(charContainer);

Remember that the characterOrientation value will be one of the following numbers, so the options.characterOrientation used here will turn the character, making it face the desired direction without additional calculations:

public class CircularTextOptions
	{
		static public const CHARACTER_ORIENTATION_INSIDE:Number = 90;
		static public const CHARACTER_ORIENTATION_OUTSIDE:Number = -90;

Step 16: Main Code Formatting

Now that we have created a MovieClip host for this character, placed it along the circle and turn it in the right direction, we should put something in it, like a TextField with the character, otherwise nothing would be visible ;-)

This is pretty basic: create a new TextField, and set all its attributes. The most important one is to use embedFonts, so that the text will still be visible after being rotated.

// Set Text and TextFormat
newTf  = new TextField();
newTf.type		  = TextFieldType.DYNAMIC;
newTf.selectable    = false;
newTf.embedFonts    = true;
newTf.autoSize      = TextFieldAutoSize.CENTER;
newTf.antiAliasType = AntiAliasType.NORMAL;
newTf.text = sourceTf.text.charAt(i);

We have a TextField with the text in it, now we have to format this text to looks like the original. We will use a try/catch to warp the setTextFormat because if something goes wrong in your text formatting, because of missing fonts, the error will pop up here, and this will help you debug your font issues.

charTf = sourceTf.getTextFormat(i);
try {
	newTf.setTextFormat(charTf);
} catch (e:Error) {
	trace('textFormat error');// place a breakpoint here to watch for potential font issues...
}

Finally we have to center the TextField into the target MovieClip we created in the previous step, to make sure they look aligned on the circle. The radiusOffset parameter we use here complete the circle radius: when fine-tuning the look of your circular text, having both the circle radius – which set where the character containers are – and an offset make easier to set the desired character spacing. It could be totally done without this offset, but makes life easier for some designer working with our snippets.

newTf.x = -(charBounds.width)/2;
newTf.y = -(charBounds.height) + options.radiusOffset;

That’s it, we’re done. We have gone through all the steps and now have a fully working routine.


Step 17: Main Code Class so Far

And here comes the complete CircularText class we have built throughout the steps of this tutorial:

package utils.clips
{
	import fl.text.TLFTextField;

	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	import flash.text.AntiAliasType;
	import flash.text.Font;

	/**
	 * Use CircularText.generateText(templateTextfield, targetMovieClip,
	 * options) to create a well-spaced character distribution around a circle
	 * in the target movieclip.
	 */
	public class CircularText
	{

		public function CircularText()
		{
		}

		/**
		 * @param sourceTf  The Textfield wich is used as source and template.
		 * 					Typically a dynamix textField, invivisible, in which
		 * 					the text and textFormat are set by the rest of the
		 * 					program.
		 * @param host		The target movieClip in which the text circle will
		 * 					be created.
		 * @param options	A CircularTextOptions object with formatting option
		 * 					to make the text circle looks like we want to.
		 */
		static public function generateText(sourceTf:TextField,
											host:MovieClip,
											options:CircularTextOptions=null):void
		{
			if (options == null) options = new CircularTextOptions();

			// We explode the original textField into smaller clips, each one containing a character

			var newTf:TextField;
			var charTf:TextFormat;
			var i:int;
			var charCnt:int = sourceTf.length;
			var charBounds:Rectangle;

			// the default 'source' bounds are the whold textFields bounds
			var templateBounds:Rectangle = sourceTf.getBounds(sourceTf.parent);

			// If we trim the 'extra' white, then the boundaries of the last visible character
			if (options.trimWhite)
			{
				charBounds = sourceTf.getCharBoundaries(0);
				templateBounds.left  = charBounds.left;
				charBounds = null;
				i = 1;
				do {
					charBounds = sourceTf.getCharBoundaries(sourceTf.length-i);
					i++;
				} while (charBounds == null); // Take care of null-boundareis character like carriage return	

				templateBounds.right = charBounds.right;
			}

			var degrees:Number;
			var radians:Number;
			var charContainer:MovieClip;
			var radius:Number = options.radius;
			for (i = 0; i < charCnt; i++)
			{
				charBounds = sourceTf.getCharBoundaries(i);
				if (charBounds != null) // special chars, like carriage return, do not have bounds, hence this test
				{
					// Compute the angular offset of the char based on its metrics
					if (options.characterOrientation == CircularTextOptions.CHARACTER_ORIENTATION_INSIDE)
					{
						degrees = options.phase  + (charBounds.left + 0.5*charBounds.width) * 360/templateBounds.width;
					}else {
						degrees = options.phase  - (charBounds.right - 0.5*charBounds.width) * 360/templateBounds.width;
					}
					radians = degrees*(Math.PI/180);

					// Create a new Textfield to render this character
					newTf  = new TextField();
					charTf = sourceTf.getTextFormat(i);

					// Set Text and TextFormat
					newTf.type = TextFieldType.DYNAMIC;
					newTf.selectable = false;
					newTf.embedFonts = true;
					newTf.autoSize = TextFieldAutoSize.CENTER;
					newTf.antiAliasType = AntiAliasType.NORMAL;

					newTf.text = sourceTf.text.charAt(i);
					try {
						newTf.setTextFormat(charTf);
					} catch (e:Error) {
						trace('textFormat error');// place a breakpoint here to watch for potential font issues...
					}

					newTf.x = -(charBounds.width)/2;
					newTf.y = -(charBounds.height) + options.radiusOffset;

					charContainer = new MovieClip();
					if (options.showAnchors)
					{
						// here comes the graphic aspect of the anchors, if you want something else
						charContainer.graphics.beginFill(0xff00ff, 1);
						charContainer.graphics.drawRect(0,0,5,5);
						charContainer.graphics.endFill();
					}
					charContainer.addChild(newTf);

					if (options.characterOrientation == CircularTextOptions.CHARACTER_ORIENTATION_INSIDE)
					{
						charContainer.rotation = Math.round(degrees)+ options.characterOrientation;
						charContainer.x = radius * Math.cos(radians);
						charContainer.y = radius * Math.sin(radians);
					} else {
						charContainer.rotation = Math.round(degrees)+ options.characterOrientation;
						charContainer.x = radius * Math.cos(radians);
						charContainer.y = radius * Math.sin(radians);
					}

					host.addChild(charContainer);
				}
			}

		}
	}
}

Step 18: Main Code Apply the Transformation

We have seen all the parts, and put them together in a utility class. Now we have just to call this method to generate a circular display of the TextField.

// tfTemplate is the TextField containing the source text to transform
// animHost is a movieClip in which we will create the circle
var options:CircularTextOptions = new CircularTextOptions();
options.characterOrientation = CircularTextOptions.CHARACTER_ORIENTATION_INSIDE;
options.radius 		 = 50;
options.radiusOffset = 0;
options.trimWhite 	 = true;
options.showAnchors  = false;
CircularText.generateText(tfTemplate, animHost, options);

Does this code look like something you’ve already seen? Well it should, because this sample usage is really close to the createCircularText method we built at the beginning. Now you might see that almost everything is in place.


Step 19: Main Code A Simple Demo

Now that all the code is complete, you might compile the demo we have built in the first steps (or open it from the downloadable sources).

For those who jumped over the first section, the code in the demo is very basic: simple listeners to update the circular text when something is changed. It has an addedToStage listener to set up the other listeners on the input components (a TextField, some Sliders and some Checkboxes); several listener functions which all call the createCircularText(); and this createCircularText() routine which sets up the options object with the values read from the components and calls the CircularText.generateText method exactly like in our snippets above.


Step 20: Main Code Creating Subclasses

Typically if you’re on a project which involves several displays of circular text, you might find it useful to create inherited styling subclasses, like SmallCircularTextOptions and LargeCircularTextOptions to set the default values you want to use in each case. This way you won’t have to type the parameters each time you need to generate a text transformation.

public class SampleSmallCircularTextOptions extends CircularTextOptions
{

	public function SampleSmallCircularTextOptions()
	{
		super();
		radius = 50;
		characterOrientation = CHARACTER_ORIENTATION_INSIDE;
		// showAnchors = AppManager.isDebug; // Here read the debug setting from your application
	}
}

With this class, creating the circular text only requires a source TextField and a target MovieClip to host the circle, giving us a really small amount of code:

// tfTemplate is the TextField containing the source text to transform
// animHost is a movieClip in which we will create the circle
CircularText.generateText(tfTemplate, animHost, new SampleSmallCircularTextOptions());

Step 21: Extension Circle to a Spiral

Do you want to go further? If this is the kind of transformation you use in your projects, you might notice that it is now really easy to modify the coordinate calculations to create something else than a circle. Here we will quickly look at how to make a spiral.

So let’s start by thinking about how to plot our point on a spiral. Basically there are two differences from placing the letters on a circle and alongside a spiral:

  1. The radius from the center to a character is not constant: each step the radius is increased (or decreased) by a small amount when walking along a spiral
  2. The path length might be longer than just 2*PI*Radius, so that the characters go ‘below’ the previous ones.

Here comes the updates of the CircleTextOptions variables to be able to store these two parameters:

/* ---- Spiral specific options ---- */
/** By default, only 1 turn, therefore a circle */
public var turnCount:Number = 1;
/** Damping make the 'circle' radius smaller (or bigger) each time;
    if it's equal to one, then the radius doesn't change */
public var spiralDamping:Number = 1;

Then we need to update our CircularText.generateText() method to take care or these parameters. As mentioned, the radius will no longer be constant.

var radius:Number = options.radius;
for (i = 0; i < charCnt; i++)
{
	// Spiral update : after each character the spiral damping is applied
	radius *= options.spiralDamping;

This way, the initial radius value will be the same as our circle. Then for each character it will be multiplied. The default value of 1 will keep the radius unchanged, but if we set a slightly smaller amount, like 0.97, the radius will be smaller each step.

Then we want to control the length of the spiral. Just after calculating the degrees value for the current character, we want to multiply it by the turn count of the spiral. If the spiral loops only one time, it will be like a circle (if the radius is left unchanged). If the spiral loops more than one time, the characters will overlap. So the degrees value has to be multiplied by turnCount to transform our value for 1 turn to its new value for n turns.

degrees = options.turnCount * degrees;

That’s it, nothing more to do to have a customizable spiral! You might want to edit the createCircularText() method of the test class CircularTextTest to try it.

// Previous option settings still there ...
// Spiral update : We will use a damping != 1 and a number of turn != 1
options.turnCount 	  = 1.5;
options.spiralDamping = 0.97;

CircularText.generateText(tfTemplate, animHost, options);

And here comes the corresponding updated SWF. You might want to add sliders to control the turnCount and damping values if you want to play with different values easily.


Conclusion

I hope this tutorial successfully highlighted the common pitfalls one will encounter while playing with text measurements, exploding a TextField and recreating the original text formatting. Do play with the sources and fine-tune it to your needs. Thanks for reading!



View full post on Activetuts+

Page 1 of 812345...»Last »
search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • Tuts+ Community Meetup in New York!
  • HTML5 Canvas Optimization: A Practical Example
  • Recreate the Cover Flow Effect Using Flash and AS3
  • Drawing Activetuts+ to a Close
  • Intro to Dart: Creating a Marquee
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character Code Create Creating Critique Custom design Effect Effects Files Flash from Game Guide HTML5 Introduction Macromedia Motion Muzzle part Player Premium Professional Quick Silverlight Simple Text Tool Tutorial Tuts+ Using Video website Workshop
About Our Site:

Hey there and welcome to "Flash Video Training Source", a resource for anybody interested in learning more about Adobe's great tool. We feature educational videos, which will help you master Adobe Flash and help you get to know all of its features. We at "Flash Video Training Source" believe that video training and video... more

Why don't you follow us on Twitter and get the latest video tutorials twitted to your account. Just click on the floating twitter bar to your right!

Go Back In Time
June 2013
M T W T F S S
« Jul    
 12
3456789
10111213141516
17181920212223
24252627282930
Pretty Blank Box
top

Blogroll

  • Development Blog
  • Documentation
  • Plugins
  • Suggest Ideas
  • Support Forum
  • Themes
  • WordPress Planet

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Archives

  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
Powered by WordPress  |  Designed by Elegant Themes  |  Lightning Fast Hosting by Site 5 Hosting