Sunday, 28 June 2009

Twistable Flash object with ActionScript3

Hi Readers,

It came to my mind I've never made a twistable element in Flash. So I wrote one. The basics:
It needs an item (descendant of the DisplayObject class) to twist. Don't forget to position this element to the point you want to twist around. (Most cases it is the center point.) My idea is when you click on the object, you store the current angle relative to center of ui element and store the current angle of the object. Then if you move your cursor, you will know the difference between the initial angle and the current angle. And you add this difference to the stored angle of the object. [It is easy, however, my english makes it hard to understand.] The interesting thing is to get the angle from a cursor position. I thought that the good old trigonometrics functions give the shade between 0 and 360 but, it came to light, I was wrong. Some recall:
[http://en.wikipedia.org/wiki/Sine#Sine]
A triangle with a 90 degree angle has 3 side: adjacent, opposite, hypotenuse. You can calculate the tangent alpha by division of the oposite with adjacent. Arctangent gives the reverse of tangent, so atan(tan(alpha)) = aplha. But if you make some test you realize its not the whole 360 degree (or 2PI in rad) but 2 peaces of 180. Strange, but I have never been a math guy.

Anyway, here you are my quick source. Just paste to a Flash IDE as it is and run it.
var angle_onDown:Number;
var angle_potmeter:Number;
var is_turn:Boolean = false;

var potmeter = new Sprite();
potmeter.graphics.beginFill(0xAA4422);
potmeter.graphics.drawRoundRect(-100, -100, 200, 200, 20, 20);
potmeter.graphics.endFill();
potmeter.x = potmeter.y = 200;
addChild(potmeter);

potmeter.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
potmeter.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
potmeter.addEventListener(MouseEvent.MOUSE_UP, onUp);

function onDown(event:MouseEvent):void {
is_turn = true;
angle_onDown = getCurrentAngle(event.stageX - potmeter.x, event.stageY - potmeter.y);
angle_potmeter = potmeter.rotation;
}

function onMove(event:MouseEvent):void {
if (is_turn) {
potmeter.rotation = angle_potmeter - (angle_onDown - getCurrentAngle(event.stageX - potmeter.x, event.stageY - potmeter.y));
}
}

function onUp(event:MouseEvent):void {
is_turn = false;
}

function getCurrentAngle(relX:Number, relY:Number):Number {
var relDegree:Number = Math.atan(relY / relX) / Math.PI * 180;
return relX < 0 ? 180.0 + relDegree : relDegree;
}

You can grab the rectangle and twist.

I would be happy if anyone can explain why the formula in the getCurrentAngle() function gives 2 peaces of 180 interval? (That is why I added the ternary operator for the return command.)

Night,
Peter

No comments:

Post a Comment