Jump to content
GreenSock

Joe Hakooz

Draggable Snap - Getting endValue between 0 - 360

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

This is just a math question that I'm struggling to answer...

 

I'm using the Draggable with type: 'rotation'. And I want it to "snap" to degrees I'm providing via an array. 

The example snap code looks like this:

var rotationSnap = 90;
snap:function(endValue) { 
    return Math.round(endValue / rotationSnap) * rotationSnap;
}

Since my "rotationSnap" variable could be any number between 0-360, how can I calculate the return value to always be between 0 and 360?,Specifically when the endValue is negative or higher than 360.

 

Example Issue:

Let's say my array contains the values 0, 90, 180, and 270. The problem is that a negative endValue always returns 0 from my array. And an endValue higher than 360 always returns 270 from my array. 

 

Extra Info: I have a function that compares endValue to my array and returns the closest number. 

 

Thanks for any info and please let me know if I need to clarify.

Link to comment
Share on other sites

So you want it to snap to 90 degree increments, and also constrained to 0 <= x < 360 ? There's plenty of ways to calculate that, here's one way (could be optimised, but its only going to loop once or twice anyway, so I'll skip it for now; please forgive me):

var rotationSnap = 90;
var snap = function(endValue) {
  endValue = Math.round(endValue / rotationSnap) * rotationSnap;
  while (endValue >= 360) endValue -= 360;
  while (endValue < 0) endValue += 360;
  return endValue;
};
Link to comment
Share on other sites

Thank you for the fast response!

My situation is a little different and I realize now I could ask it a much simpler way, and should probably do so in a math forum...

 

I guess what I'm asking is...

For a "rotation" draggable, the "snap" function passes the variable "endValue" which can be any number negative or positive.

How do I take "endValue" and convert it to a number between 0 and 360?

 

Thanks again for your help!

 

PS... I believe your solution would only work if the negative or positive endValue was between -360 and 720. endValue could be outside of those bounds. And I'm pretty sure there is some strange built-in math function that is designed for this very situation. I really should have payed more attention in math class!

Link to comment
Share on other sites

Umm, what I posted does exactly that... it treated 360 as 0, but you can fix that by deleting one character.

// convert endValue to an increment of rotationSnap in the range
// 0 <= x < 360
var snap = function(endValue) {

  // snap endValue to an increment of rotationSnap i.e. a multiple of 90
  endValue = Math.round(endValue / rotationSnap) * rotationSnap;
  // at this point endValue could still be greater than 360 or
  // less than 0

  // if endValue is >= 360, reduce it until it's within 0 <= x < 360
  // to use the range 0 <= x <= 360, remove the equal sign from
  // this while comparison
  while (endValue >= 360) endValue -= 360;

  // if endValue is < 0, increase it until it's within 0 <= x < 360
  while (endValue < 0) endValue += 360;

  // return the adjusted endValue.
  // min value will be 0, and max value will be 359.999999999....
  return endValue;

};

Edit: looks like you added a PS in there. It will definitely work for ANY value, since it uses while loops, not just a single if e.g. the line

while (endValue >= 360) endValue -= 360;

won't stop reducing endValue until it is less than 360. I guarantee it ;)

  • Like 1
Link to comment
Share on other sites

You could also just use the modulus operator which is faster than doing a loop:

var rotationSnap = 90;
var snap = function(endValue) {
  endValue = (Math.round(endValue / rotationSnap) * rotationSnap) % 360;
  return (endValue < 0) ? endValue + 360 : endValue;
};
  • Like 4
Link to comment
Share on other sites

Of course it is. I knew I was forgetting something that smart people know...

  • Like 1
Link to comment
Share on other sites

Thanks Jamie. You are smarter than me... I totally missed the fact that the loop would catch any value. 

 

And thank you Jack for dropping the magic modulus operator on me!

  • Like 1
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.
×