I couldn’t do my job without tweening classes like the amazing TweenMax. But who sais you have to tween the properties of a display object? Why not tween the properties of “just an object” and then use the drawing api to connect all the dots? Just like those “draw me by following the numbers” drawings you loved as a kid
In this case, I’m using the stunning bezierTrough feature of TweenMax to fluidly draw the line.
Continue reading for source code (ofcourse you’ll be needing the TweenMax classes):
package
{
import gs.TweenMax;
import gs.easing.Sine;
import flash.display.Sprite;
/**
* @author josfaber
*/
public class LineWriterBezier extends Sprite
{
private var __points : Array = [
{color:0xFFFFFF, points:[ {x:50, y:-50},{x:100, y:0},{x:250, y:650},{x:300, y:700},{x:350, y:650} ]},
{color:0xFFDD00, points:[ {x:220, y:-120},{x:300, y:0},{x:350, y:50},{x:370, y:-90},{x:470, y:-80} ]},
{color:0x00AA00, points:[ {x:600, y:-120},{x:900, y:200} ]},
{color:0xAA00AA, points:[ {x:1100, y:400},{x:700, y:150} ]},
{color:0x0099AA, points:[ {x:-150, y:150}, {x:0, y:0} ]},
];
private var __pos : Object = {x:0, y:0};
private var __cur : int = 0;
private var __canvas : Sprite;
private var __maxspeed : int = 10;
public function LineWriterBezier()
{
// setup movable canvas (inverse camera)
__canvas = new Sprite( );
__canvas.x = .5 * stage.stageWidth;
__canvas.y = .5 * stage.stageHeight;
addChild( __canvas );
// draw markers
drawMarkers();
// setup initial position
__canvas.graphics.moveTo( __pos.x, __pos.y );
// set it off
nextTween( );
}
private function drawMarkers():void
{
for (var i : int = 0; i < __points.length; i++)
{
for (var j : int = 0; j < __points[i].points.length; j++)
{
__canvas.graphics.lineStyle( 1, __points[i].color, 1, true );
__canvas.graphics.drawCircle( __points[i].points[j].x, __points[i].points[j].y, 10 );
}
}
}
private function nextTween() : void
{
var numpoints:int = __points[__cur].points.length;
TweenMax.to( __pos, 2 + .5 * numpoints, {onComplete:next, onUpdate:update, onUpdateParams:[__points[__cur].color], bezierThrough:__points[__cur].points, orientToBezier:false, ease:Sine.easeInOut} );
}
private function update(color:uint = 0xFFFFFF) : void
{
// draw it
__canvas.graphics.lineStyle( 5, color, 1 );
__canvas.graphics.lineTo( __pos.x, __pos.y );
// move canvas delayed
var targX : Number = .5 * stage.stageWidth - __pos.x;
var targY : Number = .5 * stage.stageHeight - __pos.y;
var addX : Number = Math.min( __maxspeed, Math.max( -__maxspeed, .25 * ( targX - __canvas.x ) ) );
var addY : Number = Math.min( __maxspeed, Math.max( -__maxspeed, .25 * ( targY - __canvas.y ) ) );
__canvas.x += addX;
__canvas.y += addY;
}
private function next():void
{
__cur = __cur < __points.length - 1 ? __cur + 1 : 0;
if ( __cur == 0 )
{
__canvas.graphics.clear();
drawMarkers();
}
nextTween();
}
}
}
