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

# Draggable Rotation - Snap at various degrees

## Recommended Posts

First thanks to Jamie and Jack for answering a similar question. Turns out I was asking the wrong question

What I'm failing to achieve is something very similar to the Draggable Spin demo...

http://www.greensock.com/draggable

My requirement has two differences:

1. I need to snap to a bunch of degrees from an array that are not in even increments. For example [0,  88, 185, 268].
2. I need a callback so I can display information related to the "snapped" degree.

You can think of this as the Wheel of Fortune with uneven distances between each pin.

A few things to note:

I tried supplying an array to the snap option, but once the dial turns more than one rotation, it comes whipping back like it's attached to a rubber band. In addition, I can't use a callback with this technique (I don't think). But the GreenSock Spin demo allows you to spin the dial around and around, and it smoothly lands on a "snap" degree.

Thanks for any help!

##### Share on other sites

This is entirely possible, yes. The behavior you described when passing the array to Draggable's snap is actually quite appropriate - it should snap back once the user spins past the boundary (like if your max value is 268 and they try spinning to 1045 which is several rotations past the max, it should come back) but it sounds like you want to allow folks to have no maximum or minimum, only make sure that they land on a value that's a 360-degree increment of the values in your array. Right?

I don't have time to code all the logic for you right now, but the basic idea would be to:

1. Use the modulus thing I showed you in your other post to force the end value to its corresponding one between 0 and 360.
2. Find the closest value in your array
3. Figure out how many full rotations there are between the original endValue and the new one you just found. For example, if the original endValue is 990, the modulus thing would show that it'll land at 268 from your array, and there are two additional full rotations (720 degrees), so add that back in to the endValue that you return. In this case it'd be 988. Think of it like:
`arrayValue + Math.floor((originalValue - arrayValue) / 360) * 360`

I hope that helps.

##### Share on other sites

Thanks Jack!

I was actually considering doing exactly that but thought I was reinventing the wheel (so to speak) so decided to come back to the forum for ideas.

I'm now comfortable with where to take this and will post back my code once I have a solution.

##### Share on other sites

I finally got this working, but I'm curious...

"snap" appears to fire 3 times when you release the mouse. Is that by design?

Notes: Works just like the Draggable Spin demo, but allows us to use an array of varying degrees. And since it's a function we can easily execute any other code we want.

```var dialarray = [0,14,55,87,133,150,222,299,301,330];
// Snap option inside Draggable.create()
snap:function(originalValue) {
// suppress originalValue to 0-360
var endValue = Math.round(originalValue % 360);
// change negative degree to positive
if(endValue < 0){
endValue = 360 + endValue;
}
// get closest value from array
var arrayValue = parseFloat(closestDeg(endValue, dialarray));
// get extra rotations to add to our arrayValue
var addValue = Math.floor((originalValue - arrayValue) / 360) * 360;
if((endValue-arrayValue+360)%360>180){
}
}

// get nearest degree
function closestDeg(num, arr) {
var ds = arr.map(function( {
var d = Math.abs(num - ;
return d > 180 ? 360 - d : d;
});
return arr[ds.indexOf(Math.min.apply(null, ds))];
};
```

Thanks again Jack for everything!

##### Share on other sites

Great, thanks for sharing. And yes, it is normal for the function to get called several times (it's a long story and has to do with accurately predicting and refining the end value).

##### Share on other sites

• 8 months later...

Hi there I am sort of new to as3 & tweenMax and am wanting some help please.

I have a volumeMC that I want to rotate [ drag ] and snap every 10 degrees, stop @ 360deg @ 0deg & return the value it snapped at.

Steven

##### Share on other sites

Hi scottiescotsman Steven )

if you mean in javascript ; so try this

```Draggable.create("#volume", {
type:"rotation",
bounds:{minRotation:0, maxRotation:360},
liveSnap:true,
snap:function(endValue) { return Math.round( endValue / 10 ) * 10; }
});
```
• 1
##### Share on other sites

Hi Scotty,

You are posting in our HTML5 / JavaScript forum so all the code you see in this thread is not for AS3.

And don't worry, its a common mistake.

So if you need a JavaScript solution for your problem you are definitely in the right place.

However, if you need to do this in Flash, we don't really have an exact product that matches Draggable (as AS3 has a fairly reliable drag API natively).

On our ThrowPropsPlugin page there is a dial demo. can download the demo file from a link in the faq and take a look at the code to see how it was built but the dial itself is only a demo and not a product that we plan to support or build additional features on, its really just a freebie. If you want the dial to to support the physics-based throwing that would require a purchase of Shockingly Green membership as described on that page.

##### Share on other sites

Sorry about the posting in wrong section

Steven