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 Dec 28, 2023
1 parent 76b70dc commit d69091c
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)']])(

Check warning on line 110 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Replace `[120,·'rgb(0,·255,·0)'],·[240,·'rgb(0,·0,·255)']])(` with `⏎····[120,·'rgb(0,·255,·0)'],⏎····[240,·'rgb(0,·0,·255)'],`

Check warning on line 110 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Replace `[120,·'rgb(0,·255,·0)'],·[240,·'rgb(0,·0,·255)']])(` with `⏎····[120,·'rgb(0,·255,·0)'],⏎····[240,·'rgb(0,·0,·255)'],`

Check warning on line 110 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Replace `[120,·'rgb(0,·255,·0)'],·[240,·'rgb(0,·0,·255)']])(` with `⏎····[120,·'rgb(0,·255,·0)'],⏎····[240,·'rgb(0,·0,·255)'],`
'should convert not zero hsl with non zero hue %s to %s',

Check warning on line 111 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Replace `··'should·convert·not·zero·hsl·with·non·zero·hue·%s·to·%s',⏎···` with `])('should·convert·not·zero·hsl·with·non·zero·hue·%s·to·%s',`

Check warning on line 111 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Replace `··'should·convert·not·zero·hsl·with·non·zero·hue·%s·to·%s',⏎···` with `])('should·convert·not·zero·hsl·with·non·zero·hue·%s·to·%s',`

Check warning on line 111 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Replace `··'should·convert·not·zero·hsl·with·non·zero·hue·%s·to·%s',⏎···` with `])('should·convert·not·zero·hsl·with·non·zero·hue·%s·to·%s',`
(hue, rgbValue) => {
let input = 'hsl(' + hue + ', 100%, 50%)';

Check warning on line 113 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Delete `··`

Check warning on line 113 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Delete `··`

Check warning on line 113 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Delete `··`
let output = parsers.parseColor(input);

Check warning on line 114 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Replace `······` with `····`

Check warning on line 114 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Replace `······` with `····`

Check warning on line 114 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Replace `······` with `····`
expect(output).toEqual(rgbValue);

Check warning on line 115 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Delete `··`

Check warning on line 115 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Delete `··`

Check warning on line 115 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Delete `··`
}

Check warning on line 116 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Replace `····}⏎··` with `··}`

Check warning on line 116 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Replace `····}⏎··` with `··}`

Check warning on line 116 in lib/parsers.test.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Replace `····}⏎··` with `··}`
);
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));

Check warning on line 18 in lib/utils/colorSpace.js

View workflow job for this annotation

GitHub Actions / Lint and tests (18)

Replace `value` with `(value)`

Check warning on line 18 in lib/utils/colorSpace.js

View workflow job for this annotation

GitHub Actions / Lint and tests (20)

Replace `value` with `(value)`

Check warning on line 18 in lib/utils/colorSpace.js

View workflow job for this annotation

GitHub Actions / Lint and tests (latest)

Replace `value` with `(value)`
};

0 comments on commit d69091c

Please sign in to comment.