17 November 2008
All
Adobe AIR 1.5 gives developers access to many of the cool new features that are available with Adobe Flash Player 10, such as Adobe Pixel Bender or 3D transformations. In addition to the new Flash Player capabilities, AIR 1.5 includes integration of the SquirrelFish JavaScript VM into the WebKit HTML engine, support for encrypting the local database, and many bug fixes and improvements.
Wouldn't it be cool to have an AIR application that uses Pixel Bender effects, 3D transformations, and an encrypted local database? BlackBookSafe is an HTML/JavaScript application built on AIR 1.5 that makes good use of these features.
Note: BlackBookSafe is a contact list sample application that uses the JQuery framework and the AS3CoreLib library. When you launch the application, the database is populated with 10 records taken from the public Employee Directory sample application built in Flex.
In this article I break down the architecture of the BlackBookSafe sample application and explain how it leverages the new features in AIR 1.5. Although I will not go into great detail (you have the code, and you can review it on your own), I will try to help you get up to speed using these features for your applications.
Before I start dissecting the application, I suggest you download the source code of the application and unzip and load it into your preferred editor so you can easily follow along. When building an HTML/Ajax application on AIR, you have the following options:
Note: For more information on getting started building on AIR, see Getting started started for HTML/JavaScript developers.
Figure 1 shows the code of the BlackBookSafe project in Aptana.
Identify the structure of the application
Now that you have the project in place, it's time to have a look at its structure. The root of the project contains the HTML files and the application.xml file. BlackBookSafe.html is the initial window of the application; the rest of the HTML files represent one possible state or window. If you'll take a look at these files, you'll notice that there is only HTML code inside, and a little bit of JavaScript. The look and feel of the HTML interface is implemented via CSS files, and the business logic is done in JavaScript files loaded by the initial window, BlackBookSafe.html.
Note: For more details on the structure and files of HTML files, see Introducing Adobe AIR for Ajax developers.
Looking at the rest of the folders, you will find that:
Now, let's go back to the initial window, BlackBookSafe.html. You'll notice that this file doesn't have a user interface. It just loads all the JavaScript files, sets the main CSS file, and on the body tag initializes the application (you can find the definition of this function inside of the js/BlackBookSafe.js file):
<body id="body" onload="BBS.Application.initialize()" >
At this point, you might wonder what is the architecture of this application and why was it created this way. Each state of the application is created by a separate HTML file that is loaded in a different HTMLLoader (it is an AIR class that acts like a container for HTML content). After the loaders are created, the handlers are attached for the HTML components that are used for user interaction.
Separating each state or window of the application, and loading each one in its own loader, gives flexibility—you can easily display one window or multiple windows at the same time. Figures 2 and 3 show two different states of the application: one with only one loader visible, and another with two loaders visible at the same time.

Using these separate loaders has another advantage: you can very easily apply Pixel Bender effects or 3D transformations on each one separately. Using this cool Flash Player 10 feature requires a DisplayObject; the HTMLLoader inherits from DisplayObject. In Figure 3, for example, the window from the background is curved by applying a Pixel Bender effect, andn when you navigate from one contact to another, a 3D Transformation effect is applied only on the loader that holds the detail page. Pretty cool, isn't it?
Pixel Bender uses a highly efficient programming language created by Adobe for image processing. So far, it is implemented in Adobe After Effects CS4 and Flash Player 10. Adobe provides a toolkit that lets you create, compile, and preview filters and effects.
BlackBookSafe stores the effects in the assets/blender/ folder. You can load any effect into the toolkit and play with it. The magic happens inside BlackBookSafe.js—at the end of the file there is a function called $(). As I stated before, each display/window of the page is loaded in a separate HTMLLoader. With this approach, you can apply a Pixel Bender effect on the whole loader. To apply an effect on an HTMLLoader, you need to have the effect compiled with the Pixel Bender Toolkit (this will generate a .pbj file). Copy this file inside of your project.
The following code demonstrates some sample effects that BlackBookSafe uses:
//create a shader out of the compiled effect shake.pbj
function loadShader(){
//Use a loader to get the bytes of the Pixel Bender effect
var loader = new runtime.flash.net.URLLoader();
//sets the data format to binary, as the effect is compiled
loader.dataFormat = runtime.flash.net.URLLoaderDataFormat.BINARY;
//add a listener on the complete event for the loader;
loader.addEventListener(runtime.flash.events.Event.COMPLETE,
function(){
//create a shader out of the loaded data
shader = new runtime.flash.display.Shader(loader.data); });
//starts the load of the effect
loader.load(new runtime.flash.net.URLRequest("shake.pbj"));}
loadShader();
//next create a tween with a linear effect
function linear(t, b, c, d){
return (t/d)*c + b;
}
//this is a function for creating a tween
function tween(startPixel, stopPixel, duration, callback,
finish, reverse){
if(reverse){
var temp = stopPixel;
stopPixel = startPixel;
startPixel = temp;
}
var fps = 30;
var transitionEffect = linear;
var currentEffect = 0;
var startTime = runtime.flash.utils.getTimer();
function animate(){
var newTime = runtime.flash.utils.getTimer();
var deltaTime = newTime-startTime;
var pos = deltaTime/duration;
currentEffect = transitionEffect(deltaTime, startPixel, stopPixel-startPixel, duration);
if(nativeWindow.closed || callback(currentEffect, pos) || duration<=deltaTime){
clearInterval(interval);
interval = null;
if(finish) finish();
}
}
animate();
var interval = setInterval(animate, 1000/fps);
//And finally apply the effect on the stage:
function shake(){
tween(0, 1, 1200,
function(rotation){
//setting the values for the effect's parameters
shader.data.width.value[0] = htmlLoader.width;
shader.data.height.value[0] = htmlLoader.height;
shader.data.transition.value[0] = rotation;
shader.data.weight.value[0] = 0.5;
//applying the effect to the HTMLLoader
htmlLoader.filters = [ new runtime.flash.filters.ShaderFilter(shader) ];
},
function(){
// remove filters at the end
htmlLoader.filters = [];
}
);
}
BlackBookSafe uses 3D transformations when you navigate from one contact to another, or for the flip (or cube effect) when you enter or exit in edit mode. The flip is implemented like this: the detail is transformed into a bitmap (see Figure 4) and it is displayed on top of the HTMLLoader that holds the contact. Then the data for the contact page is changed for the next person.
Next, a 3D rotation is applied around the y axis, on the bitmap data, and on the HTMLLoader (see Figures 5).
The magic happens inside Transform3D.js, Effect3D.js, and the $() function in BlackBookSafe.js. The following effect rotates the entire content of the AIR application:
// set the distance between the eye and the display object
nativeWindow.stage.transform.perspectiveProjection.focalLength = 800;
// we want to change the rotation origin for the htmlLoader, so we have to
// create a new Sprite and move it in the middle of the scene and
// add the htmlLoader to this sprite, but move it, so that the origin
// of the new sprite is exactly the middle of the htmlLoader
var sprite = new runtime.flash.display.Sprite();
nativeWindow.stage.addChild(sprite);
htmlLoader.parent.removeChild(htmlLoader);
sprite.addChild(htmlLoader);
function rotate(){
tween(0, 1, 1200,
function(rotation){
htmlLoader.x = -htmlLoader.width / 2;
sprite.x = - htmlLoader.x;
sprite.rotationY = rotation * 360;
},
function(){
sprite.rotationY = 0;
}
);
}
//you can use the same tween function I show you for the bender effect
As you can see in Figure 6, the HTMLLoader is added to a sprite that has half the width of the entire stage. Then the rotation is done on the sprite. If you tried to rotate the HTMLLoader directly, the effect would look a little strange, in that the content will be out of view at some points.
Encrypting the local database
In previous versions of the AIR runtime, if you wanted to store sensitive data in your AIR application, you had to use the encrypted local store. Although this is helpful in a pinch, the encrypted local store is not a relational database; it uses only key/value pairs. With AIR 1.5, you can use either the encrypted local store or the encrypted (SQLite) database which is included in AIR. If you want to use the encrypted database you have to do the following:
BlackBookSafe uses this algorithm for keeping the data safe (this isn't the silver bullet, so I encourage you to look for different techniques to generate random keys):
Note: If you forget the password, the data is lost forever.
The js/Database.js and js/KeyManager.js files contain the logic for generating the key and store it, as well as for working with the database.
At first you might be tempted to think that the new features in AIR 1.5 are little more than window dressing for business applications. However, after looking more closely at BlackBookSafe, you'll see that support for 3D transformations or Pixel Bender effects can greatly enhance the user experience if they are used properly. Remember, with great power comes great responsibility: you have to decide carefully when to use these effects and how.
Note: BlackBookSafe was created by Mirela Budaes, Horia Olaru, Alex Chiculita, Raul Hudea, Marius Ioana, and Tudor Muscalu of the AIR team.
| 04/11/2012 | Surround sound 5.1 with Air 3.2 on desktop app? |
|---|---|
| 12/12/2011 | Live Streaming H.264 Video on iOS using AIR |
| 04/17/2012 | HTMLLoader - Google Maps? |
| 04/12/2012 | Tabindex in forms on mobile? |