먼저, "#ffffff" 16진수 표현을 RGB로 변환하 기
/**
* @param {string} hexColor #ffffff 와 같이 16진수 형태로 작성된 색상 문자열
* @returns {[number, number, number]} R, G, B 배열 (0 ~ 255)
*/
function hexColorToRGB(hexColor) {
const rgb = hexColor.startsWith('#') ? hexColor.slice(1) : hexColor;
const [r, g, b] = [rgb.slice(0, 2), rgb.slice(2, 4), rgb.slice(4, 6)].map((hex) => Number.parseInt(hex, 16));
return [r, g, b];
}
"#ffffff"
같은 식의 16진수로 표현된 색상 문자열을 R, G, B 배열로 변환합니다.
RGB를 HSL로 변환하기
/**
* 출처: https://www.30secondsofcode.org/js/s/rgb-to-hsl/
*
* @param {[number, number, number]} rgb R, G, B 값 배열
* @returns {[number, number, number]} H, S, L 값 배열
*/
function rgbToHSL(rgb) {
const r = rgb[0] / 255;
const g = rgb[1] / 255;
const b = rgb[2] / 255;
const l = Math.max(r, g, b);
const s = l - Math.min(r, g, b);
const h = s
? l === r
? (g - b) / s
: l === g
? 2 + (b - r) / s
: 4 + (r - g) / s
: 0;
return [
60 * h < 0 ? 60 * h + 360 : 60 * h,
100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
(100 * (2 * l - s)) / 2,
];
}
소스코드의 출처는 https://www.30secondsofcode.org/js/s/rgb-to-hsl/ 입니다.
RGB 배열을 HSL 배열로 변환합니다. 잘 동작하는 것을 확인할 수 있습니다.
HSL을 RGB로 변환하기
/**
* 출처: https://www.30secondsofcode.org/js/s/hsl-to-rgb/
*
* @param {[number, number, number]} hsl H, S, L 값 배열
* @returns {[number, number, number]} R, G, B 값 배열
*/
function hslToRGB(hsl) {
const h = hsl[0];
const s = hsl[1] / 100;
const l = hsl[2] / 100;
const k = (n) => (n + h / 30) % 12;
const a = s * Math.min(l, 1 - l);
const f = (n) =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
return [255 * f(0), 255 * f(8), 255 * f(4)];
}
소스코드의 출처는 https://www.30secondsofcode.org/js/s/hsl-to-rgb/ 입니다.
다시 RGB를 HSL로 변환합니다. 변환이 문제없는 것을 잘 검증할 수 있었습니다.
HSL을 문자열로
브라우저에서 HSL 문자열을 나타내는 방법은 간단합니다.
/**
* @param {[number, number, number]} hsl H, S, L 값 배열
* @returns {string} hsl(h, s%, l%) 로 표현된 문자열
*/
function stringifyHSL(hsl) {
const [h, s, l] = hsl;
return `hsl(${h}, ${s}%, ${l}%)`;
}
HSL 값 정규화하기
/**
* @param {[number, number, number]} hsl H, S, L 값 배열
* @returns {[number, number, number]} 정규화된 H, S, L 값 배열
*/
function normalizeHSL(hsl) {
const [h, s, l] = hsl;
return [
((Math.round(h) % 360) + 360) % 360, // 0 ~ 360, positive modulo
Math.max(0, Math.min(100, Math.round(s))), // 0 ~ 100
Math.max(0, Math.min(100, Math.round(l))), // 0 ~ 100
];
}
hsl 배열의 값이 항상 아래와 같이 나오도록 해주는 함수를 만듭니다.
- H: 0 ≤ H < 360
- S: 0 ≤ S ≤ 100
- L: 0 ≤ L ≤ 100
브라우저에서 사용
index.html
<body>
<div class="color-form">
<p id="color-name"></p>
<div class="color"></div>
</div>
</body>
<script>
function setColor(color) {
document.getElementById('color-name').innerText = color;
document.getElementById('color-name').style.color = color;
document.querySelector('.color').style.backgroundColor = color;
}
setColor([
hexColorToRGB,
rgbToHSL,
normalizeHSL,
stringifyHSL,
].reduce((acc, pipe) => pipe(acc), '#ecb127'));
</script>