AS 3 LightBox Class

December 22nd, 2007

I have always been a big fan of the “LightBox” effect in web 2.0 apps and wrote this little class to use in my applications.

Ironically after I wrote this class I was told that Flex has something similar built into it. This is a really lightweight version that should have enough versatility to fit any project’s needs. Enough selling, here is the class and some examples on how to use it:

package com.jessefreeman.ui {
        import flash.display.DisplayObject;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
       
        import com.jessefreeman.utils.ReflectionUtility;
       
        import caurina.transitions.Tweener;

        /**
         * @author Jesse Freeman
         * Copyright (c) 2007 bFreeDesign.com. All rights reserved.
         */

        public class LightBox extends Sprite {
               
                private var _current_display:Sprite; // Current Display for the lightbox
                private var _screen_cover:Sprite;// Asset used to overlay stage and acts as background fro LightBox
                private var _active:Boolean; // Tells if the Lightbox is open or close
                private var _display_reflection; //
               
                /**
                 *
                 */

                public function get active():Boolean{
                        return _active; 
                }
               
                /**
                 *
                 */

                public function LightBox(config:Object) {
                        init(config);
                }
               
                /**
                 *
                 */

                protected function init(config:Object):void{
                        _screen_cover = creat_box(50,50);
                }

                /**
                 * This function creates the stage overlay and attaches a passed in Display Object as the focus of the LightBox. It also listens to a close form event to exit the lightbox
                 * @param target: Target DisplayObject to be attached to the lightbox
                 * @param animate: toggles animation
                 * @param reflection: adds a reflection to the target DisplayObject from the Reflection Utility
                 */

                
                public function open(target:DisplayObject, animate:Boolean, reflection:Boolean = false, custom_width:Number = NaN, custom_height:Number = NaN):void{
                        _active = true;
                       
                        _screen_cover.width = stage.stageWidth;
                        _screen_cover.height = stage.stageHeight;
                       
                        addEventListener(MouseEvent.CLICK, close);
                        _screen_cover.alpha = 0;
                        addChild(_screen_cover);
                       
                        _current_display = new Sprite();
                        _current_display.alpha = 0;
                        _current_display.addChild(target);
                       
                        // Set up width and height of target
                        var temp_width:Number;
                        var temp_height:Number;
                       
                        if(custom_width)
                                temp_width = custom_width;
                        else
                                temp_width = _current_display.width;
                               
                        if(custom_width)
                                temp_height = custom_height;
                        else
                                temp_height = _current_display.height;
                       
                        // Center Object
                        _current_display.x = stage.stageWidth/2 - temp_width/2;
                        _current_display.y = stage.stageHeight/2 - temp_height/2;
                       
                        if(reflection){
                                var display_reflection:Sprite = ReflectionUtility.reflection(target);
                               
                                display_reflection.x = target.x;
                                display_reflection.y = target.y+target.height;
                                display_reflection.alpha = .2;
                                _current_display.addChild(display_reflection);
                        }
                       
                        addChild(_current_display);
                       
                        dispatchEvent(new Event(Event.OPEN,true));
                       
                        if(animate){
                                Tweener.addTween(_screen_cover,{alpha:1,time:.5});
                                Tweener.addTween(_current_display,{alpha:1,time:.3,delay:.2});
                        }
                }
               
                /**
                 * Closes the LightBox and removes the display.
                 */

                public function close(event:Event = null):void{
                       
                        removeChild(_screen_cover);
                        removeChild(_current_display);

                        _current_display = null;
                       
                        dispatchEvent(new Event(Event.CLOSE, true));
                       
                        _active = false;
                }
               
                /**
                 * Used to create mask over content
                 */

                internal function creat_box(width:Number,height:Number,alpha:Number = 0,color:Number = 0xff0066, bevel:Number = 0):Sprite{
                        var mask:Sprite = new Sprite();
                                mask.graphics.beginFill(color,alpha);
                                 mask.graphics.lineStyle(1, 0×000000,0);
                                mask.graphics.drawRoundRect(0, 0,width,height,bevel,bevel);
                                 mask.graphics.endFill();
                   return mask; 
                }
        }

}

It is important to note this class has two dependent classes, my reflection utility (get it here) and Tweener (get it here) to handle the fade up and down of the overlay image.

So how does this work? here are a few code snippets from an application I am using this in

private function create_lightbox():void{
        // — Light Box
        var lb_config:Object = new Object();
                lb_config.x = 0;
                lb_config.y = 0;
       
        // Create Instance
        _light_box = new LightBox(lb_config);
        addChild(_light_box);
       
        // Listeners
        _light_box.addEventListener(Event.OPEN, lightbox_open);
        _light_box.addEventListener(Event.CLOSE, lightbox_close);
                       
                       
        // Error Box (linkage from library) for Light Box - is never added to display list unless inside of the LightBox
        _error_box = new ErrorBox();
}
       
        /**
         * Blurs background when LightBox opens
         * @param event
         */

        private function lightbox_open(event:Event) : void {
                Tweener.addTween(_view_collection,{_blur_blurX:10,_blur_blurY:10,time:1,delay:0});
                _controls.visible = false;                 
                stage.removeEventListener(MouseEvent.MOUSE_MOVE, toggle_control_visibility);
        }
       
        /**
         * resets background when LightBox closes
         * @param event
         */

        private function lightbox_close(event:Event) : void {
                stage.addEventListener(MouseEvent.MOUSE_MOVE, toggle_control_visibility);
                Tweener.addTween(_view_collection,{_blur_blurX:0,_blur_blurY:0,time:.5,delay:0});
        }

And here is an example of how I would call the LightBox to show an error MC from the library. Its important to note that _error_box (the asset from the library) was already defined in the above code and was not added to the display tree. This instance could just as well be declared on the fly then passes directly into the LightBox open method.

/**
                 * Handdles IO Errors and displays error message through the LightBox
                 * @param event
                 */

                private function on_io_error(event:IOErrorEvent){
                    _error_box.label_tf.htmlText = “The Song could not be loaded: <br/>”+event.text;
                    _light_box.open(_error_box, true,true);
                        SongItem.reset_selection();
                }

Where to go from here? The only thing missing from this code sample is a way to make the LightBox auto recenter the DisplayObject. In the past I have added an extra method onto the LightBox class called realign(). Inside of that I add centering code for the _current_display. Then I add stage resize event listeners that call the realign() method. You can see where some of the resize code was set up because of the custom width and height you can pass into the open() method. That exists to help offset the _current_display in case you want to have it not completely centered based on its dimension. I use this for masked objects that don’t always give off their visible dimension or if I want them to show up higher on the screen.

One last thing you may have noticed is the optional reflection perimeter in the open() method. That just takes the DisplayObject you pass into it and adds a subtle reflection using the reflection utility. Noting earth shattering here but sometimes that added touch makes a big difference in the visual side of your app. After all, even though Flash isn’t part of the whole Web 2.0 revolution, we can still have “wet floors” too.

Enjoy!

Leave a Reply