package { import flash.display.Shape; import flash.display.Sprite; import flash.events.KeyboardEvent; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.GlowFilter; import flash.ui.Keyboard; [SWF(width=550, height=550, backgroundColor=0)] /** * Copies a single shape's vector drawings into several other shapes rotated * around a common point. */ public class graphic_flex_image_effects_01_Flex_CopyingGraphics extends Sprite { private static const INIT_SEGMENTS:uint = 10; private static const MAX_SEGMENTS:uint = 20; private static const MIN_SEGMENTS:uint = 3; private static const THICKNESS:uint = 1; private static const COLOR:uint = 0x66CCCC; private static const ROTATION_RATE:uint = 1; private var _shapeHolder:Sprite; private var _shapes:Vector.; /** * Constructor. */ public function graphic_flex_image_effects_01_Flex_CopyingGraphics() { init(); } /** * Initializes shapes and sets up stage listeners. */ public function init():void { _shapeHolder = new Sprite(); _shapeHolder.x = stage.stageWidth/2; _shapeHolder.y = stage.stageHeight/2; addChild(_shapeHolder); _shapes = new Vector.(); for (var i:uint = 0; i < INIT_SEGMENTS; i++) { addSegment(); } positionSegments(); stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown); stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp); stage.addEventListener(KeyboardEvent.KEY_DOWN, onStageKeyDown); filters = [new GlowFilter(COLOR)]; } /** * Draws a new line in the master shape and copies the master shape's drawing * into the other shapes in the vector array. */ private function draw():void { var shape:Shape = _shapes[0]; shape.graphics.lineTo(shape.mouseX, shape.mouseY); var segments:uint = _shapeHolder.numChildren; // when updating, skip initial shape since that is what is being copied for (var i:uint = 1; i < segments; i++) { _shapes[i].graphics.copyFrom(shape.graphics); } } /** * Adds a new shape to the number of rotated shapes. */ private function addSegment():void { var shape:Shape = new Shape(); // for any but initial shape, simply copy the graphics from the initial shape if (_shapes.length > 0) { shape.graphics.copyFrom(_shapes[0].graphics); // initial shape just needs a linestyle } else { shape.graphics.lineStyle(THICKNESS, COLOR); } _shapes.push(shape); _shapeHolder.addChild(shape); } /** * Removes a segment from the end of the rotated shapes vector. */ private function removeSegment():void { var shape:Shape = _shapes.pop(); _shapeHolder.removeChild(shape); } /** * Rotates all the segments so that they are placed at equal angles around central point. */ private function positionSegments():void { var segments:uint = _shapeHolder.numChildren; var angle:Number = 360/segments; for (var i:uint = 1; i < segments; i++) { _shapes[i].rotation = angle*i; } } /** * Handler for when the stage is clicked. This moves the pen in the master shape to * the clicked position and sets up a listener for ENTER_FRAME. * * @param event The event dispatched by the stage. */ private function onStageMouseDown(event:MouseEvent):void { var shape:Shape = _shapes[0]; shape.graphics.moveTo(shape.mouseX, shape.mouseY); addEventListener(Event.ENTER_FRAME, onThisEnterFrame); } /** * Handler for when the mouse is released on the stage. * This removes the listener for ENTER_FRAME. * * @param event The event dispatched by the stage. */ private function onStageMouseUp(event:MouseEvent):void { removeEventListener(Event.ENTER_FRAME, onThisEnterFrame); } /** * Handler for the ENTER_FRAME event. This rotates all of the shapes and updates the drawing. * * @param event The event dispatched by this sprite. */ private function onThisEnterFrame(event:Event):void { _shapeHolder.rotation += ROTATION_RATE; draw(); } /** * Handler for when a key is pressed. If it is the UP or DOWN arrow, the number of segments * is increased or decreased. * * @param event The event dispatched by the stage. */ private function onStageKeyDown(event:KeyboardEvent):void { switch (event.keyCode) { // for UP arrow key, add a segment if we are within limit case Keyboard.UP: if (_shapeHolder.numChildren < MAX_SEGMENTS) { addSegment(); positionSegments(); } break; // for DOWN arrow key, remove a segment if we are within limit case Keyboard.DOWN: if (_shapeHolder.numChildren > MIN_SEGMENTS) { removeSegment(); positionSegments(); } break; } } } }