Random Etc. Notes to self. Work, play, and the rest.

Simple Text Outlines in Flash

(This post is part of the series I threatened to write about actionscript 3.)

For the mySociety travel time maps I wanted to have user-defined labels that looked pretty much like the map styles in the OpenStreetMap base maps we were using, like this one:

London SW1P 4DR, from OpenStreetMap.org (licensed CC-BY-SA)

It turns out Flash doesn't have a way to draw the outlines of text easily, nor does it have a stroke filter like Photoshop. I tried a few different solutions that didn't work out, including a combinations of ConvolutionFilters (too hard to get right), GlowFilters (too blurry) and stacks of offset BevelFilters (nasty looking edges). Since the only thing in Flash that has the same quality antialiasing as the text does is, well, more text, that's what I ended up using. It looks like this:

Flash Text Outlines

I've included a sample SWF and pulled out the relevant AS3 code (for Flex Builder) in the full post, below.

 
 
package {
 
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.text.AntiAliasType;
  import flash.text.TextField;
  import flash.text.TextFormat;
 
  [SWF(backgroundColor="#808080")]
  public class TextOutlines extends Sprite
  {
 
    public function TextOutlines()
    {
      stage.align = StageAlign.TOP_LEFT;
      stage.scaleMode = StageScaleMode.NO_SCALE;
 
      var tf:TextField = new TextField();
      tf.antiAliasType = AntiAliasType.ADVANCED;
      tf.defaultTextFormat = new TextFormat("Helvetica", 18);
      tf.textColor = 0xffffff;
      tf.text = "Sample Outlined Text";
      tf.x = 5;
      tf.y = 5;
      tf.width = tf.textWidth + 4;
      tf.height = tf.textHeight + 4;
 
      var background:Sprite = new Sprite();
 
      var borderWeight:Number = 2;
 
      for (var i:int = -borderWeight; i <= borderWeight; i++) {
        for (var j:int = -borderWeight; j <= borderWeight; j++) {
          if (i == 0 && j == 0) continue;
          var otf:TextField = clone(tf);
          otf.selectable = false;
          otf.textColor = 0x000000;
          otf.x = i;
          otf.y = j;
          background.addChild(otf);
        }
      }
 
      background.x = tf.x;
      background.y = tf.y;
 
      background.cacheAsBitmap = true;
      background.mouseEnabled = false;
      addChild(background);
 
      addChild(tf);
    }
 
    public function clone(tf:TextField):TextField
    {
      var otf:TextField = new TextField();
      for each (var prop:String in ['defaultTextFormat',
                                    'antiAliasType',
                                    'text',
                                    'width',
                                    'height']) {
        otf[prop] = tf[prop];
      }
      return otf;
    }
 
  }
 
}
 

1 Comment

Although I am not too familiar with the flex environment I am with the Flash IDE. One option I have just found, especially if you are using flash player 8+ is to add a glow filter to the textbox, with blurx and blury = 3 and strength = 300% there is a nice outline around the dynamic text.

Posted by Luke on 1 February 2008 @ 2pm