Friday, 25 December 2009

Lolcat viewer

Hi Readers,

What a peaceful Christmas day, isn't it? In the morning I wrote a small AIR application brings lolcats into your desktop. Basically it's a dummy RSS reader for ICanHasCheezburger shows the latest kittens. Here you are:

Let's take a look at the code:

I used Flex with Flex SDK 3.0.
First we need a couple of display objects:
  • Image container: the main lolcat image
  • Secondary image container: the same lolcat image with delay. It makes transitions seamless.
  • Indicator: an external SWF animation indicates network loading
  • Control bar: previous / next / refresh buttons

 <mx:Image id="image_backup"/>
<mx:Image id="image" updateComplete="imageUpdateComplete(event);" click="nextImage();"/>

<mx:SWFLoader source="{indicator}" width="40" height="40" id="indicator_swf" alpha="0.6"/>

<mx:Canvas backgroundColor="0x000000" backgroundAlpha="0.5" bottom="0" left="0" right="0" height="40"
mouseOver="control_bar.alpha = 1"
mouseOut="control_bar.alpha = 0.3"
<mx:LinkButton label="Previous" bottom="10" left="10" color="#CCCCCC" click="{previousImage()}"/>
<mx:LinkButton bottom="10" right="10" label="Next" color="#CCCCCC" click="{nextImage()}"/>
<mx:LinkButton label="Refresh" horizontalCenter="0" bottom="10" color="#CCCCCC" click="{refreshLolcatXML()}"/>

For the SWF animation it's highly suggested to embed the SWF movie itself:
public var indicator:Class;

Loading RSS feed is stupid simple. The feed's address:
   public static const LOLCAT_RSS:String = '';

And the upadating function for getting the feed itself:
   public function refreshLolcatXML():void {
var ur:URLRequest = new URLRequest(LOLCAT_RSS);
var ul:URLLoader = new URLLoader(ur);
ul.addEventListener(Event.COMPLETE, rssReady);
ul.addEventListener(IOErrorEvent.IO_ERROR, networkError);

Let's see what we have got when the request comes back (this is the event I registered for Event.COMPLETE):
   public function rssReady(event:Event):void {
var xml:XML = new XML(;
var items:XMLList = xml.*..item;
currentImageNum = 0;
for each (var item:XML in xml.*..item) {
if (item..MEDIA_NS::content[1]) {

I really like the ActionScript 3 XML layer. XML is already a native ActionScript 3 item, and the XML and XMLList classes make processing XMLs so easy. Quickly the response string is converted to XML and traversed for the important lolcat URLs. On every RSS reload I save results in the imageList ArrayCollection variable. I used one defined namespace, because the URLs can be found under that namespace:
   public static const MEDIA_NS:Namespace = new Namespace('');

Right after getting the response the first image is displayed. These are the stepping functions:
   public function nextImage():void {
if (image.source != imageList[currentImageNum]) {
indicator_swf.visible = true;
image.source = imageList[currentImageNum];
currentImageNum = (currentImageNum + 1) % imageList.length;

public function previousImage():void {
currentImageNum = (currentImageNum - 2 + imageList.length) % imageList.length;

One last small trick. When the image container triggers an updateComplete event, the whole resized for the appropriate image's size:
   public function networkError(event:IOErrorEvent):void {trace('Network error: ' + event);}

public function imageUpdateComplete(event:FlexEvent):void {
trace('Image update. W: ' + image.measuredWidth + ' H: ' + image.measuredHeight);
if (image.measuredWidth > 0) {
var tw:Tween = new Tween(this, Application.application.width, image.measuredWidth, 400, -1, onResizeWidthUpdate, onResizeWidthEnd);
var th:Tween = new Tween(this, Application.application.height, image.measuredHeight + 18, 400, -1, onResizeHeightUpdate, onResizeHeightEnd);
image_backup.source = image.source;
indicator_swf.visible = false;

With the Tween class it's also easy. This is the full Flex source, if you are interested in:
Download Lolcat's source.

And one other cool thing. I've seen a lot that awesome AIR installer object on many sites. So, made a bit research and found this tool you can make your own AIR installer:
Adobe AIR intaller badge This is what you see above.

Happy holidays,

No comments:

Post a Comment