AS3: StageManager

View Example
View Documentation
Download Class & Example Files

The StageManager aligns items according to their selected alignment mode. You have the ability to resize your items with "easing" or "instant" modes as well. It also dispatches an event, ON_RESIZE, that allows for further manipulation of items to the stage sizing.

This is a port of my AS2 StageManager but I've changed some stuff around since you can now align not just movie clips but sprites and other display objects as well.

Actionscript:
  1. package com.reintroducing.utils
  2. {
  3.     import flash.display.DisplayObject;
  4.     import flash.display.Stage;
  5.     import flash.display.StageAlign;
  6.     import flash.display.StageScaleMode;
  7.     import flash.events.Event;
  8.     import flash.events.EventDispatcher;
  9.    
  10.     import com.reintroducing.events.StageManagerEvent;
  11.    
  12.     import fl.transitions.Tween;   
  13.  
  14.     /**
  15.      * Creates an instance of the StageManager that aligns items according to their selected alignment mode.  Also dispatches an event, ON_RESIZE, that allows for further manipulation of items to the stage sizing.
  16.      *
  17.      * @usage
  18.     <code>
  19.     import fl.transitions.easing.*;
  20.     import com.reintroducing.utils.StageManager;
  21.     import com.reintroducing.events.StageManagerEvent;
  22.    
  23.     var listener:Object = new Object();
  24.     var sm:StageManager = new StageManager(stage, "easing", .5, Regular.easeOut);
  25.    
  26.     sm.addItem(test1_mc, "TL", 10, 10);
  27.     sm.addItem(test2_mc, "TC");
  28.     sm.addItem(test3_mc, "TR");
  29.     sm.addItem(test4_mc, "ML");
  30.     sm.addItem(test5_mc, "MC");
  31.     sm.addItem(test6_mc, "MR");
  32.     sm.addItem(test7_mc, "BL");
  33.     sm.addItem(test8_mc, "BC");
  34.     sm.addItem(test9_mc, "BR", -30, -50);
  35.    
  36.     trace("LENGTH OF ITEMS: " + sm.items.length);
  37.    
  38.     sm.addEventListener(StageManagerEvent.ON_RESIZE, resizeHandler);
  39.    
  40.     function resizeHandler($evt:StageManagerEvent):void
  41.     {
  42.         trace("STAGE WIDTH: " + stage.stageWidth + " & STAGE HEIGHT: " + stage.stageHeight);
  43.     };
  44.    
  45.     sm.init();
  46.     </code>
  47.      *
  48.      * @author Matt Przybylski [http://www.reintroducing.com]
  49.      * @version 1.0
  50.      */
  51.    
  52.     public class StageManager extends EventDispatcher
  53.     {
  54. //- PRIVATE & PROTECTED VARIABLES -------------------------------------------------------------------------
  55.  
  56.         private var _stage:Stage;
  57.         private var _items:Array;
  58.         private var _resizeStyle:String;
  59.         private var _easeTime:Number;
  60.         private var _easeFunc:Function;
  61.         private var _tweenX:Tween;
  62.         private var _tweenY:Tween;
  63.        
  64. //- PUBLIC & INTERNAL VARIABLES ---------------------------------------------------------------------------
  65.        
  66.        
  67.        
  68. //- CONSTRUCTOR -------------------------------------------------------------------------------------------
  69.    
  70.         /**
  71.          * Creates a new instance of the StageManager class.
  72.          *
  73.          * @usage <code>var sm:StageManager = new StageManager($stage, $resizeStyle, $easeTime, $easeFunc);</code>
  74.          *
  75.          * @param $stage A reference to the main stage.
  76.          * @param $resizeStyle A string value that represents how to move the clips into position ("easing" or "instant").
  77.          * @param $easeTime If the $resizeStyle is set to "easing", time (in seconds) it takes to ease clips into position.
  78.          * @param $easeFunc If the $resizeStyle is set to "easing", the easing function used to ease clips into position.
  79.          *
  80.          * @return void
  81.          */
  82.        
  83.         public function StageManager($stage:Stage, $resizeStyle:String, $easeTime:Number, $easeFunc:Function):void
  84.         {
  85.             this._stage         = $stage;
  86.             this._items         = new Array();
  87.             this._resizeStyle   = $resizeStyle;
  88.             this._easeTime   = $easeTime;
  89.             this._easeFunc   = $easeFunc;
  90.             
  91.             this._stage.scaleMode = StageScaleMode.NO_SCALE;
  92.             this._stage.align = StageAlign.TOP_LEFT;
  93.             this._stage.addEventListener(Event.RESIZE, onResize);
  94.         }
  95.  
  96. //- PRIVATE & PROTECTED METHODS ---------------------------------------------------------------------------
  97.        
  98.         private function onResize($evt:Event):void
  99.         {
  100.             if (this._resizeStyle == "instant")
  101.             {
  102.                 this.doInstantResize();
  103.             }
  104.             else if (this._resizeStyle == "easing")
  105.             {
  106.                 this.doEasingResize();
  107.             }
  108.            
  109.             this.dispatchEvent(new StageManagerEvent(StageManagerEvent.ON_RESIZE, {}));
  110.         }
  111.        
  112.         // Resizes the clips using no easing but instant movement.
  113.         private function doInstantResize():void
  114.         {
  115.             var numClips:int = this._items.length;
  116.            
  117.             for (var i:int = 0; i <numClips; i++)
  118.             {
  119.                 var clip:DisplayObject = this._items[i].item;
  120.                 var clipX:Number = this._items[i].x;
  121.                 var clipY:Number = this._items[i].y;
  122.                
  123.                 switch (this._items[i].mode)
  124.                 {
  125.                     case "TL":
  126.                         clip.x = (0 + clipX);
  127.                         clip.y = (0 + clipY);
  128.                         break;
  129.                    
  130.                     case "TC":
  131.                         clip.x = (((this._stage.stageWidth * .5) - (clip.width * .5)) + clipX);
  132.                         clip.y = (0 + clipY);
  133.                         break;
  134.                        
  135.                     case "TR":
  136.                         clip.x = ((this._stage.stageWidth - clip.width) + clipX);
  137.                         clip.y = (0 + clipY);
  138.                         break;
  139.                        
  140.                     case "ML":
  141.                         clip.x = (0 + clipX);
  142.                         clip.y = (((this._stage.stageHeight * .5) - (clip.height * .5)) + clipY);
  143.                         break;
  144.                        
  145.                     case "MC":
  146.                         clip.x = (((this._stage.stageWidth * .5) - (clip.width * .5)) + clipX);
  147.                         clip.y = (((this._stage.stageHeight * .5) - (clip.height * .5)) + clipY);
  148.                         break;
  149.                        
  150.                     case "MR":
  151.                         clip.x = ((this._stage.stageWidth - clip.width) + clipX);
  152.                         clip.y = (((this._stage.stageHeight * .5) - (clip.height * .5)) + clipY);
  153.                         break;
  154.                        
  155.                     case "BL":
  156.                         clip.x = (0 + clipX);
  157.                         clip.y = ((this._stage.stageHeight - clip.height) + clipY);
  158.                         break;
  159.                        
  160.                     case "BC":
  161.                         clip.x = (((this._stage.stageWidth * .5) - (clip.width * .5)) + clipX);
  162.                         clip.y = ((this._stage.stageHeight - clip.height) + clipY);
  163.                         break;
  164.                        
  165.                     case "BR":
  166.                         clip.x = ((this._stage.stageWidth - clip.width) + clipX);
  167.                         clip.y = ((this._stage.stageHeight - clip.height) + clipY);
  168.                         break;
  169.                 }
  170.             }
  171.         }
  172.        
  173.         // Resizes the clips using an easing equation.
  174.         private function doEasingResize():void
  175.         {
  176.             var numClips:int = this._items.length;
  177.            
  178.             for (var i:int = 0; i <numClips; i++)
  179.             {
  180.                 var clip:DisplayObject = this._items[i].item;
  181.                 var clipX:Number = this._items[i].x;
  182.                 var clipY:Number = this._items[i].y;
  183.                 var x:Number;
  184.                 var y:Number;
  185.                
  186.                 switch (this._items[i].mode)
  187.                 {
  188.                     case "TL":
  189.                         x = (0 + clipX);
  190.                         y = (0 + clipY);
  191.                         break;
  192.                    
  193.                     case "TC":
  194.                         x = (((this._stage.stageWidth * .5) - (clip.width * .5)) + clipX);
  195.                         y = (0 + clipY);
  196.                         break;
  197.                        
  198.                     case "TR":
  199.                         x = ((this._stage.stageWidth - clip.width) + clipX);
  200.                         y = (0 + clipY);
  201.                         break;
  202.                        
  203.                     case "ML":
  204.                         x = (0 + clipX);
  205.                         y = (((this._stage.stageHeight * .5) - (clip.height * .5)) + clipY);
  206.                         break;
  207.                        
  208.                     case "MC":
  209.                         x = (((this._stage.stageWidth * .5) - (clip.width * .5)) + clipX);
  210.                         y = (((this._stage.stageHeight * .5) - (clip.height * .5)) + clipY);
  211.                         break;
  212.                        
  213.                     case "MR":
  214.                         x = ((this._stage.stageWidth - clip.width) + clipX);
  215.                         y = (((this._stage.stageHeight * .5) - (clip.height * .5)) + clipY);
  216.                         break;
  217.                        
  218.                     case "BL":
  219.                         x = (0 + clipX);
  220.                         y = ((this._stage.stageHeight - clip.height) + clipY);
  221.                         break;
  222.                        
  223.                     case "BC":
  224.                         x = (((this._stage.stageWidth * .5) - (clip.width * .5)) + clipX);
  225.                         y = ((this._stage.stageHeight - clip.height) + clipY);
  226.                         break;
  227.                        
  228.                     case "BR":
  229.                         x = ((this._stage.stageWidth - clip.width) + clipX);
  230.                         y = ((this._stage.stageHeight - clip.height) + clipY);
  231.                         break;
  232.                 }
  233.                
  234.                 this._tweenX = new Tween(clip, "x", this._easeFunc, clip.x, x, this._easeTime, true);
  235.                 this._tweenY = new Tween(clip, "y", this._easeFunc, clip.y, y, this._easeTime, true);
  236.             }
  237.         }
  238.        
  239. //- PUBLIC & INTERNAL METHODS -----------------------------------------------------------------------------
  240.    
  241.         /**
  242.          * Initializes the StageManager and helps avoid the FireFox bug (won't manage the stage on initial load).
  243.          *
  244.          * @usage <code>sm.init();</code>
  245.          *
  246.          * @return void
  247.          */
  248.        
  249.         public function init():void
  250.         {
  251.             this._stage.dispatchEvent(new Event(Event.RESIZE));
  252.         }
  253.  
  254.         /**
  255.          * Adds an item to the items array so that is is tracked when resizing. $offsetX and $offsetY are optional and can be left blank to use no offsets.
  256.          *
  257.          * <p>
  258.          * The $alignMode parameter can be any of the following string values:
  259.          * <ul>
  260.          * <li>"TL": top left</li>
  261.          * <li>"TC": top center</li>
  262.          * <li>"TR": top right</li>
  263.          * <li>"ML": middle left</li>
  264.          * <li>"MC": middle center</li>
  265.          * <li>"MR": middle right</li>
  266.          * <li>"BL": bottom left</li>
  267.          * <li>"BC": bottom center</li>
  268.          * <li>"BR": bottom right</li>
  269.          * </ul>
  270.          * </p>
  271.          *
  272.          * @usage <code>sm.addItem(test2_mc, "TL", 10, 30);</code>
  273.          *
  274.          * @param $item The item that is to be added to the items array.
  275.          * @param $alignMode A string value that represents the mode to align the item to.
  276.          * @param $offsetX An optional number that represents the value to offset the item on its x axis from its align spot (negative offsets left).
  277.          * @param $offsetY An optional number that represents the value to offset the item on its y axis from its align spot (negative offsets up).
  278.          *
  279.          * @return void
  280.          */
  281.        
  282.         public function addItem($item:DisplayObject, $alignMode:String, $offsetX:Number = 0, $offsetY:Number = 0):void
  283.         {
  284.             this._items.push({item: $item, mode: $alignMode, x: $offsetX, y: $offsetY});
  285.         }
  286.        
  287.         /**
  288.          * Removes an item from the items array so it is no longer tracked by the resizing.
  289.          *
  290.          * @usage <code>sm.removeItem(test_mc);</code>
  291.          *
  292.          * @param $item The item that is to be removed from the items array.
  293.          *
  294.          * @return void
  295.          */
  296.        
  297.         public function removeItem($item:DisplayObject):void
  298.         {
  299.             var numClips:int = this._items.length;
  300.            
  301.             for (var i:int = 0; i <numClips; i++)
  302.             {
  303.                 var item:DisplayObject = this._items[i].item;
  304.                
  305.                 if (item == $item)
  306.                 {
  307.                     this._items.splice(i, 1);
  308.                 }
  309.             }
  310.         }
  311.    
  312. //- EVENT HANDLERS ----------------------------------------------------------------------------------------
  313.    
  314.        
  315.    
  316. //- GETTERS & SETTERS -------------------------------------------------------------------------------------
  317.    
  318.         /**
  319.          * Returns the current items array.
  320.          *
  321.          * @usage <code>trace(sm.items);</code>
  322.          *
  323.          * @return An array of the items currently being aligned to the stage.
  324.          */
  325.        
  326.         public function get items():Array
  327.         {
  328.             return this._items;
  329.         }
  330.    
  331. //- HELPERS -----------------------------------------------------------------------------------------------
  332.    
  333.         public override function toString():String
  334.         {
  335.             return "com.reintroducing.utils.StageManager";
  336.         }
  337.    
  338. //- END CLASS ---------------------------------------------------------------------------------------------
  339.     }
  340. }

If you found this post useful, please consider leaving a comment, subscribing to the feed, or making a small donation.

14 Comments

[...] stumbleupon, technorati, twitter, more '; AS3 StageManager 1 Minute Ago View Example View Blog Post The StageManager aligns items according to their selected alignment mode. You have the ability to [...]

Thanks Matt ! very much !!!

Great class !

Very handy, thanks!

hi,

how would you go about to set a constraint (stage dimension)using this class? Like if I want to let user able to resize but the minimum stage size cant be smaller than 350x200...

thanks.

Hey Rich,
The class isn't designed to do that right now, but that's actually a very good option to have. I'll try to add that in soon but unfortunately it probably won't be until next week as I'm heading off to FITC tomorrow morning.

Thanks for the suggestion!

Thank you !
I have just tried and just change this class. Instead of Tween class i've used Tweener class. It work !

I am going to use it in my plans and I would make you of comebacks if I find error..

Mika

Glad you like it Mika, but why edit it to use Tweener? Did you change the functionality or just wanted to use Tweener in it? I didn't include a tweening engine because i didn't want to have to include dependencies, but if you insist on using a tweening engine i would go with TweenLite (http://www.tweenlite.com). It's updated more frequently, faster, and more lightweight than Tweener.

I think that native Flash Tweens are very restricted. Tweener give you more posibilities. Like bezier etc...

I think Tweener is better than Tweenlight because i met several bug with Tweenlight.

Thank's a lot for this StageManager

(sorry for my english )

[...] Voici la source : lien [...]

no problem about your english.

what bugs have you run into with TweenLite? I assure you there are not many (if any at all) bugs in the engine. I use it on a daily basis and push it a lot and it has better bezier tweening capabilities than Tweener.

Nice class dude! Thanks. Like the tweening

you're welcome, thomas.

Very, very helpful... Thank you very much for this class...

Hi There,
I'm trying to implement your stage manager and for some reason one of the assets goes off the stage and comes back to its right position only after me manually changing the size of the window...

here'smy code:
addChild(myOcean);
sm=new StageManager(stage,"easing",.5,Regular.easeOut);
sm.addEventListener(StageManagerEvent.ON_RESIZE, resizeHandler);

sm.addItem(myOcean, "BC");
sm.init();

Leave a comment

(required)

(required)