Jump to content
Search Community

Rotation Snap

scottiescotsman test
Moderator Tag

Recommended Posts

var dial:Sprite;
var radius:Number = 0;
var angle:Number = 0;
var angleConvert:Number = 180 / Math.PI;

init();

function init():void
{
makeDial();
makeOrb();
}

function onMove(e:MouseEvent):void
{
angle = Math.atan2(mouseY - dial.y, mouseX - dial.x);
volumeMC.rotation = angleConvert * angle + 90;
}

function onOrbDown(e:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.addEventListener(MouseEvent.MOUSE_UP, onOrbUp);
}

function onOrbUp(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
stage.removeEventListener(MouseEvent.MOUSE_UP, onOrbUp);
}

function makeDial():void {
dial = new Sprite();
var g:Graphics = dial.graphics;
g.lineStyle(2, 0x333333);
g.drawCircle(0, 0, radius);
dial.x = 170;
dial.y = 370;
addChild(dial);
}

function makeOrb():void {

volumeMC.buttonMode = volumeMC.useHandCursor = true;
volumeMC.addEventListener(MouseEvent.MOUSE_DOWN, onOrbDown);
}

Hi :)

I have a volumeMC dial that drags and drops great, but I want to use the rotation snap in tweenMax to make this better.

All I want it to do is ....

 

1] drag rotate volumeMC around its own centre from 0-360deg in 10deg intervals.

2] to trace the current rotation value to I can adjust the sound.

 

here is what I have that works but I don't like it ...

 

 

hope someone can help :)

 

Steven

 

Link to comment
Share on other sites

The only thing I can offer in addition is a method that will take any number and snap to any increment.

So if you can smoothly drag your mc in a circle you should be able to pass the current rotation value into such a function.

 

Just paste this code into a blank fla to see how it works

 

trace( "snap 33 to nearest increment of 20  = " + snapTo(33, 20)); //output 40
trace( "snap 8 to nearest increment of 5  = " + snapTo(8, 5)); //output 10
trace( "snap 2223 to nearest increment of 500  = " + snapTo(2223, 500)); //output 2500

//convert 0-360 to increments of 10
for (var i:int = 0; i <360; i++) {
    trace(snapTo(i, 10));  // 10, 20, 30, ... 100, 110, 120, ... 340, 350, 360
}

//given number, snap increment
function snapTo(num, snap) {
     return Math.round(num / snap) * snap; 
}
  • Like 1
Link to comment
Share on other sites

Thanks for supporting GreenSock through the purchase of your membership.

I wish you much success with the bonus plugins and tools. 

 

I took a quick crack at updating the dial demo.

I don't have time to go into great detail but basically I used a proxy object to spin and get rotation values and then I snapped those values to 30 degree increments and applied them to the dial. In other words there is an invisible dial sitting on top of the green dial that spins smoothly and I translate those values to the rotation of the visible dial. 

 

Check out the attached zip. Unzip and place the fla next to your com folder.

To change the snap value to 10, just edit line 54:

var rotationSnap = 30;

 

From what you describe you don't need the throwing, but its in there.

 

Online preview: http://www.fastswf.com/8mzov0A

rotation-snap.zip

Link to comment
Share on other sites

  • 2 months later...
/*********************************************************/

function mouseDownHandler(event:MouseEvent):void
{
	TweenLite.killTweensOf(main_Player.dial);
	offset = Math.atan2(main_Player.dial.y - this.mouseY, this.mouseX - main_Player.dial.x);
	r1 = r2 = main_Player.dial.rotation;
	t1 = t2 = getTimer();
	main_Player.dial.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
	main_Player.dial.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}

/*********************************************************/

function mouseUpHandler(event:MouseEvent):void
{
	main_Player.dial.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
	main_Player.dial.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
	var time: Number = (getTimer() - t2) / 1000;
	var dif: Number = main_Player.dial.rotation - r2;
	if (dif != dif % 180) {
		dif += (dif < 0) ? 360 : -360;
	}
	var rVelocity: Number = dif / time;
	ThrowPropsPlugin.to(main_Player.dial, {
		throwProps: {
			rotation: {
				velocity: rVelocity,
				resistance: 250,
				end: getEnd
			}
		},
		onUpdate: snapEnd,
		ease: Strong.easeOut
	}, 10, 0.25, 2);
}

/*********************************************************/

function getEnd(endValue)
{
	var rotationSnap = 30;
	return Math.round(endValue / rotationSnap) * rotationSnap;
}

/*********************************************************/

function snapEnd():void
{
	//volumeTxt.text = String(int(degFromRot(dial.rotation)));
}

/*********************************************************/

function degFromRot(p_rotInput: Number):Number
{
	var degOutput: Number = p_rotInput;
	while (degOutput >= 360) {
		degOutput -= 360;
	}
	while (degOutput < 0) {
		degOutput += 360;
	}
	return degOutput;
}

/*********************************************************/

Tried to figure out how to restrict it to 0-360 ?

As I have it working perfectly apart from I can rotate it constantly with no restrictions, as it is a volume controller and needs to stop @ 360 & 0 deg

 

Thanks

Steven 

Link to comment
Share on other sites

Jamie that doesn't work m8 :(

 

dial starts @ 12 o'clock [volume = 0] and works great at rotating and changing the volume. With the only problem being it keeps rotating and changing volume even if I rotate < 0 or > 360.

 

the code you had written as it didn't restrict the rotation at all, and if I mouse UP just after 6 o'clock it snapped to 12 o'clock.

 

Sorry to be a nuisance.... plz help

 

Steven

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...