After some tweaking with the string thing.. I have finally made a class out of it.
here is the class, place it in a folder interactingweb or change the package name accordingly where your fla file is present.
package interactingweb
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
public class cord extends Sprite
{
public static const CT_ATTACH:String = "Attach";
public static const CT_FOLLOW:String = "Follow";
public static const CT_REPEL:String = "Repel";
public static const CT_ATTRACT:String = "Attract";
private var gotonodes:Array = new Array();
private var currentnodes:Array = new Array();
private var cordType:String = CT_ATTACH;
private var cordSeg:int = 15;
private var cords:Sprite;
private var x1cor:Number;
private var y1cor:Number;
private var x2cor:Number;
private var y2cor:Number;
private var haschild:Boolean = false;
private var maxDist:Number = 10;
private var lineClr:uint = 0xffffff;
private var circleClr:uint = 0xffffff;
private var drawObj:Boolean = false;
public function cord(type:String, x1CoOr:Number, y1CoOr:Number, x2CoOr:Number, y2CoOr:Number)
{
if(type == CT_ATTACH || type == CT_FOLLOW || type == CT_REPEL || type == CT_ATTRACT)
cordType = type;
if(cordType == CT_FOLLOW)
{
x2cor = x1CoOr;
y2cor = y1CoOr;
x1cor = x2CoOr;
y1cor = y2CoOr;
}
else
{
x1cor = x1CoOr;
y1cor = y1CoOr;
x2cor = x2CoOr;
y2cor = y2CoOr;
}
gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
currentnodes=gotonodes;
}
public function setSegment(seg:int)
{
if(seg>=1)
cordSeg = seg;
gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
currentnodes=gotonodes;
}
public function setType(type:String)
{
var switchType:Boolean = false;
if(cordType == CT_FOLLOW || type == CT_FOLLOW)
switchType = true;
if(type == CT_ATTACH || type == CT_FOLLOW || type == CT_REPEL || type == CT_ATTRACT)
cordType = type;
if(switchType)
{
var tempx:Number = x2cor;
var tempy:Number = y2cor;
x2cor = x1cor;
y2cor = y1cor;
x1cor = tempx;
y1cor = tempy;
}
gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
currentnodes=gotonodes;
}
public function setMaxDist(distance:Number):void
{
if(cordType == CT_ATTACH || cordType == CT_FOLLOW)
{
if(distance >= 0)
maxDist = distance;
}
else
{
if(distance >=1)
maxDist = distance;
}
}
public function setLineClr(color:uint):void
{
lineClr=color;
}
public function setCircleClr(color:uint):void
{
circleClr=color;
}
public function setDrawObj(bool:Boolean):void
{
drawObj=bool;
}
private function Interpolate(x1:Number,y1:Number,x2:Number,y2:Number,n:int):Array
{
var tempx:Number = x2;
var tempy:Number = y2;
var ang = Math.atan2(tempy-y1, tempx-x1);
if(cordType == CT_FOLLOW)
{
tempx = x2 - maxDist*Math.cos(ang);
tempy = y2 - maxDist*Math.sin(ang);
}
else if(cordType == CT_ATTACH)
{
x1 += maxDist*Math.cos(ang);
y1 += maxDist*Math.sin(ang);
}
var dist= Math.sqrt(Math.pow(tempx-x1,2)+Math.pow(tempy-y1,2));
var points = [];
for(var l = -2;l<=dist;l+=dist/n)
{
var x3 =x1+l*Math.cos(ang);
var y3 = y1+l*Math.sin(ang);
points.push({xco:x3,yco:y3});
}
points.push({xco:x1,yco:y1});
if(cordType == CT_FOLLOW)
points.push({xco:x1,yco:y1});
return points;
}
public function DrawNodes():void
{
if(haschild) removeChild(cords);
cords = new Sprite();
addChild(cords);
haschild=true;
cords.graphics.lineStyle(1,lineClr,40);
cords.graphics.moveTo(currentnodes[0].xco,currentnodes[0].yco);
if(cordType == CT_FOLLOW)
{
for(var j = 0; j<currentnodes.length-2;j++)
{
cords.graphics.lineTo(currentnodes[j].xco,currentnodes[j].yco);
}
cords.graphics.beginFill(circleClr,1);
if(drawObj)
cords.graphics.drawCircle(currentnodes[currentnodes.length-3].xco,currentnodes[currentnodes.length-3].yco,5);
}
else
{
for(var i = 0; i<currentnodes.length-1;i++)
{
cords.graphics.lineTo(currentnodes[i].xco,currentnodes[i].yco);
}
cords.graphics.beginFill(circleClr,1);
if(drawObj)
cords.graphics.drawCircle(currentnodes[0].xco,currentnodes[0].yco,5);
}
cords.graphics.endFill();
}
public function updateSeg(xcoordinate:Number,ycoordinate:Number)
{
if(cordType == CT_ATTACH)
{
x1cor = xcoordinate;
y1cor = ycoordinate;
gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
}
else if(cordType == CT_FOLLOW)
{
x2cor = xcoordinate;
y2cor = ycoordinate;
gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
}
else if(cordType == CT_REPEL)
{
var dx:Number = x1cor-xcoordinate;
var dy:Number = y1cor-ycoordinate;
var dist:Number = Math.sqrt(dx*dx+dy*dy);
var dir:Number = Math.atan2(dy, dx);
if(dist<maxDist)
{
var tempx:Number = Math.cos(dir)*(maxDist-dist) + x1cor;
var tempy:Number = Math.sin(dir)*(maxDist-dist) + y1cor;
if (dist > maxDist) dist = maxDist;
gotonodes=Interpolate(tempx,tempy,x2cor,y2cor,cordSeg);
}
else gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
}
else
{
var dx1:Number = x1cor-xcoordinate;
var dy1:Number = y1cor-ycoordinate;
var dist1:Number = Math.sqrt(dx1*dx1+dy1*dy1);
if(dist1<maxDist) gotonodes=Interpolate(xcoordinate,ycoordinate,x2cor,y2cor,cordSeg);
else gotonodes=Interpolate(x1cor,y1cor,x2cor,y2cor,cordSeg);
}
}
public function updateCord()
{
for(var node = 0; node<gotonodes.length-1 || node<currentnodes.length-1;node++)
{
currentnodes[node].xco=currentnodes[node].xco+(gotonodes[node].xco-currentnodes[node].xco)/(node*node/30+1);
currentnodes[node].yco=currentnodes[node].yco+(gotonodes[node].yco-currentnodes[node].yco)/(node*node/30+1);
}
DrawNodes();
}
}
}
In fla file, all you do as below
- import the package
- create a cord object (you can also change the cord type later using setCordType)
- Call DrawNodes method to actually initiate a drawing object
- two key functions of animation
- updateSeg which will update the segments.
- updateCord which will update the cord itself.
- Few fields worth noting
- Cord type: This can be changed by setCordType method, there are four types namely
- CT_ATTACH
- CT_FOLLOW
- CT_REPEL
- CT_ATTRACT
- Maximum Distance: This can be changed by setMaxDist method, default value is 10 and for cord types CT_ATTACH and CT_FOLLOW min value is 0 and for other two min value is 1. This is the distance maintained by the cord end.
- Draw Object: This can be changed by setDrawObj method, default is false. If enabled will draw a circle of radius 5.
- Cord Segments: This can be changed by setCordSeg method. default is 15 no of segments to break the cord into, more the number higher the precession(don’t go too much, it will be a CPU overhead).
- Line and Circle Color: This can be changed by setLineClr and setCircleClr respectively. default is white(0xffffff). Pass as valid value as there is no check for the correctness of data.
for ex:-
import interactingweb.*;
var temp:cord = new cord(cord.CT_FOLLOW,this.x,this.y,this.x,stage.stageHeight);
temp.setType(cord.CT_ATTACH);
temp.setSegment(25);
temp.setMaxDist(0);
temp.setDrawObj(true);
temp.DrawNodes();
stage.addChild(temp);
stage.addEventListener(Event.ENTER_FRAME, onmove1);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onmove);
function onmove(e:MouseEvent)
{
temp.updateSeg(stage.mouseX,stage.mouseY);
}
function onmove1(e:Event)
{
temp.updateCord();
}
Play around with temp cord object… Have fun.