30th Oct 2008

arcTo curved animation

While trying to answer another post on Flashkit, ran across an interesting dilemma.

The basic idea here was to create a function that would create a curved animation path to a specified x and y coordinate.

The basic idea here is:

  1. Find the pivot point between the current x and y and the desired x and y.
  2. Calculate the current angle from this pivot point for the current x and y of the clip.
  3. Calculate the ending angle based on the desired ending coordinates and the pivot point.
  4. Using trig, update the x and y of the clip along an arc at a given radius until it reaches the end angle.

After a while of playing with it, came up with this

In AS frame main movie:

import CurvedAnimation;
var ca:CurvedAnimation = new CurvedAnimation(ball);

Class File (this is by no means complete and has some code left over from various previous attempts, but it shows what I finally came up with):

class CurvedAnimation {
private var _clip:MovieClip;
private var startAngle:Number;
private var currentAngle:Number;
public var speed:Number = 1;
public var arcWidth:Number;
private var endAngle:Number;
private var pivotX:Number;
private var pivotY:Number;
private var updateInterval:Number;
public function CurvedAnimation(clip:MovieClip) {
trace(“new curved animation”);
this._clip = clip;
public function arcTo(endX:Number, endY:Number) {
var midWay = Math.sqrt(Math.pow(this._clip._x-endX, 2)+Math.pow(this._clip._y-endY, 2))/2;
this.arcWidth= 100;
_root.endPin._x = endX;
_root.endPin._y = endY;
_root.endPin.lbl_txt.text = “End point”;

if (endX>this._clip._x) {
this.pivotX = Math.floor(this._clip._x+midWay);
} else {
this.pivotX = Math.floor(this._clip._x-midWay);
if (endY>this._clip._Y) {
this.pivotY = Math.floor(this._clip._y+midWay);
} else {
this.pivotY = Math.floor(this._clip._y-midWay);
this.currentAngle = this.startAngle = Math.atan2(this._clip._y – this.pivotY ,this._clip._x – this.pivotX)*180/Math.PI
this.endAngle = Math.atan2(endY – this.pivotY ,endX- this.pivotX)*180/Math.PI
this.updateInterval = setInterval(this, “updatePosition”, 100);
private function debug() {
_root.midPin._x = this.pivotX;
_root.midPin._y = this.pivotY;
_root.midPin.lbl_txt.text = “mid point”;
trace(“Current position x: “+this._clip._x+” y: “+this._clip._y);
trace(“Pivot point x: “+this.pivotX+” y: “+this.pivotY);
trace(“Start Angle “+this.startAngle);
trace(“Current Angle “+this.currentAngle);
trace(“End Angle “+this.endAngle);
_root.debug.mouseAngle.text =this.currentAngle

private function updatePosition(){

//this._clip._y = -0.002644 * Math.pow(((this._clip._x += 5) – 200), 2) + 200;
if (Math.floor(this.currentAngle) <= Math.floor(this.endAngle)){
this._clip._y = this.pivotY + Math.sin(this.currentAngle * (Math.PI/180))*this.arcWidth;
this._clip._x = this.pivotX + Math.cos(this.currentAngle * (Math.PI/180))*this.arcWidth;
this.currentAngle += this.speed;
this.currentAngle %= 360;



Comments are closed.