bgrins / TinyColor

Fast, small color manipulation and conversion for JavaScript
https://bgrins.github.io/TinyColor/
MIT License
5.06k stars 438 forks source link

Negative Value for HUE #12

Open VladimirCores opened 11 years ago

VladimirCores commented 11 years ago

I find your library useful thanks you. But for my purposes there is a one little bug with negative hue value, please fix them it's line 784: var m1 = Number(match[1]); return { h: ( m1 > 0 ? (m1 > 360 ? m1 - 360 : m1 ) : 360 + m1 ), s: match[2], l: match[3] };

Best Regards, Vladimir Minkin

bgrins commented 11 years ago

Vladimir, Thanks for tracking this down. Can you explain what input is failing for you, and what the expected behavior is so we can make sure it is fixed? I want to make sure that we can spec out what should happen with negative values so we can add it to the test suite.

timothyausten commented 8 years ago

Same thing here. Since color is measured on a circular scale, any increases or decreases in the value should just keep on going around the circle instead of going out-of-range.

For example, tinycolor.js should normalize an out-of-range value of 361 as just 1. Conversely, it should change -1 into 359. A very high number such as 721 should be just 1. My version is similar to Vladimir's, except it allows input values beyond 360. Fiddle.

return { h: ( m1 < 0 ? m1 % 360 + 360 : m1 % 360 ), s: match[2], l: match[3] };

P.S. I have been getting some mileage out of this library, and I love it. :)

bgrins commented 8 years ago

Yes I think this is what CSS colors are doing: http://jsfiddle.net/dd1t8zvq/. From http://www.w3.org/TR/css3-color/#hsl-color: "As an angle, it implicitly wraps around such that -120=240 and 480=120".

@timothyausten would you be able create a pull request with your change and a small test case?

timothyausten commented 8 years ago

Pull request created.

yukulele commented 8 years ago

According to this article https://en.wikipedia.org/wiki/Modulo_operation#Remainder_calculation_for_the_modulo_operation you can use floored division function:

modulo(x,y){
  return x - y * Math.floor(x / y)
}
tinycolor(h: modulo(hue, 360), s: 100, l: 50)