Drag a clock hand around the clock

Is there s simple way to code a user control analog clock. I am just looking for the ability to drag the big (minute) hand around the clock.

This is as far as I’ve gotten:

class Main extends Sprite 
{

public var clock:Bitmap = new Bitmap(Assets.getBitmapData("img/clock.png"));
public var bigHandBMP:Bitmap = new Bitmap(Assets.getBitmapData("img/handBig.png"));

public var bigHand:MovieClip = new MovieClip();

public var xPos:Float = 0;
public var yPos:Float = 0;
public var oldRotation:Float = 0;
public var pressing:Bool = false;

public function new() 
{
	super();
	
	addChild(clock);
	bigHandBMP.x = -30;
	bigHandBMP.y = -292;
	bigHand.addChild(bigHandBMP);
	bigHand.x = 300;
	bigHand.y = 300;
	addChild(bigHand);	
	
	stage.addEventListener(MouseEvent.MOUSE_DOWN, ClickHandler);
	stage.addEventListener(MouseEvent.MOUSE_UP, ReleaseHandler);
	stage.addEventListener(MouseEvent.MOUSE_MOVE, MovingHandler);
	
}
public function MovingHandler(m:MouseEvent)
{
	if (pressing == true) {
		if (bigHand.rotation >= -90 && bigHand.rotation <= 90) {				
			bigHand.rotation = oldRotation + stage.mouseX - xPos;				
		}
	}
}
public function ClickHandler(m:MouseEvent)
{
	if (bigHand.hitTestPoint(mouseX, mouseY, true) && pressing == false) {
		pressing = true;
		xPos = stage.mouseX;
		oldRotation = bigHand.rotation;
	}
}
public function ReleaseHandler(m:MouseEvent)
{
	pressing = false;
}

1.) Make sure that you have the origin of your clock hand right at the rotation point so you can animate it smoothly
2.) Get the X/Y position of the mouse relative to the origin point
3.) Use trigonometry methods to determine the correct rotation (“soh cah toa” so “sin(x) = opposite/hypotenuse”, “cos(x) = adjacent/hypotenuse”, “tan(x) = opposite/adjacent”)

image

Looks like tangent is your friend here. You don’t know the rotation value (x) but you do know the opposite and adjacent values. If memory serves you can use the “arc tangent” to take the opposite/adjacent values and find the rotation value:

var adjacent = mouseX - clockHand.x;
var opposite = -(mouseY - clockHand.y);
var rotationInRadians = Math.atan(opposite / adjacent);
var rotation = rotationInRadians * (360 / (Math.PI / 2));

4.) Apply that to your clock hand

clockHand.rotation = rotation;

5.) (Optional) Use Actuate to smooth out the animation

Actuate.tween(clockHand, 1, { rotation: rotation }).smartRotation ();

Apologies if I’m wrong but I believe these concepts should be the basics

2 Likes

If you’d prefer to drag without animation I usually use this combinations of events:

1.) Add a MOUSE_DOWN event listener to the object
2.) When MOUSE_DOWN fires, add MOUSE_MOVE and MOUSE_UP listeners to the stage
3.) When MOUSE_MOVE fires, update the drag position
4.) When MOUSE_UP fires, remove both the MOUSE_MOVE and MOUSE_UP listeners

1 Like