Adobe AIR blurs the line between Flash and HTML technologies by making them virtually interchangeable. Using Adobe AIR, web developers can leverage ActionScript 3.0 assets directly from JavaScript, opening up an entirely new world of possibilities.
Let's say you have an application that does a mash-up of data using one of the various map APIs offered by a company like Google, Yahoo! and others. You find yourself looking at a collection of data that you've spent considerable time filtering and refining. Now you want to share your findings, but how? Do you send a link? Will the link be smart enough to return the viewer to the same state?
It'd be ideal if you could take a snapshot of the screen, save it to disk, and then e-mail it to your colleagues. As a JavaScript developer, however, you don't have access to the pixel data on the screen—there are no libraries for encoding images, and there's no way to save data locally. As an Adobe AIR developer, however, you do have access to the pixel data.
As it turns out, Adobe Flash Player can actually access the pixel data of its display area (since Flash Player 8). Although it doesn't include libraries to encode image data, the Flash community has written just such a utility for various file formats to include JPEG and PNG files. Because you're developing your application on Adobe AIR, you not only have local file access to save the image to disk—you also have access to all that Flash has to offer—right from JavaScript. The HTML file yahoomaps.html and the maps.css and prototype.js files linked in the code below are provided in the sample files folder.
<html>
<head>
<title>Yahoo! Maps<title>
<link href="maps.css" type="text/css" rel="stylesheet" />
<!-- Use Prototype for element measurement and positioning -->
<script src="prototype.js" type="text/javascript"></script>
<script
src="http://api.maps.yahoo.com/ajaxymap?v=3.4&appid=[YOUR_MAP_ID]" type="text/javascript"></script>
<script type="text/javascript">
// Static property used to seed map location
var HOME_GEO = 'Denver, CO';
// Member property for map
var map = null;
// Called when the document finishes loading
function doLoad()
{
// Create a Yahoo! map object
// Setup the desired controls
// Initialize the display of the map
map = new YMap( document.getElementById( 'map' ) );
map.addTypeControl();
map.addPanControl();
map.addZoomShort();
map.drawZoomAndCenter( HOME_GEO, 8 );
}
</script>
</head>
<!-- Listen for the document to finish loading -->
<body onLoad="doLoad();">
<!-- Yahoo! Maps content holder -->
<div id="mapholder" class="box">
<div id="map"></div>
</div>
</body>
</html>
With a map already on hand, the first thing that needs to happen is the capturing of the pixel data of the display area. Flash Player includes a BitmapData class which has a draw() method. The BitmapData.draw() method can be pointed at an object on the display and grab that pixel data. There's also a Matrix class that can be used for cropping as well as various filters such as BlurFilter and DropShadowFilter, see mapsroot.html in the sample files.
var bmp = new air.BitmapData( rect.width - 2, rect.height - 2 );
var matrix = new air.Matrix();
matrix.translate( 0 - ( rect.x + 1 ), 0 - ( rect.y + 1 ) );
bmp.draw( window.htmlLoader, matrix );
With the pixel data on hand, the next step is to encode that data into something useful. Available on Google Code is the ActionScript Core Library project. This project includes numerous valuable functionalities, among which are JPEG and PNG image encoders. You can include the Flash SWF file from this project in a SCRIPT tag in your HTML code, and leverage any of the functionality directly from JavaScript (see mapsroot.html and library.swf in the sample files folder).
<!-- Include AS3 Core Library assets to encode PNG -->
<script src="library.swf" type="application/x-shockwave-flash"></script>
...
var file = air.File.desktopDirectory.resolvePath( 'map.png' );
var png = null;
var stream = new air.FileStream();
png = runtime.com.adobe.images.PNGEncoder.encode( bmp );
stream.open( file, air.FileMode.WRITE );
stream.writeBytes( png, 0, 0 );
stream.close();
With an image of the screen in memory, the last step is to save the file to disk. The FileStream class mentioned earlier supports binary file IO, so this is a perfect reason to use it. However, Yahoo! Maps has a resolution limit, so it'd be nice to restrict the overall size of the native window itself. As it turns out, the Adobe AIR APIs offer the ability to generate and control numerous aspects of native OS windows. One such property is the maximum size of a window, as seen in the mapsroot.html sample file.
// Configure placement and maximum size of native window
window.nativeWindow.x = ( air.Capabilities.screenResolutionX - window.nativeWindow.width ) / 2;
window.nativeWindow.y = ( air.Capabilities.screenResolutionY - window.nativeWindow.height ) / 2;
window.nativeWindow.maxSize = new air.Point( 640, 480 );
This brings the application full circle. What was once an excellent web application has now become an amazingly full-featured desktop application. By leveraging the best of both HTML and JavaScript alongside the features available in Flash, a new class of application and developer is created. You're no longer a JavaScript developer, you're an Adobe AIR developer. Welcome to the desktop!
For more information about the AIR runtime, visit the Adobe AIR product page.
For more inspiration, check out the sample applications in the Adobe AIR Developer Center for HTML/Ajax, Flex, and Flash, as well as the Adobe AIR Developer Derby winners and the apps showcase.
To start building HTML-based apps on Adobe AIR go to the Getting Started section of the Adobe AIR Developer Center for HTML and Ajax or follow the instructions in Developing Adobe AIR Applications with HTML and Ajax. Also be sure to stop by the Ajax Technology Center.