package { import flash.display.GraphicsPathCommand; import flash.display.Sprite; import flash.events.MouseEvent; [SWF(width=550, height=400, backgroundColor=0xFFFFFF)] /** * Demonstrates how Graphics.drawPath() may be used to redraw vector lines by saving the drawing commands and data. */ public class graphic_flex_image_effects_01_Flex_ChangingPointsOnAPath extends Sprite { private const COLOR:uint = 0xFF; private const THICKNESS:uint = 3; private var _pathCommands:Vector.; private var _pathData:Vector.; private var _anchors:Vector.; private var _anchor:Sprite; private var _anchorIndex:uint; /** * Constructor. */ public function graphic_flex_image_effects_01_Flex_ChangingPointsOnAPath() { init(); } /** * Initialization method for instantiating vector arrays and establishing listener for MOUSE_DOWN on the stage. */ private function init():void { _anchors = new Vector.(); _pathCommands = new Vector.(); _pathData = new Vector.(); graphics.lineStyle(THICKNESS, COLOR); stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown); } /** * Adds an anchor point at the specified position. * * @param x The x position of the new anchor. * @param y The y position of the new anchor. */ private function addAnchor(x:Number, y:Number):void { var anchor:Sprite = new Sprite(); // this will draw a big dot anchor.graphics.lineStyle(20); anchor.graphics.lineTo(1, 0); anchor.addEventListener(MouseEvent.MOUSE_DOWN, onAnchorDown); anchor.addEventListener(MouseEvent.MOUSE_UP, onAnchorUp); anchor.x = x; anchor.y = y; addChild(anchor); _anchors.push(anchor); } /** * Uses Graphics.drawPath() to redraw path using commands and data stored in the vectors. */ private function redrawPath():void { graphics.clear(); graphics.lineStyle(THICKNESS, COLOR); graphics.drawPath(_pathCommands, _pathData); var dataLength:uint = _pathData.length; // must move to the last data position so that a new lines are drawn from this position graphics.moveTo(_pathData[dataLength-2], _pathData[dataLength-1]); } /** * Handler for when an anchor point is clicked. This begins drag of anchor point. * * @param event The MouseEvent caused by the click. */ private function onAnchorDown(event:MouseEvent):void { _anchor = event.target as Sprite; _anchor.startDrag(); // save the index so that the anchor's data can be easily accessed in the _pathData vector _anchorIndex = _anchors.indexOf(_anchor); stage.addEventListener(MouseEvent.MOUSE_MOVE, onAnchorMove); event.stopPropagation(); } /** * Handler for when the mouse moves while dragging an anchor. This updates the path data and redraws the path. * * @param event The MouseEvent caused by the move. */ private function onAnchorMove(event:MouseEvent):void { // update the path data that corresponds to the dragged anchor _pathData[_anchorIndex*2] = _anchor.x; _pathData[_anchorIndex*2+1] = _anchor.y; redrawPath(); event.updateAfterEvent(); } /** * Handler for when an anchor point is released after dragging. This removes the stage MOUSE_MOVE listener. * * @param event The MouseEvent caused by the release. */ private function onAnchorUp(event:MouseEvent):void { if (_anchor) { _anchor.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_MOVE, onAnchorMove); } } /** * Handler for when the stage is clicked. This adds a new anchor point and draws to the new anchor. * * @param event The MouseEvent caused by the click. */ private function onStageMouseDown(event:MouseEvent):void { var x:Number = stage.mouseX; var y:Number = stage.mouseY; addAnchor(x, y); // this means this is the first anchor, so only move to position without drawing if (_pathCommands.length < 1) { _pathCommands.push(GraphicsPathCommand.MOVE_TO); graphics.moveTo(x, y); // else there are previous anchors, so simply draw to the new position } else { _pathCommands.push(GraphicsPathCommand.LINE_TO); graphics.lineTo(x, y); } _pathData.push(x, y); } } }