Skip to content

Commit

Permalink
Fix HSL to RGB conversion
Browse files Browse the repository at this point in the history
Adapts the implementation given in https://drafts.csswg.org/css-color/#hsl-to-rgb.

Fixes #142.
  • Loading branch information
trambi authored and domenic committed Dec 28, 2023
1 parent 76b70dc commit 885b232
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
9 changes: 8 additions & 1 deletion lib/parsers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,14 @@ describe('parseColor', () => {

expect(output).toEqual('rgba(5, 5, 5, 0.5)');
});

it.each([
[120, 'rgb(0, 255, 0)'],
[240, 'rgb(0, 0, 255)'],
])('should convert not zero hsl with non zero hue %s to %s', (hue, rgbValue) => {
let input = 'hsl(' + hue + ', 100%, 50%)';
let output = parsers.parseColor(input);
expect(output).toEqual(rgbValue);
});
it.todo('Add more tests');
});
describe('parseAngle', () => {
Expand Down
28 changes: 13 additions & 15 deletions lib/utils/colorSpace.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
'use strict';

const hueToRgb = (t1, t2, hue) => {
if (hue < 0) hue += 6;
if (hue >= 6) hue -= 6;

if (hue < 1) return (t2 - t1) * hue + t1;
else if (hue < 3) return t2;
else if (hue < 4) return (t2 - t1) * (4 - hue) + t1;
else return t1;
};
const MAX_HUE = 360;
const COLOR_NB = 12;
const MAX_RGB_VALUE = 255;

// https://www.w3.org/TR/css-color-4/#hsl-to-rgb
exports.hslToRgb = (hue, sat, light) => {
const t2 = light <= 0.5 ? light * (sat + 1) : light + sat - light * sat;
const t1 = light * 2 - t2;
const r = hueToRgb(t1, t2, hue + 2);
const g = hueToRgb(t1, t2, hue);
const b = hueToRgb(t1, t2, hue - 2);
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
hue = hue % MAX_HUE;
if (hue < 0) {
hue += MAX_HUE;
}
function f(n) {
const k = (n + hue / (MAX_HUE / COLOR_NB)) % COLOR_NB;
const a = sat * Math.min(light, 1 - light);
return light - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
}
return [f(0), f(8), f(4)].map((value) => Math.round(value * MAX_RGB_VALUE));
};

0 comments on commit 885b232

Please sign in to comment.