Font blurring problems when embedding Captivate SWFs
A current project sees us producing short simulations using Adobe Captivate and embedding the resulting SWF in our own e-learning application.
Our application is deployed using Steven Sacks’ Gaia Flash framework, and loads the Captivate content as an ‘Asset’. Some custom XML parameters let us specify the exact width and height, but despite matching the Captivate settings exactly we were seeing a mysterious font-blurring effect that simply wasn’t there when we viewed the Captivate content outside our application.
It turns out our problem was in the use of customised UI elements in Captivate. We’d imported some button art at an incorrect size and resized it within Captivate. Ordinarily this wouldn’t be an issue because (we discovered) Captivate does some (ahem) ‘magic stage resizing’ in the background when it’s running as a standalone element, and the ‘magic’ wasn’t happening when it was embedded in our Gaia application.
The solution was an old one… ‘do everything exactly right the first time’ – ensure all button and UI art was at the correct dimensions, removing the need for Captivate to do any ‘magic stage resizing’ and restoring complete clarity to our text.
OMG! Specific Flash accessibility techniques, code samples and tests for WCAG 2.0
Historically it’s been difficult to find meaningful help when trying to make Flash content comply with the old W3C, and more recently WCAG2.0, accessibility requirements. This W3C draft list of Flash Techniques for WCAG2.0 is (a draft version) of the final word.
It includes detailed instructions for the Flash IDE Accessibility panel, example AS2 and AS3 implementations, and tests to ensure compliance for 35 different Flash scenarios. I love this list because it makes it easier for me to explain the amount of work in ‘making it accessible’ to colleagues who don;t really ‘get’ accessibility.
More than that, it gives testable code examples of specific implementations and explains them in multiple contexts. Thankyou W3C!
Because it’s currently a draft document you won’t find these techniques in the ‘How To Meet WCAG 2.0 Checklist‘. Comments close on August 9.
‘Fluxus’ – Flex and Actionscript Library / Package management repository (think Ruby Gems or Perl CPAN)
Described by one of the project owners as ‘like RubyGems for the Flash platform’, the Fluxus Project currently provides a database of AS3 libraries, and will ‘soon’ feature a command-line interface to the database, and a GUI to manage your local ‘Fluxus’.
Anyone already on GitHub should ‘watch’ this, it’s gonna get seriously useful. And if you’ve got skills you can use to help the community out then head over to http://fluxdb.fluxusproject.org/
Check it out – over 270 AS3 libraries and counting!
AS3 _targetInstanceName equivalent is scrollTargetName
Back in the MX2004 day we could use the _xch clip in the Flash IDE to help us determine the name of any asset we dropped our component onto. Excessive Googling hasn’t turned up anything useful so, dear reader, this is for you.
In the CS4 library, select your component clip, right-click and choose ‘Component Definition‘. Add a parameter called scrollTargetName, give it a variable name of ‘scrollTargetName‘. In your component class, ensure you have getters and setters for ‘scrollTargetName‘ and for ‘scrollTarget‘, like this:
Now update your component by selecting ‘Component Definition’ again, but this time just clik ‘OK‘ to force the update.
Now place a TextField or MovieClip onstage and give it an instance name, then drag your updated component from the library onto the test clip. If you check the Component Parameters panel you should see that it’s automagically populated with the instance name of your example clip, just like _targetInstanceName used to. Dragging it onto other named instances should also update the parameter in the panel. Dragging your component onto an unnamed instance forces a default instance name, couldn’t be sweeter!
I also implemented some functionality that (via the SWFPanel of my component) auto-positions the dropped component instance at the top-left of its’ target instance. Let me know in the comments if you want to see how this is done.
Building an AS3 FLA based component with a SWFPanel and a LivePreview
In learning how to make AS3 components I found a large amount of frustration with Adobe’s documentation. Every useful resource I found had a slightly different (yet valid) approach to the finer points of component development. It seems everyone has a different solution depending on their requirements, so be prepared to read a lot before you dive in.
The online resources I used were:
- The exhaustive Jeff Kamerer articles on the Adobe site based on the UIComponent framework
- A non-UIComponent solution from David Barlia’s ‘Studio Barliesque’ blog
- A slightly less complex implementation than mine at RedBjarne’s Blog
- A shorter, simpler article by Chris Sperry
- Useful background info about custom parameter UIs (SWFPanels) and JSFL from Keith Peters
- Adobe documentation for JSFL in Flash CS4
Example files:
My finished files are available here for download. Because this component requires some absolute filepath parameters I recommend:
- Placing the extracted directory at the root level of your ‘C’ drive
- Macintosh users will need to replace the current ‘c|’ characters with the relevant drive name and delimiter characters.
OK, on with development…
My requirements
I needed a component that could be used by (low tech-savvy) design staff to preview external text in the Flash IDE. The text is HTML tagged CDATA within an XML document. The project uses embedded fonts too, so it was critical that what appeared in the IDE was exactly what appeared in the published SWF.
In a nutshell, I needed an AS3 component with a LivePreview (to load and correctly display the embedded fonts), and a SWFPreview (to display the component parameters in a more legible fashion that the standard Flash component parameters panel).

This image shows XMLTextArea Component instances displaying CSS styled HTMLText in the Flash CS4 IDE with an embedded font (the font is NOT an active Windows font, it's embedded in a SWF that's loaded for use by the LivePreview). Note the list items in the bottom instance, they're indented using CSS, not by the addition of 'space' characters into the text.
Step 1: Creating the ‘shell’
Setting up a development workflow is straightforward as long as you remember the 3 elements of the component (runtime, live preview, SWF panel). I made a directory with some empty FLAs first:
- XMLTextAreaComponent.fla (to contain and test the component during development)
- XMLTextAreaComponentLivePreview.fla (to build the LivePreview SWF that you’ll see in the Flash IDE while authoring with component), and
- XMLTextAreaComponentSWFPanel.fla to develop a functional UI instead of using the Component Parameters panel.
Next, create the Document classes for each of these FLAs. Using a consistent naming convention throughout development is critical, it lets me focus on the problems that need solving instead of wondering which class or fla I’m looking at. The Document classes are named as follows:
- com.ui.textarea.component.XMLTextAreaComponent.as
- com.ui.textarea.component.XMLTextAreaComponentLivePreview.as
- com.ui.textarea.component.XMLTextAreaComponentSWFPanel.as
You can download my finished Flash CS4 (Windows) files from here. I’d recommend putting the directory at the root of your ‘C’ drive, that way you couldn’t need to change any of the component instance parameters to see the XMLTextAreaComponentTest.fla functioning correctly.
Step 2: Build the SWFPanel
For me, the SWFPanel is the logical place to start. It focuses attention on the functional requirements of the component. The XMLTextArea needs a relatively large amount of startup configuration (text source, stylesheet, external fonts, author-time and runtime location info) that would be inconvenient to set using the standard Component Parameters panel.

This image is a populated SWFPanel for one of the onstage instances of the component. This is currently quite clumsy looking, but it points each instance to its XML text file, SWF containing the embedded fonts and stylesheet at runtime and author-time.
First I laid out my SWFPanel UI (XMLTextAreaComponentSWFPanel.fla), then named my component instances. I always have ‘Automatically declare stage instances’ turned off in my FLAs, so in the com.ui.textarea.component.XMLTextAreaSWFPanel class you’ll see I’ve declared each component instance as follows:
When we change something in the SWFPanel we need to communicate that change explicitly to the selected onstage instance of the component. Conversely, the SWFPanel also needs to be initialised with the onstage component instance parameters. Here are the JSFL commands to retrieve the onstage instance values:
…and here’s how we populate the SWFpanel (see the init() method of the XMLTextAreaSWFPanel class) when an instance of the component is selected onstage:
Lastly, we need to update the component parameters of the onstage instance whenever we use the SWFPanel to make changes. I do that with event listeners that issue more JSFL commands, like so:
The rest of the XMLTextAreaComponentSWFPanel class just implements these concepts for all the other UI widgets. The important concepts are:
- the SWFPanel uses JSFL to communicate with the onstage instance
- it’s one-way communication, the SWFPanel does all the work of interrogating onstage instances and updating itself
- the component instance can’t dynamically talk to the SWFPanel, other than when it’s selected, and that’s only to expose its component parameters.
To test the JSFL communication we need to connect the SWFPanel up to a component instance, so the next step is to build a basic version of the component, give it some parameters and connect it to the SWFPanel.
Step 3: The Component – parameters
OK, next I create the basic component. Make a MovieClip, then in the Library right-click and select ‘Component Definition’. For this one I enter the Class as ‘com.ui.textarea.component.XMLTextAreaComponent‘ and point the ‘Custom UI’ field to ‘XMLTextAreaComponentSWF.swf‘. During development I prefer to use the ‘Custom UI in external .swf file’ option. It makes updating much quicker if I make changes to the SWFPanel for any reason. In addition to setting the class in the component definition I also needed to set the Linkage ID in the ‘Properties’ panel.
Because I’m still a component newbie (and it’s hard enough to keep track of the basics right now), I’ve chosen to extend the UIComponent class and override the ‘configUI()’ method. I set up my component clip with the same 2 frame structure discussed in the Jeff Kamerer articles on the Adobe site and it worked for me (i.e. compiled without errors) immediately.
Once you’ve linked the component clip in your Library to the component class file you’ll find that any changes you make to the ‘Parameters’ list in the ‘Component Definition’ panel won’t be saved. This is because the component now looks to the Class you nominated for its’ parameters. These need to be defined with getters and setters like so:
I found that unless I included the ‘name’ parameter in the ‘Inspectable’ metadata the component parameter wasn’t available to me from JSFL in the SWF panel. Dunno why, it just worked for me this way. This process was repeated for all component parameters, then I right-clicked the component movieclip in the Library and chose ‘Component Definition’, and clicked ‘OK’ again. We need to do this anytime we make changes to the component class that would affect it’s functionality in the Flash IDE. Since we’ve just added component parameter getters and setters in the component class we need to update it before it can be properly tested.
Now I tested the communication between my SWFPanel UI widgets and the onstage component instances.
Step 4 – The LivePreview
This is probably my favourite part of FLA-based component development because it brings completely customised functionality and appearance to the Flash IDE. From within the IDE the LivePreview loads the fonts, CSS and HTML, and renders the text onscreen exactly as it renders at runtime. Designers can work with visible, correctly styled external HTML text, and all the text remains external to the FLAs (so translation or revision can be completed with no recompiling).
The basic framework of a LivePreview SWF can be seen in my example files:
- The Document Class of the LivePreview.fla should be set to fl.livepreview.LivePreviewParent
- In frame 1 on the timeline, a clip (with a Linkage to the XMLTextAreaComponentLivePreview class) that contains an onstage instance named ‘avatar_mc’. (I also included a TextArea component and some dynamic TextFields, but later converted these to guide layers, they’re still present in my example files).
- The XMLTextAreaLivePreview class extends UIComponent and overrides the setSize() and draw() methods
- All the component parameters need getters and setters in the XMLTextAreaLivePreview class to access their values in the IDE at authoring time.
All the action in my component happens in the draw() method after the fonts, XML and CSS are loaded and parsed.
NB: The onstage LivePreview won’t update dynamically while you’re resizing it. This is also a constraint of the components provided by Adobe, so I didn’t stress too much about finding a solution. If you have one, please leave a note in the comments.
Step 5 – Deployment
All our Flash team members (designers and developers) are also connected to our classes via SubVersion. Currently the component is in ‘beta’, being tested by a couple of key staff, so I haven’t yet prepared an MXP for distribution. When that happens I’ll add my notes here.
Finally
There’s one more ‘dirty little secret’ in this component. When I changed the ‘visibleXMLText’ component parameter in an onstage instance, it wouldn’t automatically refresh the view (even though it could trace out the updated text) so I used JSFL to deselect and reselect the component in question (found the technique here). Unfortunately it breaks the Flash ‘undo’ functionality for any onstage instance of this component. Yes, it sucks, but it’s not a showstopper. Again, if you have an idea that might work, tell me in the comments please.
Combining the Timeline with OOP AS3 in Flash – InsideRIA
My team currently has 3 graphic designers (only one of whom can code, and that’s currently restricted to timeline code) and 2 Actionscript coders. Our workflow relies on designers laying out screen content and coders ‘connecting it up’.
As a result we use a lot of OOP classes, but also make use of a lot of timeline code. It lets everyone work together in relative harmony, allows team members to work relatively independently and lets us get the job done quicker.
Our standard practice is to declare stage instances on frame 1, no matter what, and ensure they exist across the entire timeline, hiding and showing when necessary. It works, but it ain’t elegant. This is the next level…
Articulate Engage content inside an AS3 Flash container? Well, almost…
Articulate’s Engage software is a quick and polished way to create eLearning interactions. Unfortunately, it’s also built from the ground up in AS2.
So while the Engage content SWFs can be loaded into an AS3 container, you definitely can’t use images in your Engage content because the XML onLoad event fails to fire when AS2 content is loaded into an AS3 container.
I used ‘Charles‘ to see what HTTP requests were being sent and noticed that:
- When browsing directly to the Engage SWF a GET request for the image is sent immediately after the Engage content XML is loaded; and
- When browsing the Engage content after it’s loaded into my AS3 container the GET request for the image is never sent.
While it’s not cast-iron proof I think it’s safe to assume that an ‘onLoad’ event for the XML might not be firing, so the Engage SWF hangs, waiting for confirmation that never comes.
While it’s not completely crippled (text-only interactions are just fine) this reduces the usefulness of Engage content in any Flash environment that’s been built in the last few years.
Making Flash Accessible – A pragmatic approach
My first serious exposure to Flash and accessibility was in 2004. One of my problems then was my understanding of accessibility. That’s improved a little, but the landscape changes (along with Flash and Actionscript) and since then I still haven’t found a solution that lets me produce ‘accessible’ content with the same effort as my usually inaccessible work.
While I don’t have anything I’d call a ‘complete solution’ I’ve used a number of partial solutions along the way:
- providing an onscreen link to an HTML-only version of the interactive content. This is never a straight copy of the text content. It’s a re-write of the interactive content as though it were an article, delivering the intended message without any audio, video, animation, images or colour. It’s the quickest way I’ve found to give a version of the content that’s accessible to the maximum number of assistive technologies with the minimum of production effort (and cost to the client);
- providing Flash content that is visible to MSAA enabled assistive technologies (like the JAWS screen reader) and also ‘wired up’ for keyboard navigation; and
- customised captioning combined with keyboard navigation, like this example (from 2004) to provide content accessible to hearing-impaired users and keyboard-only users.
AFAIK, obstacles that still stand in the way of convenient production of accessible content in Flash include:
- Flash still isn’t happy talking to Apple’s assistive technology. We can still only rely on MSAA as a technology bridge between the Flash Player and the real world (in this case, Microsoft’s real world);
- The vast number of impairments and their relevant assistive technologies. As well as additional development time it presents a massive overhead in testing. I’ve never yet been able to successfully justify the additional cost of purchasing the most basic assistive technologies (JAWS, a workstation to test on) to any employer.
So where to from here? I need to assume that there won’t usually be the budget or resources for producing multiple versions of the content, so I think the majority of my clients (Australian, so our legislative requirements aren’t yet as stringent as the US) would be happy with keyboard and screenreader accessibility.
For static content that’s fine, but interactions (beyond standard component-based radio-button and checkbox interactions) will need to be designed and coded quite differently, or ignored altogether.
If you’ve read this far you might already have pragmatic solutions to these problems – what are you doing about them?
Remedial TextFormat instructions…
Don’t waste that extra hour wondering why your embedded Flash fonts (textField.embedFonts = true) aren’t working… Make sure your ‘setTextFormat’ happen AFTER the text has been applied (via htmlText, or CSS, or inline font selection)
AS2 to AS3 conversion? Save on typing!
Jobe Makar has a nice little utility to do the finger-numbing basics of class conversion from AS2 to AS3. Get it here










