Skip to content

Commit 0993484

Browse files
committed
Fix color conversion bugs
1 parent 6a8cd62 commit 0993484

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

src/p4/color-utils.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const hexToRgb = (hex) => {
2020
};
2121

2222
export const rgbToHex = (r, g, b) => {
23-
return '#' + Math.round(r).toString(16).padStart(2, '0') + Math.round(b).toString(16).padStart(2, '0') + Math.round(g).toString(16).padStart(2, '0');
23+
return '#' + Math.round(r).toString(16).padStart(2, '0') + Math.round(g).toString(16).padStart(2, '0') + Math.round(b).toString(16).padStart(2, '0');
2424
};
2525

2626
export const rgbToHsv = (r, g, b) => {
@@ -33,9 +33,8 @@ export const rgbToHsv = (r, g, b) => {
3333
s = max == 0 ? 0 : d / max;
3434
if (max == min) {
3535
h = 0;
36-
if (min === 0 || min === 1) {
37-
// Saturation does not matter in the case of pure white or black
38-
// In these cases we'll set saturation 1 to provide a better editing experience
36+
if (min === 0) {
37+
// Saturation does not matter in the case of pure black, so just set it to 1 instead so the editor makes more sense
3938
s = 1;
4039
}
4140
} else {

test/p4/color-utils.test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,40 @@ test('rgbToHex', () => {
1414
expect(rgbToHex(0, 0, 0)).toEqual('#000000');
1515
expect(rgbToHex(255, 255, 255)).toEqual('#ffffff');
1616
expect(rgbToHex(255, 0, 0)).toEqual('#ff0000');
17+
expect(rgbToHex(0, 255, 0)).toEqual('#00ff00');
18+
expect(rgbToHex(0, 0, 255)).toEqual('#0000ff');
19+
expect(rgbToHex(0xab, 0xcd, 0x12)).toEqual('#abcd12');
20+
expect(rgbToHex(1, 2, 255)).toEqual('#0102ff');
1721
});
1822

1923
test('rgbToHsv', () => {
2024
expect(rgbToHsv(0, 0, 0)[0]).toEqual(0);
25+
// (saturation does not matter in pure black)
2126
expect(rgbToHsv(0, 0, 0)[2]).toEqual(0);
27+
expect(rgbToHsv(255, 255, 255)).toEqual([0, 0, 1]);
2228
expect(rgbToHsv(255, 0, 0)).toEqual([0, 1, 1]);
2329
});
2430

2531
test('hsvToRgb', () => {
2632
expect(hsvToRgb(0, 0, 0)).toEqual([0, 0, 0]);
2733
});
34+
35+
test('round-trip accuracy', () => {
36+
for (const color of [
37+
'#4c5aff',
38+
'5a4cff',
39+
'000000',
40+
'ffffff',
41+
'abcdef',
42+
'123456',
43+
'002348',
44+
'acbd38'
45+
]) {
46+
const rgb = hexToRgb(color);
47+
const hsv = rgbToHsv(...rgb);
48+
const rgb2 = hsvToRgb(...hsv);
49+
expect(Math.abs(rgb2[0] - rgb[0])).toBeLessThan(0.0001);
50+
expect(Math.abs(rgb2[1] - rgb[1])).toBeLessThan(0.0001);
51+
expect(Math.abs(rgb2[2] - rgb[2])).toBeLessThan(0.0001);
52+
}
53+
});

0 commit comments

Comments
 (0)