JavaScript 作 ▸ 2018-12-06 12:23 JavaScriptでRGB⇔HSL変換 #JavaScript ゲーム作ってたときに使ってたものです。計算方法は、全面的に次のサイト様を参考にさせていただきました。 RGBとHSLの相互変換ツールと変換計算式 - PEKO STEP 小数の精度の都合上、完全な双方向の変換はできない場合があります。 RGBは 0 ~ 255, 色相は 0 ~ 360, 彩度と明度は 0 ~ 100 の範囲を想定してます。 結果は小数にもなります。スタイルに使う場合は丸めてください。 RGB -> HSL/** * RGBからHSLを算出して返却 * @param {Number} r - 赤 (0~255) * @param {Number} g - 緑 (0~255) * @param {Number} b - 青 (0~255) * @return {Object} h: 色相 (0~360), s: 彩度 (0~100), l: 明度 (0~100) */ const rgb2hsl = function(r, g, b) { const RGB_MAX = 255; const HUE_MAX = 360; const SATURATION_MAX = 100; const LIGHTNESS_MAX = 100; const max = Math.max(r, g, b); const min = Math.min(r, g, b); let h, s, l; // Hue const hp = HUE_MAX / 6; if (max == min) { h = 0; } else if (r == max) { h = hp * ((g - b) / (max - min)); } else if (g == max) { h = hp * ((b - r) / (max - min)) + HUE_MAX / 3; } else { h = hp * ((r - g) / (max - min)) + HUE_MAX * 2 / 3; } if (h < 0) { h += HUE_MAX; } // Saturation const cnt = (max + min) / 2; if (cnt < RGB_MAX / 2) { if (max + min <= 0) { s = 0; } else { s = (max - min) / (max + min) * SATURATION_MAX; } } else { s = (max - min) / (RGB_MAX * 2 - max - min) * SATURATION_MAX; } // Lightness l = (max + min) / RGB_MAX / 2 * LIGHTNESS_MAX; return { h: h, s: s, l: l }; };HSL -> RGB/** * HSLからRGBを算出して返却 * @param {Number} h - 色相 (0~360) * @param {Number} s - 彩度 (0~100) * @param {Number} l - 明度 (0~100) * @return {Object} r: 赤 (0~255), g: 緑 (0~255), b: 青 (0~255) */ const hsl2rgb = function(h, s, l) { const RGB_MAX = 255; const HUE_MAX = 360; const SATURATION_MAX = 100; const LIGHTNESS_MAX = 100; let r, g, b, max, min; h = h % HUE_MAX; s = s / SATURATION_MAX; l = l / LIGHTNESS_MAX; if (l < 0.5) { max = l + l * s; min = l - l * s; } else { max = l + (1 - l) * s; min = l - (1 - l) * s; } const hp = HUE_MAX / 6; const q = h / hp; if (q <= 1) { r = max; g = (h / hp) * (max - min) + min; b = min; } else if (q <= 2) { r = ((hp * 2 - h) / hp) * (max - min) + min; g = max; b = min; } else if (q <= 3) { r = min; g = max; b = ((h - hp * 2) / hp) * (max - min) + min; } else if (q <= 4) { r = min; g = ((hp * 4 - h) / hp) * (max - min) + min; b = max; } else if (q <= 5) { r = ((h - hp * 4) / hp) * (max - min) + min; g = min; b = max; } else { r = max; g = min; b = ((HUE_MAX - h) / hp) * (max - min) + min; } return { r: r * RGB_MAX, g: g * RGB_MAX, b: b * RGB_MAX }; };テストケースRGB -> HSLconsole.log(rgb2hsl( 255, 0, 0)); // -> h: 0, s: 100, l: 50 console.log(rgb2hsl( 255, 127.5, 0)); // -> h: 30, s: 100, l: 50 console.log(rgb2hsl( 255, 255, 0)); // -> h: 60, s: 100, l: 50 console.log(rgb2hsl(127.5, 255, 0)); // -> h: 90, s: 100, l: 50 console.log(rgb2hsl( 0, 255, 0)); // -> h: 120, s: 100, l: 50 console.log(rgb2hsl( 0, 255, 127.5)); // -> h: 150, s: 100, l: 50 console.log(rgb2hsl( 0, 255, 255)); // -> h: 180, s: 100, l: 50 console.log(rgb2hsl( 0, 127.5, 255)); // -> h: 210, s: 100, l: 50 console.log(rgb2hsl( 0, 0, 255)); // -> h: 240, s: 100, l: 50 console.log(rgb2hsl(127.5, 0, 255)); // -> h: 270, s: 100, l: 50 console.log(rgb2hsl( 255, 0, 255)); // -> h: 300, s: 100, l: 50 console.log(rgb2hsl( 255, 0, 127.5)); // -> h: 330, s: 100, l: 50 console.log(rgb2hsl( 0, 0, 0)); // -> h: 0, s: 0, l: 0 console.log(rgb2hsl( 51, 51, 51)); // -> h: 0, s: 0, l: 20 console.log(rgb2hsl(127.5, 127.5, 127.5)); // -> h: 0, s: 0, l: 50 console.log(rgb2hsl( 255, 255, 255)); // -> h: 0, s: 0, l: 100 console.log(rgb2hsl( 51, 0, 0)); // -> h: 0, s: 100, l: 10 console.log(rgb2hsl( 102, 0, 0)); // -> h: 0, s: 100, l: 20 console.log(rgb2hsl( 153, 0, 0)); // -> h: 0, s: 100, l: 30 console.log(rgb2hsl( 204, 0, 0)); // -> h: 0, s: 100, l: 40 console.log(rgb2hsl( 153, 102, 102)); // -> h: 0, s: 20, l: 50 console.log(rgb2hsl(178.5, 76.5, 76.5)); // -> h: 0, s: 40, l: 50 console.log(rgb2hsl( 204, 51, 51)); // -> h: 0, s: 60, l: 50 console.log(rgb2hsl(229.5, 25.5, 25.5)); // -> h: 0, s: 80, l: 50HSL -> RGBconsole.log(hsl2rgb( 0, 100, 50 )); // -> r: 255, g: 0, b: 0 console.log(hsl2rgb( 30, 100, 50 )); // -> r: 255, g: 127.5, b: 0 console.log(hsl2rgb( 60, 100, 50 )); // -> r: 255, g: 255, b: 0 console.log(hsl2rgb( 90, 100, 50 )); // -> r: 127.5, g: 255, b: 0 console.log(hsl2rgb( 120, 100, 50 )); // -> r: 0, g: 255, b: 0 console.log(hsl2rgb( 150, 100, 50 )); // -> r: 0, g: 255, b: 127.5 console.log(hsl2rgb( 180, 100, 50 )); // -> r: 0, g: 255, b: 255 console.log(hsl2rgb( 210, 100, 50 )); // -> r: 0, g: 127.5, b: 255 console.log(hsl2rgb( 240, 100, 50 )); // -> r: 0, g: 0, b: 255 console.log(hsl2rgb( 270, 100, 50 )); // -> r: 127.5, g: 0, b: 255 console.log(hsl2rgb( 300, 100, 50 )); // -> r: 255, g: 0, b: 255 console.log(hsl2rgb( 330, 100, 50 )); // -> r: 255, g: 0, b: 127.5 console.log(hsl2rgb( 360, 100, 50 )); // -> r: 255, g: 0, b: 0 console.log(hsl2rgb( 390, 100, 50 )); // -> r: 255, g: 127.5, b: 0 console.log(hsl2rgb( 99, 0, 0 )); // -> r: 0, g: 0, b: 0 console.log(hsl2rgb( 99, 0, 20 )); // -> r: 51, g: 51, b: 51 console.log(hsl2rgb( 99, 0, 50 )); // -> r: 127.5, g: 127.5, b: 127.5 console.log(hsl2rgb( 99, 0, 100 )); // -> r: 255, g: 255, b: 255 console.log(hsl2rgb( 0, 100, 10 )); // -> r: 51, g: 0, b: 0 console.log(hsl2rgb( 0, 100, 20 )); // -> r: 102, g: 0, b: 0 console.log(hsl2rgb( 0, 100, 30 )); // -> r: 153, g: 0, b: 0 console.log(hsl2rgb( 0, 100, 40 )); // -> r: 204, g: 0, b: 0 console.log(hsl2rgb( 0, 20, 50 )); // -> r: 153, g: 102, b: 102 console.log(hsl2rgb( 0, 40, 50 )); // -> r: 178.5, g: 76.5, b: 76.5 console.log(hsl2rgb( 0, 60, 50 )); // -> r: 204, g: 51, b: 51 console.log(hsl2rgb( 0, 80, 50 )); // -> r: 229.5, g: 25.499999999999993, b: 25.499999999999993 console.log(hsl2rgb( 60, 100, 10 )); // -> r: 51, g: 51, b: 0 console.log(hsl2rgb( 60, 100, 20 )); // -> r: 102, g: 102, b: 0 console.log(hsl2rgb( 60, 100, 30 )); // -> r: 153, g: 153, b: 0 console.log(hsl2rgb( 60, 100, 40 )); // -> r: 204, g: 204, b: 0 console.log(hsl2rgb( 120, 100, 10 )); // -> r: 0, g: 51, b: 0 console.log(hsl2rgb( 120, 100, 20 )); // -> r: 0, g: 102, b: 0 console.log(hsl2rgb( 120, 100, 30 )); // -> r: 0, g: 153, b: 0 console.log(hsl2rgb( 120, 100, 40 )); // -> r: 0, g: 204, b: 0 console.log(hsl2rgb( 180, 100, 10 )); // -> r: 0, g: 51, b: 51 console.log(hsl2rgb( 180, 100, 20 )); // -> r: 0, g: 102, b: 102 console.log(hsl2rgb( 180, 100, 30 )); // -> r: 0, g: 153, b: 153 console.log(hsl2rgb( 180, 100, 40 )); // -> r: 0, g: 204, b: 204 console.log(hsl2rgb( 240, 100, 10 )); // -> r: 0, g: 0, b: 51 console.log(hsl2rgb( 240, 100, 20 )); // -> r: 0, g: 0, b: 102 console.log(hsl2rgb( 240, 100, 30 )); // -> r: 0, g: 0, b: 153 console.log(hsl2rgb( 240, 100, 40 )); // -> r: 0, g: 0, b: 204 console.log(hsl2rgb( 300, 100, 10 )); // -> r: 51, g: 0, b: 51 console.log(hsl2rgb( 300, 100, 20 )); // -> r: 102, g: 0, b: 102 console.log(hsl2rgb( 300, 100, 30 )); // -> r: 153, g: 0, b: 153 console.log(hsl2rgb( 300, 100, 40 )); // -> r: 204, g: 0, b: 204