Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Buzzafett

ThrowProps 90 Degrees Rotation Snap

Recommended Posts

I'm using the ThrowProps rotation code, except it doesn't quite work how I want it to.

How would I get the AS3 ThrowProps Rotation Demo.fla code to snap to 90 degrees as in the Draggable js demo?

http://www.greensock.com/draggable/
http://www.greensock.com/js/demo/throwprops/spin.html

Need some AS3 code from the following .js code:

var rotationSnap = 90 * (Math.PI / 180); //90 degrees described in radians (for snapping
Draggable.create("#knob", {type:"rotation", //instead of "x,y" or "top,left", we can simply do "rotation" to make the object spinnable!
throwProps:true, //enables kinetic-based flicking (continuation of movement, decelerating after releasing the mouse/finger)
snap:function(endValue) { //this function gets called by ThrowPropsPlugin when the mouse/finger is released and it plots where rotation should normally end and we can alter that value and return a new one instead. This gives us an easy way to apply custom snapping behavior with any logic we want. In this case, we'll just make sure the end value snaps to 90-degree increments but only when the "snap" checkbox is selected. Keep in mind that rotation values are always defined in radians, not degrees!
return Math.round(endValue / rotationSnap) * rotationSnap;}});
Link to comment
Share on other sites

In the Fla replace your mouseUpHandler with the one below and add the getEnd function

 

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

//NEW FUNCTION
function getEnd(endValue) {
var rotationSnap = 90; Flash needs degrees. no need to convert to radians
return Math.round(endValue / rotationSnap) * rotationSnap;
}

I noticed you had a seemingly related question in another topic about nesting the dial in another symbol. Well, if you want to do that you have to update the code that uses the mouse position of the dials immediate parent to determine the offset and velocity. 

 

Assuming dial is in a clip called container, change ALL instance of this.mouseX and this.mouseY to be container.mouseX and container.mouseY

 

BAD

var newOffset:Number = Math.atan2(dial.y - this.mouseY, this.mouseX - dial.x);

GOOD

var newOffset:Number = Math.atan2(dial.y - container.mouseY, container.mouseX - dial.x);

There is code in the MouseDownHandler and EnterFrameHandler that will need to be updated accordingly.

Link to comment
Share on other sites

Thanks Carl.

 

I amended the new code into a clean version of the ThrowProps Rotation Demo code.fla

The snap code doesn't seem to work.

 

Something to do with the getEnd(endValue) maybe?

import com.greensock.*;
import com.greensock.plugins.*;
import com.greensock.easing.*;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import flash.display.*;

TweenPlugin.activate([ThrowPropsPlugin]);

var RAD2DEG:Number = 180 / Math.PI;
var t1:uint, t2:uint, r1:Number, r2:Number, offset:Number;

dial.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);

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

function enterFrameHandler(event:Event):void {
    r2 = r1;
    t2 = t1;
    var newOffset:Number = Math.atan2(dial.y - this.mouseY, this.mouseX - dial.x);
    dial.rotation += (offset - newOffset) * RAD2DEG;
    offset = newOffset;
    r1 = dial.rotation;
    t1 = getTimer();
}

function mouseUpHandler(event:MouseEvent):void {
dial.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
dial.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
var time:Number = (getTimer() - t2) / 1000;
var dif:Number = dial.rotation - r2;
if (dif != dif % 180) {
dif +=  (dif < 0) ? 360:-360;
}
var rVelocity:Number = dif / time;

//New line of code below
ThrowPropsPlugin.to(dial, {throwProps:{rotation:{velocity:rVelocity, resistance:250, end:getEnd}}, ease:Strong.easeOut}, 10, 0.25, 2);
}

//New Function
function getEnd(endValue) {
var rotationSnap = 90; //Flash needs degrees. No need to convert to radians
return Math.round(endValue / rotationSnap) * rotationSnap;
}
Link to comment
Share on other sites

Weird, I pasted your code into my file and I noticed no problems. Worked great. Rotated smoothly in both directions and always landed on a 90 degree increment.

 

Are you sure you are using the latest version of ThrowProps that is part of your v12 bonus downloads?

Link to comment
Share on other sites

I'm using Greensock v12 Beta.

 

The dial rotates smoothly, but no snap.

Link to comment
Share on other sites

Attached is my fla and swf. Test the swf first before attempting to compile the fla (just so you can see that it does work).

 

Compile with the latest version of ThrowPropsPlugin.as

 

/**
 * VERSION: 12.0.9
 * DATE: 2013-06-25
 * AS3
 * UPDATES AND DOCS AT: http://www.greensock.com
 **/

ThrowProps_rotation_snap.zip

Link to comment
Share on other sites

Thanks again Carl. All is working now.

 

Must just have been one of those restart computer/Flash solutions.

Link to comment
Share on other sites

How would I use the code on several dials without duplicating the entire code? Using an array maybe?

Link to comment
Share on other sites

  • 6 months later...

Thank you very much guys. Being new to AS3, this saved me a lot of time !  :geek:

 

This plugin and examples shown are awesome !

 

If anyone is wondering, I modified the code just a tiny bit to use the same functions for multiple (2 in my case) dials.

dial_1.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
dial_2.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);

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

function enterFrameHandler(event:Event):void {
    r2 = r1;
    t2 = t1;
    var newOffset:Number = Math.atan2(objj.y - this.mouseY, this.mouseX - objj.x);
    
	objj.rotation += (offset - newOffset) * RAD2DEG;
	
    offset = newOffset;
    r1 = objj.rotation;
    t1 = getTimer();
}

function mouseUpHandler(event:MouseEvent):void {
	objj.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
	objj.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
	var time:Number = (getTimer() - t2) / 1000;
	var dif:Number = objj.rotation - r2;
	if (dif != dif % 180) {
		dif +=  (dif < 0) ? 360:-360;
	}
	var rVelocity:Number = dif / time;
	//New line of code below
	ThrowPropsPlugin.to(objj, {throwProps:{rotation:{velocity:rVelocity, resistance:250}}, ease:Strong.easeOut}, 10, 0.25, 2);
}
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.
×