1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| package utils
{
import flash.display.Shape;
import flash.geom.Point;
public class BezierLine extends Shape
{
private var _time :Number = 0;
private var _prevTime :Number = 0;
private var _threshold :Number;
private var _frozen :Boolean = true;
private var anchor1 :Point;
private var anchor2 :Point;
private var control1 :Point;
private var control2 :Point;
private var _lineStyle :Object = { thickness:2, color:0xffffff, alpha:.35 };
public function BezierLine( $anchor1:Point, $control1:Point, $control2:Point, $anchor2:Point, $threshold:Number = .025, $lineStyle:Object = null )
{
anchor1 = $anchor1;
anchor2 = $anchor2;
control1 = $control1;
control2 = $control2;
_threshold = $threshold;
if( $lineStyle )
this.graphics.lineStyle( $lineStyle.thickness, $lineStyle.color, $lineStyle.alpha );
else
this.graphics.lineStyle( _lineStyle.thickness, _lineStyle.color, _lineStyle.alpha );
this.graphics.moveTo( anchor1.x, anchor1.y );
}
private function updateLine():void
{
if( _frozen ) return;
var len:int = 1, i:int, dif:Number,
posx:Number, posy:Number, u:Number;
if( _time < 1 )
{
dif = _time - _prevTime;
//check to see if the difference between last frame and this is under
//the threshold, if it is, change the length of the for loop for
//how many segments the current line will be broken in to
if( dif > _threshold ) len = Math.ceil( dif / _threshold );
for( i = 0; i < len; ++i )
{
//if on last loop (or first of len=1) set to time, else
//increment thru the time by the threshold amount, making smoother lines
if( i == len - 1 )
u = _time;
else
u = _prevTime + ( i * _threshold );
//draw lines based on http://www.paultondeur.com/2008/03/09/drawing-a-cubic-bezier-curve-using-actionscript-3/
posx = Math.pow(u,3)*(anchor2.x+3*(control1.x-control2.x)-anchor1.x)
+3*Math.pow(u,2)*(anchor1.x-2*control1.x+control2.x)
+3*u*(control1.x-anchor1.x)+anchor1.x;
posy = Math.pow(u,3)*(anchor2.y+3*(control1.y-control2.y)-anchor1.y)
+3*Math.pow(u,2)*(anchor1.y-2*control1.y+control2.y)
+3*u*(control1.y-anchor1.y)+anchor1.y;
this.graphics.lineTo(posx,posy);
}
}
else
this.graphics.lineTo(anchor2.x,anchor2.y);
_prevTime = _time;
}
public function clear():void
{
_frozen = true;
this.graphics.clear();
}
public function get time():Number
{
return _time;
}
/**
* Tween this value from 0-1 to animate the line in and out.
*/
public function set time(value:Number):void
{
_time = value;
_frozen = false;
updateLine();
}
}
} |