I’ve just made my first commit to GitHub, and it consists of a modified version of as3syndication lib that will work in the Flash IDE. You may recall that earlier I proposed the fix and offered the files here. Now, if you prefer, you can just go to my profile at GitHub.

The people may now rejoice.

Tags:
Published: 08.06.10 :: No Comments »


I’d like to take a moment to draw your attention to a very useful class that’s been around for some time, but that I’ve never really bothered to use: flash.system.Capabilities. It gives you all kinds of useful information about the environment your SWF currently resides in. I’ve got an example below.

The SWF above (with any luck) should tell you whether or not you’re running a debug version of flashplayer, who the manufacturer of your flash plugin is, what operating system you’re running, what player type you’re using (should be plugin on this page), and what version of the flash player you’re running.

If you download the files for this demo here and run the SWF on your local machine, you should see a different value in the player type field.

The player type is the most useful piece of information to me. In theory you could use it to load different data or behave differently in general depending on whether you’re viewing your SWF in the Flash IDE or on a webpage, without having to add your own obnoxious boolean “debug” flags.

Categories: APIActionscript 3ArticleDocumentationDownloadsFlashTips
Tags:
Published: 08.05.10 :: No Comments »


I’m pleased to formally announce the relaunch of my portfolio at www.agitcraft.com. It’s been a long,  winding, mostly poorly organized effort on my part consisting of numerous missteps and restarts. I’ve technically been working on this iteration of the site for about 4 months (from scratch), although I’ve been grinding away at redesign efforts both with this domain and with my previous portfolio at altpixel.net for well over two years now. To give you a vague idea of how long this has been brewing, the svn I’ve been working out of is currently in revision 381 after going through at least 4 branches, and I’m the only person developing this.

I’d also like to take this opportunity to give credit where credit is due:

  • Jack Doyle for the greensock tweening platform (which makes all the animation in the site possible), without which I’m sure I would have gone crazy long ago.
  • The entire Papervision3d team for their excellent 3D package, which powers the 3D “solar system” motif that I use to display my interface.
  • The team of developers who’ve thus far worked on as3syndicationlib. There were a couple issues I ran into, but they were minor in the long run and they certainly don’t take away from the fact that I was able to parse and consolidate 5 feeds in real time with only a few lines of code. Awesome!
  • The developers of PureMVC, for making a framework that has literally changed the way that I work on large projects and made my site possible.
  • Matt McInerny at the League of Movable Type for providing the fantastic “Raleway” typeface I’m using both in my logo and for section headers.
  • An anonymous sound fx provider at flashkit.com for providing the ominous intro tune that plays when the site loads. I say anonymous because I was inattentive when I grabbed the audio and forgot to take note of the name/location of the file I snagged. I dug around today but could not, for the life of me, find the file on there. If anybody recognizes it let me know and I’ll give a proper shout out.

The wealth of libraries and tools freely available is part of what makes Flash such an exciting platform to develop for. I certainly could not have completed a project of this scale without them.

Anyway, if you like the site let other people see it. If you have problems with it let me know. I’m hoping this remains a growing work rather than a one-off showpiece.

Published: 08.02.10 :: No Comments »


It’s time to speak about a problem that’s been troubling me for quite a while now. Flash CS4 (and certainly versions that precede it) seems to have major problems consistently and accurately rendering text. I’ve prepared some screen captures that demonstrate the problem.

Text Field Properties

It all begins innocently enough. I’ve created a text field on the stage and I move over to the properties panel to toy with it. In this case, the text field uses Arial Regular at 12 points as its font. It’s anti-aliased for readabilty, and it’s selectable.

Embedded Characters

Although I don’t expect that any of my viewers will be without Arial, I embed the font all the same. I make a broad selection of characters that should cover most if not all of my use cases for this text field, without embedding everything.

Editing Text

Now that I’ve configured my text field, I select it on the stage and put in some standard lorem ipsum to test my application with. Everything up to this point seems fine…

How Text Renders

…until I finish editing the text. Now that I have it selected, but am no longer editing it, everything has changed. Compare this screen capture to the one that precedes it.

This problem is not new. It’s particularly pernicious when you’re trying to align other objects with on-screen text.

Categories: ArticleBugsFlashTypographyUncategorized
Tags:
Published: 07.06.10 :: 2 Comments »


Perhaps you, like me, have had a need, at some point or another, to parse RSS feeds in Actionscript. If so, then perhaps you’ve also stumbled across the generally wonderful as3syndicationlib developed by Mike Chambers and Christian Cantrell. For those of you who aren’t in the know, allow me to provide the following excerpt from the project’s google code page:

Use the syndication library to parse Atom and all versions of RSS easily. This library hides the differences between the formats so you can parse any type of feed without having to know what kind of feed it is.

These claims actually hold up pretty well…once you get the code running.

The problem is that the codebase was written specifically for development in Flex. While Flex is a great platform for certain projects, many of us still use Flash for a lot of the work we do, so a toolkit that relies on packages that are only available to Flex just doesn’t do it.

This problem is also no secret. It’s listed as an accepted issue on its project page. The problem is that the codebase apparently hasn’t been updated since December of 2006.  That’s no joke kids.

Fortunately, a solution was pushed forth from outside the project by a Mr. Martin Legris in the form of a bare implementation of the missing “DateBase” class that the syndication library looks for, as well as an edit to an import statement buried down in ParsingTools.as.

So if you, like me, have a need to consume RSS/Atom Feeds in Flash and need a solution that works, look no further. I present, to you, an updated version of the as3 syndication library with the necessary changes in place to begin using it out of the box in your flash projects.

The files are all available here.

Categories: ArticleBugsDownloadsFlashLibrariesas3syndicationlib
Published: 07.02.10 :: No Comments »


I received quite a response yesterday to my post offering a circular fill animation. First of all, I had a brief conversation with Frank Salim.

Frank: drawArc
?
is there a reason that isn’t an appropriate solution?
me: drawArc isn’t a function in flash.display.graphics
Frank: wacky
arcTo is a function on the canvas 2d context in html5
me: There is a curveTo function that takes 2 anchor points
Frank: are there any curve functions?
ok
me: but it’s not very intuitive
and this is easier
once the asset exists
Frank: can an asset contain code
me: sure
Frank: shrug
Yes, ultimately I could have come up with a programmatic solution to this problem. In the near future, for arguments sake, I suppose I will.
Another thread of conversation was running at the same time in (*gasp*) Google Buzz. Yes, some of us are using it. A coworker (Stephen Weber) ribbing me about how I was spending my time turned into a brief discussion on the “Flash vs. HTML5″ debate circulating right now. It expresses my views on the matter quite nicely.
Stephen Weber - Are you really this bored to be making 360 frame loading animations? I expect a new 3D physics engine or gaming engine. Or even better why not learn JS so HTML5 will be your next love.
Ian Ford - Ultimately this is more useful than a 3D physics engine in flash would be.
Stephen Weber - What about HTML5?
Ian Ford - I’m waiting to see what it will really be useful for. Video is a small niche that HTML5 doesn’t entirely fill (at least for our uses at Ignite), and I’m not sure there’s anything I’d like to develop that HTML5 is better suited for than flash.
Stephen Weber - I completely agree and they still have to decide on a video standard. I really am surprised about your thoughts though. I really thought you would be all for HTML5. I am really interested in the fact that Javascript takes a lot of resources to do something that is pretty easy to Flash (there are various examples of this). There is definitely a push against Flash out there right now. I am starting to think it would be important for our group to explore other technologies in case Flash starts getting less popular (I doubt this will happen).
Ian Ford - I support a universal standard for markup and layout adopted by all browsers, implemented to the same standards, with support for dynamic content and rich media, hopefully released on an open platform.

HTML5 would like to be that. If it ends up doing so, I’ll be a big supporter.

Stephen Weber - Ditto. Standards help developers make better more universal products.
Ian Ford - Developers should flex their influence and support standards. We shouldn’t put our resources into draconian platforms. We should vote with our fingertips, as it were.
Stephen Weber - How does that go along with your development in Flash?
Ian Ford - Flash is already a great approximation of what I want in a platform. Its wide penetration makes it a de facto standard. I am confident that when I develop in Flash, everyone who sees the final product can see it in the same way. This is something developers have never been able to confidently say about HTML+CSS+JS, and unless some real consensus is reached amongst browser vendors the problem will persist into HTML5 as well.

While it may not be completely open, those aspects of it which are closed allow the platform to grow rapidly (as it has) without waiting for the consent of larger bodies and opposing forces.

Stephen Weber - Nicely put.

Categories: ArticleFlashHTML5
Published: 05.19.10 :: No Comments »


Matt Kenefick over at Big Spaceship Labs posted a thoughtful, level-headed examination of the debate on the future of Flash considered against the emerging “threat” of HTML5. This is one of the better articles I’ve read on the matter.

Categories: Links
Tags:
Published: 04.20.10 :: No Comments »



Milky Ball

I’m inclined to disagree. So is Prashanth Kamalakanthan. He has a tumblog called “Flash is Dead” in which he highlights several examples of why it clearly is not.

Thanks to Frank for the link.

Categories: Links
Tags:
Published: 03.19.10 :: No Comments »


Gesture Recognition

I’ve spent the last day or two reacquainting myself with what’s been done to achieve reliable gesture recognition in AS3. I have reviews of two different packages I tried, one of which is relatively new and one of which has been around for some time.

One note about all of the gesture recognition classes I’ve looked at is that they are direction-dependent. That is to say that if you’re attempting to capture the gesture corresponding to a vertical line, a stroke from top to bottom is not the same thing as a stroke from bottom to top. Furthermore, neither of those will necessarily be captured in a stroke from top to bottom to top. This all has to do with the algorithms being employed to detect gestures and attempts to make them run as efficiently as possible.

The first package I looked at was offered up by a Mr. Felix at bertiesbraum.de. Felix’s gesture recognizer consists of AS3 implementations of the “$1 Gesture Recognizer” and “ShortStraw Corner Finder” algorithms, which he has the decency to cite and link to (unlike me).

His post does a much better job of explaining basic usage of the classes than I care to at the moment, but what I will say is that I was unable to get the classes to function without false positives. This is likely because, as Felix notes, “The gestures are also rotation, position and scale invariant,” which is to say that a single stroke probably ends up being a single stroke, regardless of which direction it points. With more complex figures I was able, in the sample application Felix provides, to demonstrate direction dependence. In my case I’m trying to detect single strokes in distinct directions, and so it may be that these algorithms are over-engineered for my purposes.

The second package I looked into was posted in a short article at ByteArray.org by Didier Brun. I caught this post when it first came out (almost three years ago) and was very impressed with the concept but didn’t have any real use for it at the time. I toyed with it today and have been pleased with the results.

Initially Mr. Brun’s classes posed the same problem that most gesture recognition algorithms do: it was unable to recognize identical patterns if they proceeded in different directions. Additionally, all of the packages I’ve seen presume that the user will begin their gesture by pressing the mouse button down, and end the gesture by releasing it. I’m trying to detect whether or  not a user is shaking an object they’ve picked up in an up-and-down fashion, so it’s important to me to recognize sub-gestures within a larger “gesture.” If I depend solely on button presses and releases, the gesture that ends up being analyzed consists of tens of motions at the least.

I came up with a solution using Mr. Brun’s classes that allowed me to achieve my ends. Brun’s gesture recognition class offers a custom event that fires when capture begins and ends, when a match is made or not made, and while capture is taking place. The last of those was most important to me. I added a public property to his existing GestureEvent class. The modified class looks like this:

package com.foxaweb.ui.gesture {

	import flash.events.Event;

	public class GestureEvent extends Event {

		// ------------------------------------------------
		//
		// ---o static
		//
		// ------------------------------------------------

		public static const START_CAPTURE:String="startCapture";
		public static const STOP_CAPTURE:String="stopCapture";
		public static const CAPTURING:String="capturing";
		public static const GESTURE_MATCH:String="gestureMatch";
		public static const NO_MATCH:String="noMatch";

		// ------------------------------------------------
		//
		// ---o properties
		//
		// ------------------------------------------------

		public var datas:*;
		public var fiability:uint;
		public var moves:String;

		// ------------------------------------------------
		//
		// ---o constructor
		//
		// ------------------------------------------------

		public function GestureEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false){
			super (type,bubbles,cancelable);
		}

		// ------------------------------------------------
		//
		// ---o methods
		//
		// ------------------------------------------------

		public override function clone():Event{
			return new GestureEvent(type, bubbles, cancelable) as Event;
		}

	}
}

I also made a change to the MouseGesture class to make sure that “moves” were being attached to GestureEvents dispatched during the “CAPTURING” phase. The modified function looks like this:

protected function captureHandler(e:TimerEvent):void{

	// calcul dif
	var msx:int=mouseZone.mouseX;
	var msy:int=mouseZone.mouseY;

	var difx:int=msx-lastPoint.x;
	var dify:int=msy-lastPoint.y;
	var sqDist:Number=difx*difx+dify*dify;
	var sqPrec:Number=DEFAULT_PRECISION*DEFAULT_PRECISION;

	if (sqDist>sqPrec){
		points.push(new Point(msx,msy));
		addMove(difx,dify);
		lastPoint.x=msx;
		lastPoint.y=msy;

		if (msx<rect.minx)rect.minx=msx;
		if (msx>rect.maxx)rect.maxx=msx;
		if (msy<rect.miny)rect.miny=msy;
		if (msy>rect.maxy)rect.maxy=msy;
	}
	// event
	var evt:GestureEvent = new GestureEvent(GestureEvent.CAPTURING);
	evt.moves = moves.join("");
	dispatchEvent(evt);

	//dispatchEvent (new GestureEvent(GestureEvent.CAPTURING));

}

The final step was to deal with the entire set of move data in my application. I configured my instance of the MouseGesture class to handle GestureEvent.CAPTURING events and created the following function to deal with them.

private function _captureHandler(e:GestureEvent):void {
	var reShake:RegExp = /(62|26)/g;
	var shakes:int = e.moves.match(reShake).length;
	field_shakes.text = "Number of Shakes: " + shakes;
	if (shakes >= 12) {
		stage.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));
		field_shakes.text = "Congratulations!";
	}
	trace(e.moves);
}

The important thing to note here is the regular expression being used. The strings “62″ and “26″ correspond to the output that would be expected from a vertical shake gesture in the MouseGesture class (respectively “up->down” and “down->up”). What the function does is scan the entire list of movements and look for instances in which the patterns I’m trying to match have occurred in sequence. For each occurrence of either pairing, we know that the user has successfully “shaken” the can. A single call fired to the “_captureHandler” function might have a “moves” list that looks like this…

0666662255222666666222566222266222266672226666122561

…in which each digit corresponds to one of 8 possible directions the user moved his mouse. If you count carefully, you’ll find 8 instances of either the sequence “62″ or the sequence “26.”

Ultimately Mr. Brun’s class ended up being more useful for the project that I’m working on, but I hope to see other implementations in the future that will allow for more complex gestures to be recognized.

Published: 03.11.10 :: No Comments »


So, I thought I’d bring attention to a strange inconsistency I run into on a very regular basis while developing applications in Adobe Flash.

Much of the work that I do in flash has to do with displaying and managing video. To date, I have probably created at least 50 different playlist enabled video players, by which I mean video players with a list of either links, thumbnails, or both that allow you to play other videos in the same container without leaving the page. For example, something like this…


A Generic Video Player


…with a playlist that allows you to select other videos, like this…


Video Player with Playlist


This is all well and good. Because I try to build in a way that’s generalized for client accessibility and ease-of-use (and because I don’t want to be solely responsible for updating these things myself), the standard way to go about creating something like this would be to have an external XML document that contains all of the information required to build the playlist. The application is responsible for loading that document and extracting that information from it, which it uses to build a clickable, interactive playlist. This is all quite simple. The XML could look something like this:

<playlist>
	<item>
		<uid>1</uid>
		<title>Video 1</title>
		<video>PATH TO VIDEO</video>
		<thumbnail>Image for video</thumbnail>
	</item>
	<item>
		<uid>2</uid>
		<title>Video 2</title>
		<video>PATH TO VIDEO</video>
		<thumbnail>Image for video</thumbnail>
	</item>
	<!-- and on, and on, and on -->
</playlist>

The folder structure for such an application could (and would) conceivably look like this:


FLA Folder



Within our document root, we have an FLA folder to hold our source files.

FLV Folder



We have an FLV folder for holding video assets.

SWF Folder



We have a SWF folder for holding all of our compiled application SWFs.

XML Folder



And finally we have an XML folder for holding any XML documents we’ll be loading in the application. The index file resides in the document root.

Here’s where things get screwy.

In my application, when I’m ready to load my external XML in order to build a playlist, my code will look like this:

var req:URLRequest = new URLRequest("xml/playlist.xml");
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, _playlistHandle, false, 0, true);
loader.load(req);

After I’ve loaded my playlist, suppose I want to play the first video. For the sake of brevity, we will suppose that I have an instance of a video player class that will allow me to simply pass the path to the FLV in to begin playing it, and that it’s already been instantiated and configured under the name “_player.”

function _playlistHandle(e:Event):void {
	var loader:URLLoader = e.target as URLLoader;
	var xml:XML = XML(loader.data);
	_player.play(xml.item.video[0].toString());
}

What do you suppose the path to my video is going to be, within my xml doc? If you look above, you’ll see I loaded the xml from the document root, and it would be natural for you to assume that the path to the first video is “flv/video.flv.” In this instance, you would be incorrect.

The correct path to the video file would be “../flv/video.flv.” Why is this? The relative path to an asset, in flash, varies according to what type of asset it is you’re accessing. In the case of XML you load your file from the location in which the SWF file is running, which in our example is the document root. When you’re loading video, however, you have to load your file from the physical location of the swf, not from where it’s running. In our example, that means our video file must be loaded as if the application is running from within our “swf” subfolder.

Why is this the case? I honestly have no idea. I can only imagine that in some obtuse way it’s meant to protect video content from being exploited by external domains or malicious third parties, though I can’t see exactly how.

Hopefully if you find yourself developing such an application, and you can’t figure out why the paths to your videos won’t resolve correctly, you’ll remember reading about the issue here. If anyone has a good explanation for why this is the case, I’d also be very curious to be informed.

Categories: ArticleBugsDocumentationFlashTips
Tags:
Published: 02.26.10 :: No Comments »