topical media & game development
graphic-flex-draw-classes-ChangingPointsOnAPathCurves.ax
graphic-flex-draw-classes-ChangingPointsOnAPathCurves.ax
[swf]
flex
Based on the code of the book Foundation ActionScript 3.0 Image Effects" by Todd Yard.
package
{
import flash.events.*;
import flash.display.GraphicsPathCommand;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.*;
[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 @ax-graphic-flex-draw-classes-ChangingPointsOnAPathCurves extends Sprite {
private const COLOR:uint = 0xFF;
private const THICKNESS:uint = 3;
private var _pathCommands:Vector.<int>;
private var _pathData:Vector.<Number>;
private var _anchors:Vector.<Sprite>;
private var _controlPoints:Vector.<Sprite>;
private var _anchor:Sprite;
private var _anchorIndex:uint;
Constructor.
public function @ax-graphic-flex-draw-classes-ChangingPointsOnAPathCurves() {
this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
this.init();
}
Initialization method for instantiating vector arrays and establishing listener for MOUSE_DOWN on the stage.
private function init():void {
_anchors = new Vector.<Sprite>();
_controlPoints = new Vector.<Sprite>;
_pathCommands = new Vector.<int>();
_pathData = new Vector.<Number>();
graphics.lineStyle(THICKNESS, COLOR);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
}
Adds an anchor point at the specified position.
parameter: x The x position of the new anchor.
parameter: 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
if(_anchors.length % 2 == 0) anchor.graphics.lineStyle(10);
else anchor.graphics.lineStyle(6,0xFF0000,0.5);
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.
parameter: 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.
parameter: 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();
if(_anchorIndex % 2!= 0){
graphics.lineStyle(1, 0, .5);
graphics.moveTo(_pathData[_anchorIndex*2-2],_pathData[_anchorIndex*2-1])
graphics.lineTo(_anchor.x, _anchor.y);
graphics.lineTo(_pathData[_anchorIndex*2+2],_pathData[_anchorIndex*2+3]);
}
event.updateAfterEvent();
}
Handler for when an anchor point is released after dragging. This removes the stage MOUSE_MOVE listener.
parameter: 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.
parameter: event The MouseEvent caused by the click.
private function onStageMouseDown(event:MouseEvent):void {
var x:Number = stage.mouseX;
var y:Number = stage.mouseY;
// 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);
addAnchor(x, y);
_pathData.push(x, y);
// else there are previous anchors, so simply draw to the new position
} else {
_pathCommands.push(GraphicsPathCommand.CURVE_TO);
var dataLength:uint = _pathData.length;
//calculate the initial values for the control points
var cpX:Number = _pathData[dataLength-2]+(x-_pathData[dataLength-2])/2;
var cpY:Number = _pathData[dataLength-1]+(y -_pathData[dataLength-1])/2;
addAnchor(cpX, cpY);
addAnchor(x, y);
//graphics.curveTo(cpX, cpY, x, y);
_pathData.push(cpX,cpY,x, y);
redrawPath();
}
}
}
}
(C) Æliens
27/08/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.