package { import flash.display.Shape; import flash.display.Sprite; import flash.events.Event; import flash.geom.Matrix3D; [SWF(width=600, height=400, backgroundColor=0x000000)] /** * Demonstrates how methods of Matrix3D can be used to manage depths of display objects * in order to place them in accordance to their z position. */ public class graphic_flex_image_effects_06_Flex_ManagingDepth extends Sprite { private static const RADIUS:uint = 200; private static const TOTAL_RECTS:uint = 20; private static const ANGLE_BETWEEN:Number = 360/TOTAL_RECTS * Math.PI/180; private var _rectangleHolder:Sprite; private var _rectangles:Array; /** * Constructor. Centers and rotates sprite, creates rectangles and sets up * handler for ENTER_FRAME event which will handle animation. */ public function graphic_flex_image_effects_06_Flex_ManagingDepth() { x = stage.stageWidth/2; y = stage.stageHeight/2; rotationX = 10; createRectangles(); addEventListener(Event.ENTER_FRAME, onSpriteEnterFrame); } /** * Creates the rectangle shapes as well as the array that * will hold the depths that will be sorted. */ private function createRectangles():void { _rectangleHolder = new Sprite(); _rectangles = []; var rectangle:Shape; for (var i:uint = 0; i < TOTAL_RECTS; i++) { rectangle = createRectangle(i); _rectangleHolder.addChild(rectangle); // z will be reassigned in ENTER_FRAME based on rect z depth, // at which point this array can be sorted by z value _rectangles.push({shape:rectangle, z:0}); } addChild(_rectangleHolder); } /** * Creates a rectangle shape at the specified index, which controls * its placement in its parent. * * @param index The index of the shape being created. * * @return The shape created. */ private function createRectangle(index:uint):Shape { var rectangle:Shape = new Shape(); rectangle.graphics.beginFill(Math.random()*0xFFFFFF); rectangle.graphics.drawRect(-20, -40, 40, 80); rectangle.graphics.endFill(); // place on radius of circle based on index value rectangle.x = Math.cos(ANGLE_BETWEEN*index)*RADIUS; rectangle.z = Math.sin(ANGLE_BETWEEN*index)*RADIUS; return rectangle; } /** * Sets the depths of rectangles based on their z positions. */ private function setDepths():void { var matrix:Matrix3D; for each (var rectangle:Object in _rectangles) { // find shape's transform in root coordinate system matrix = rectangle.shape.transform.getRelativeMatrix3D(root); // assign z value to object array so that it can be sorted by value rectangle.z = matrix.position.z; } // sort array based on z, placing depths from high to low _rectangles.sortOn("z", Array.NUMERIC | Array.DESCENDING); for each (rectangle in _rectangles) { // add each child in order of depth _rectangleHolder.addChild(rectangle.shape); } } /** * Handler for ENTER_FRAME event, rotates the sprite holding the rectangles * as well as the rectangles themselves so that they face the viewer. * * @param event Event dispatched by this sprite. */ private function onSpriteEnterFrame(event:Event):void { _rectangleHolder.rotationY += 1; for each (var rectangle:Object in _rectangles) { rectangle.shape.rotationY -= 1; } setDepths(); } } }