InteractiveItem Base Class
December 22nd, 2007
While building the NapkinNotebook site I needed a flexible View Class that all of the animated objects on the stage could be extended from. This is the class I decided to go with.
Most of the objects you see on NapkinNotebook.com are extended from this simple to use base class.
import flash.display.MovieClip;
import caurina.transitions.Tweener;
/**
* @author jessefreeman
*/
public class InteractiveItem extends MovieClip {
protected var _show_x : Number;
protected var _show_y : Number;
protected var _hide_x : Number;
protected var _hide_y : Number;
protected var _showing:Boolean;
public function get showing():Boolean{
return _showing;
}
public function InteractiveItem(config:Object) {
init(config);
hide(false);
}
internal function init(config:Object):void{
_show_x = config.show_x;
_show_y = config.show_y;
_hide_x = config.hide_x;
_hide_y = config.hide_y;
}
public function show(animate:Boolean,speed:Number = 1, delay:Number = 0):void{
if(animate){
if(!_showing){
Tweener.addTween(this, {x:_show_x,y:_show_y, time:speed, delay:delay});
}
}else{
x = _show_x;
y = _show_y;
}
_showing = true;
}
public function hide(animate:Boolean,speed:Number = 1,delay:Number = 0):void{
if(animate){
if(_showing){
Tweener.addTween(this, {x:_hide_x,y:_hide_y, time:speed, delay:delay});
}
}else{
x = _hide_x;
y = _hide_y;
}
_showing = false;
}
}
}
How does it work and what is the point? Well a lot of time I find I have these Sprite/MovieClip instances on the stage that need to be shown or hidden based on the state of the application. Having these objects share a common API helps speed up the devleopment a lot.
The basic idea behind this base class is once an item is initialized, it’s hide/show x and y values are saved inside of the instance and the hide() method is called. Notice on the show and hide method I have a animate property. This allows me to trigger the animation or have it immediately hide/show itself. This is really good for setting up the object as you see after the init is called, hide(false) is immediately called to move the object off screen. Here are some more examples of this in use:
This is the StaticPen class that represents the pen on the side of the Napkin Notebook. This pen is used for decoration and is shown in most of the sections but once a user clicks on sketch or buy links it goes off screen. See how it extends the InteractiveItem and that is all the code needed to get it to hide/show from then on:
import com.napkinnotebook.views.items.InteractiveItem;
/**
* @author jessefreeman
*/
public class StaticPen extends InteractiveItem {
public function StaticPen(config : Object = null) {
super(config);
}
override internal function init(config:Object):void{
super.init(config);
}
}
}
So when I need to set up the pen this is the function I call in my document class.
var config:Object = new Object();
config.show_x = 250;
config.show_y = 155;
config.hide_x = config.show_x;
config.hide_y = 700;
config.delay = 3;
_static_pen = new StaticPen(config);
addChild(_static_pen);
}
Pay attention to the config object and how it is passed into the StaticPen class constructor. I use this a lot with all of my View Classes. In AS 2 you use to be able to pass in an additional object to any MovieClip that was attached from the libarary to help set it up. I miss that in AS 3 and try to use it where ever I can. The only down side is that you need to remember all of possible values a class can accept from the config object but I find that if your code is well documented and are using FDT there shouldn’t be an issue. Also since all of the objects that extend the InteractiveItem take the same peramitors I find it a little easier to keep track of.
So how do I handle transitions? Simple, I use a switch or if/then statement in my document class that gets called when a navigation button is selected. Here is a look at that:
if(_display_mode == “View Sketch”){
_navbar.lock = false;
_moma_ticket.show(true,.5,1.5);
_note_pad.show(true,.5, 1);
}else if (_display_mode == “Sketch” || _display_mode == “Gallery”){
_note_pad.show(true,.5, .5);
_coffee_cup.show(true,.5, 2);
_static_pen.hide(true,.5, 0);
// Package
_package_front.hide(true,.5,.5);
_package_back.hide(true,.5,0);
_moma_ticket.hide(true,.5,0);
}else if (_display_mode == “Buy”){
_note_pad.hide(true,.5, 1);
_coffee_cup.hide(true,.5, 0);
_static_pen.hide(true,.5, .5);
// Package
_package_front.show(true,.5,1);
_package_back.show(true,.5,1.2);
_moma_ticket.show(true,.5,2);
}else{
_note_pad.show(true,.5, .5);
_coffee_cup.show(true,.5, 2);
_static_pen.show(true,.5, 1);
// Package
_package_front.hide(true,.5,.5);
_package_back.hide(true,.5,0);
_moma_ticket.hide(true,.5,0);
}
}
There are probably more efficient ways of doing this. In AS 2 I use to use the Tween Animation utility Fuse but I find that for simple sites this is the fastest way to get up and running.
One other cool thing about this class is the automatic state management. It keeps track if it is shown through the get showing() method. This is useful to test if a transition is complete or if the user can interact with the object. The other thing this state tracking handles is making sure an animation is not called if it has already been done. This helps with the application display_mode() method because it may call the same show() method on a InteractiveObject over and over again even if it is already being shown. I like to make the manager unaware of the objects state and let the object be as self sufficient as possible.












Leave a Reply