Monthly Archives: April 2011

Animate any Quadratic BezierLine with me

Wow, it’s been a while. Regardless, let’s get right into it shall we?

So, my code sucks, so feel free to let me know what I could do better, but made this simple class for a project I’m working on now. Hit me up on twitter (@trippedout) if you have any questions.

Fairly simple – pass it two anchor points and two control points, optional threshold and linestyle objects (feel free to change). Threshold controls the amount of times a line is broken down into smaller segs if you’re animating your line quickly and it isn’t smooth enough (smaller is smoother).

Use your favorite tweening engine to tween the ‘time’ attribute and shazam – animated quad beziers!

[cc lang=”php” width=”545″]
var bezLine:BezierLine = new BezierLine( anchor1, control1, control2, anchor2 );
addChild( bezLine ) bezLine, .35, { time:1, ease:Cubic.easeOut } );

[cc lang=”php” width=”545″]
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 ) $lineStyle.thickness, $lineStyle.color, $lineStyle.alpha );
else _lineStyle.thickness, _lineStyle.color, _lineStyle.alpha ); 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 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;,posy); } } else,anchor2.y); _prevTime = _time; } public function clear():void { _frozen = true;; } 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(); } } } [/cc] Be sure to leave a comment if you have any questions/ideas/tell me i suck!