# "javascript convert hsb/hsv color to rgb accurately" Code Answer

2

from parthik gosar's link in this comment with slight modification to let you enter each value independently or all at once as an object

/* accepts parameters
* h  object = {h:x, s:y, v:z}
* or
* h, s, v
*/
function hsvtorgb(h, s, v) {
var r, g, b, i, f, p, q, t;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
i = math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return {
r: math.round(r * 255),
g: math.round(g * 255),
b: math.round(b * 255)
};
}


this code expects 0 <= h, s, v <= 1, if you're using degrees or radians, remember to divide them out.

the returned 0 <= r, g, b <= 255 are rounded to the nearest integer. if you don't want this behaviour remove the math.rounds from the returned object.

and the reverse (with less division)

/* accepts parameters
* r  object = {r:x, g:y, b:z}
* or
* r, g, b
*/
function rgbtohsv(r, g, b) {
if (arguments.length === 1) {
g = r.g, b = r.b, r = r.r;
}
var max = math.max(r, g, b), min = math.min(r, g, b),
d = max - min,
h,
s = (max === 0 ? 0 : d / max),
v = max / 255;

switch (max) {
case min: h = 0; break;
case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
case g: h = (b - r) + d * 2; h /= 6 * d; break;
case b: h = (r - g) + d * 4; h /= 6 * d; break;
}

return {
h: h,
s: s,
v: v
};
}


this code will output 0 <= h, s, v <= 1, but this time takes any 0 <= r, g, b <= 255 (does not need to be an integer)

for completeness,

function hsvtohsl(h, s, v) {
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
var _h = h,
_s = s * v,
_l = (2 - s) * v;
_s /= (_l <= 1) ? _l : 2 - _l;
_l /= 2;

return {
h: _h,
s: _s,
l: _l
};
}

function hsltohsv(h, s, l) {
if (arguments.length === 1) {
s = h.s, l = h.l, h = h.h;
}
var _h = h,
_s,
_v;

l *= 2;
s *= (l <= 1) ? l : 2 - l;
_v = (l + s) / 2;
_s = (2 * s) / (l + s);

return {
h: _h,
s: _s,
v: _v
};
}


all of these values should be in the range 0 to 1. for hsl<->rgb go via hsv.

By Sardar Khan on July 30 2022