Trevor McCauley did the hard part years ago, as is often the case, but it seems like there's no source code out there showing text along a path in Flash using actionscript 3. I'm not the only one thinking about this – the degrafa folks have got the extremely capable algorithmist Jim Armstrong looking into the problem too.
I don't have time to write a full explanation tonight (packing calls, tomorrow I'm in Montréal for Design Engaged), but I've got a quick solution which might be of use to you if you googled upon this page. Read on for more if you're interested in a quick overview.
Today's post is about tiny details.
I've noticed a frustrating problem with text in Flash that I've finally managed to find a workaround for. I'm testing in Mac OS X using Firefox 3 and Flash 9, but I've seen it on other systems too, and recently had help reproducing this bug from our client at MSNBC, so I'm pretty sure it's widespread.
Since this is a fairly esoteric issue that will only bother Flash programmers, I'll continue only in the full version of this post.
(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:

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:

I've included a sample SWF and pulled out the relevant AS3 code (for Flex Builder) in the full post, below.
This is the second in a series of posts about actionscript 3 that I announced earlier, and my last for today. Here's the feed of posts tagged as3.
Testing for the existence of a property on an Object is simple in actionscript 3:
var object:Object = { sub: "sub" }; trace("testing object properties"); if (object.sub) { trace("CORRECT: object has a sub element"); } else { trace("WRONG: object has no sub element"); } if (object.nosub) { trace("WRONG: object has a nosub element"); } else { trace("CORRECT: object has no nosub element"); }
This yields the correct output:
testing object properties
CORRECT: object has a sub element
CORRECT: object has no nosub element
However, the same thing isn't as intuitive with XML and E4X:
var xml:XML = <xml><sub>sub</sub></xml>; trace("testing xml element"); // don't do this, it will give false positives! if (xml.sub) { trace("CORRECT: xml has a sub element"); } else { trace("WRONG: xml has no sub element"); } // don't do this, it will give false positives! if (xml.nosub) { trace("WRONG: xml has a nosub element"); } else { trace("CORRECT: xml has no nosub element"); }
This gives incorrect output:
testing xml element
CORRECT: xml has a sub element
WRONG: xml has a nosub element
The way to test reliably for the existence of xml elements is to check the length() method on the element:
trace("testing xml length()"); // this works to test for the existence of an element if (xml.sub.length()) { trace("CORRECT: xml has a sub element"); } else { trace("WRONG: xml has no sub element"); } // this also works to test for the non-existence of an element if (xml.nosub.length()) { trace("WRONG: xml has a nosub element"); } else { trace("CORRECT: xml has no nosub element"); }
This yields the correct output:
testing xml length()
CORRECT: xml has a sub element
CORRECT: xml has no nosub element
Hey, it's boring but true!
This is the first in a series of posts about actionscript 3 that I announced earlier. Here's the feed of posts tagged as3.
Even with the great speed improvements that actionscript 3 and Flash 9 offer over actionscript 2 and Flash 8, I've occasionally had the need to revisit a project and look for places to optimise.
Miscellaneous Tips
Here's a list of suggestions I recently made to Gabe, who has his own actionscripting notes, as he was revisiting an old project looking to reduce CPU usage.
Tweaking the framerate
Simply dropping the framerate of an application might work as far as CPU usage goes too.
(Be careful with this though - if you're watching exclusively watching the CPU meters, and not the app, you might be optimising for the wrong audience!)
You can do that with the SWF metadata tag above your main app class in Flex Builder. The main bit is [SWF(frameRate='15')] but check the help file as you might have background colours and width/height in there already.
Memoization
You probably won't need it, but the trick used in Digg Arc (for calculating arc points before redrawing them) was to use what's called memoization — it helps with space-time trade-offs.
The idea is to remember the results of calling a function with certain arguments and only recalculate when the arguments change.
e.g. You might have a function that you're calling it a lot with the same values e.g. calculatePoints(1,2,3,4) that looks a bit like this:
function calculatePoints(a,b,c,d):Array
{
var points:Array = [];
/*
lots of heavy math with a,b,c,d and points
*/
return points;
}
Instead of calculating every possible variation, you can create a hash of the common results:
private var results:Object = {};
function calculatePoints(a,b,c,d):Array
{
var key:String = [a, b, c, d].join();
var points:Array = results[key] as Array;
if (points) {
return points;
}
else {
points = [];
}
/*
lots of heavy math with a,b,c,d and points
*/
results[key] = points;
return points;
}
Then if calculatePoints is called again with 1,2,3,4 you grab the answer from your results Object and return that instead of calculating it again. You probably want to set a limit on the number of things you cache though, so don't use this technique without thinking about that, and only consider this if your performance bottleneck is definitely one maths-heavy function!
Caveat Optimisor!
The only way to be sure about optimisations is to time things, manually or in your development environment, and bear in mind that even to experienced coders some performance issues can be unintuitive.
I've been programming interactive maps visualisations using Flash and Actionscript 3 for almost a year now. Actionscript 3 code is what's behind the scenes of most the Flash work I've been involved with at Stamen so far: Trulia Hindsight, Digg Arc, Twitter Blocks, Modest Maps and more.
So in the spirit of writing about what's important to me (and what I'm actually doing) instead of only writing tangential asides, I'm going to start writing occasional notes on Actionscript 3 here. Hopefully the ideas explored will contribute to my upcoming workshop at Etech in San Diego in March.
I considered starting a new blog, but I've had to deal with my fractured blogging personae twice before already. Hopefully there'll be enough visualisation and project links to keep non-coders interested.
All kinds of people read this blog for all kinds of reasons, you might not care who I spent New Year with and that's OK with me. The actionscript posts will be tagged with as3, if that's all you're interested in you can subscribe to a feed of them here. (The same is true of the Processing posts, which have a feed here).
© Random Etc.. Powered by WordPress using the DePo Skinny Theme.