jeffchannell.com

AJAX Loader Animation in Flex

Posted in Flex 3
2009-05-04 00:09:44 +0000 UTC

I had a client request an AJAX loader be used on a Flash site that had, up to that point, been written in compiler-agnostic ActionScript 3. The requirements were not complex, as the animation was not expected to coincide with the loading progress. I immediately turned to the best resource on the web for AJAX loaders - Ajaxload.

Ajaxload is a great resource for royalty-free AJAX loading animations, and fit the bill perfectly. There's just one problem: animated gifs don't work in AS3.

Now, I am aware there are libraries written to make them work, but I didn't want even more third party library dependencies. So I started first by downloading the animated gif and opening it in my favorite image editor.

Figure 1

Animated gif open in the GIMP

I then created a new image with the same width as the original, and the height calculated by multiplying the number of frames by the original height. Then I imported the frames of the original into my new image, and set each frame on top of the next.

Figure 2

All the frames in a single image

Once that was complete, I wrote a small bit of ActionScript to animate the loader:

package
{
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.events.Event;
	
	[SWF( width="16", height="16" )]
	
	public class AjaxLoader extends Sprite
	{
		// assets
		[Embed( source="ajax-loader.png" )]
		[Bindable]
		private var _img:Class;
		
		// objects
		private var _bmp:Bitmap;
		private var _mask:Sprite = new Sprite();
		private var _container:Sprite = new Sprite();
		
		// params
		public var speed:int = 2;
		private var count:int = 0;
		
		public function AjaxLoader()
		{
			_bmp = new _img() as Bitmap; // set asset
			// draw mask
			_mask.graphics.beginFill( 0xff00ff, 1 );
			_mask.graphics.drawRect( 0, 0, 16, 16 );
			_mask.graphics.endFill();
			// set mask
			_bmp.mask = _mask ;
			// put it all together
			_container.addChild( _bmp );
			_container.addChild( _mask );
			addChild( _container );
			addEventListener( Event.ENTER_FRAME, animate );
		}
		private function animate( e:Event ):void
		{
			if( count++ == speed )
			{
				// set new y
				var n:Number = _bmp.y - 16;
				// make sure y is within range
				if( n * -1 >= _bmp.height ) n = 0;
				// set y
				_bmp.y = n;
				// reset speed count
				count = 0;
			}
		}
	}
}

And here is what I ended up with:

Flash Content

This is a Flash animation of an AJAX loader. It requires the Adobe Flash plugin and JavaScript to view.