Skip to content

Commit ce86248

Browse files
authored
feat: add RGB to HSL color format conversion algorithm (TheAlgorithms#1475)
* feat: add RGB to HSL color format conversion algorithm * test: add self-tests for rgb to hsl conversion algorithm * fix: change function code to concise format * fix: use throw and segregate the test cases * chore: clean up the test format * chore: use correct styling
1 parent ca761d8 commit ce86248

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

Conversions/RgbHslConversion.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Given a color in RGB format, convert it to HSL format.
3+
*
4+
* For more info: https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
5+
*
6+
* @param {number[]} colorRgb - One dimensional array of integers (RGB color format).
7+
* @returns {number[]} - One dimensional array of integers (HSL color format).
8+
*
9+
* @example
10+
* const colorRgb = [24, 98, 118]
11+
*
12+
* const result = rgbToHsl(colorRgb)
13+
*
14+
* // The function returns the corresponding color in HSL format:
15+
* // result = [193, 66, 28]
16+
*/
17+
18+
const checkRgbFormat = (colorRgb) => colorRgb.every((c) => c >= 0 && c <= 255)
19+
20+
const rgbToHsl = (colorRgb) => {
21+
if (!checkRgbFormat(colorRgb)) {
22+
throw new Error('Input is not a valid RGB color.')
23+
}
24+
25+
let colorHsl = colorRgb
26+
27+
let red = Math.round(colorRgb[0])
28+
let green = Math.round(colorRgb[1])
29+
let blue = Math.round(colorRgb[2])
30+
31+
const limit = 255
32+
33+
colorHsl[0] = red / limit
34+
colorHsl[1] = green / limit
35+
colorHsl[2] = blue / limit
36+
37+
let minValue = Math.min(...colorHsl)
38+
let maxValue = Math.max(...colorHsl)
39+
40+
let channel = 0
41+
42+
if (maxValue === colorHsl[1]) {
43+
channel = 1
44+
} else if (maxValue === colorHsl[2]) {
45+
channel = 2
46+
}
47+
48+
let luminance = (minValue + maxValue) / 2
49+
50+
let saturation = 0
51+
52+
if (minValue !== maxValue) {
53+
if (luminance <= 0.5) {
54+
saturation = (maxValue - minValue) / (maxValue + minValue)
55+
} else {
56+
saturation = (maxValue - minValue) / (2 - maxValue - minValue)
57+
}
58+
}
59+
60+
let hue = 0
61+
62+
if (saturation !== 0) {
63+
if (channel === 0) {
64+
hue = (colorHsl[1] - colorHsl[2]) / (maxValue - minValue)
65+
} else if (channel === 1) {
66+
hue = 2 + (colorHsl[2] - colorHsl[0]) / (maxValue - minValue)
67+
} else {
68+
hue = 4 + (colorHsl[0] - colorHsl[1]) / (maxValue - minValue)
69+
}
70+
}
71+
72+
hue *= 60
73+
74+
if (hue < 0) {
75+
hue += 360
76+
}
77+
78+
colorHsl[0] = Math.round(hue)
79+
colorHsl[1] = Math.round(saturation * 100)
80+
colorHsl[2] = Math.round(luminance * 100)
81+
82+
return colorHsl
83+
}
84+
85+
export { rgbToHsl }
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { rgbToHsl } from '../RgbHslConversion'
2+
describe('RgbHslConversion', () => {
3+
test.each([
4+
[
5+
[215, 19, 180],
6+
[311, 84, 46]
7+
],
8+
[
9+
[21, 190, 18],
10+
[119, 83, 41]
11+
],
12+
[
13+
[80, 100, 160],
14+
[225, 33, 47]
15+
],
16+
[
17+
[80, 1, 16],
18+
[349, 98, 16]
19+
],
20+
[
21+
[8, 20, 0],
22+
[96, 100, 4]
23+
],
24+
[
25+
[0, 0, 0],
26+
[0, 0, 0]
27+
],
28+
[
29+
[255, 255, 255],
30+
[0, 0, 100]
31+
]
32+
])('Should return the color in HSL format.', (colorRgb, expected) => {
33+
expect(rgbToHsl(colorRgb)).toEqual(expected)
34+
})
35+
36+
test.each([
37+
[[256, 180, 9], 'Input is not a valid RGB color.'],
38+
[[-90, 46, 8], 'Input is not a valid RGB color.'],
39+
[[1, 39, 900], 'Input is not a valid RGB color.']
40+
])('Should return the error message.', (colorRgb, expected) => {
41+
expect(() => rgbToHsl(colorRgb)).toThrowError(expected)
42+
})
43+
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy