-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
index.js
73 lines (59 loc) · 1.92 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// TODO: Remove this ignore comment.
// eslint-disable-next-line no-mixed-operators
const toHex = (red, green, blue, alpha) => ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1) + alpha;
export default function rgbHex(red, green, blue, alpha) {
let isPercent = (red + (alpha || '')).toString().includes('%');
if (typeof red === 'string' && !green) { // Single string parameter.
const parsed = parseCssRgbString(red);
if (!parsed) {
throw new TypeError('Invalid or unsupported color format.');
}
isPercent = false;
[red, green, blue, alpha] = parsed;
} else if (alpha !== undefined) {
alpha = Number.parseFloat(alpha);
}
if (typeof red !== 'number' ||
typeof green !== 'number' ||
typeof blue !== 'number' ||
red > 255 ||
green > 255 ||
blue > 255
) {
throw new TypeError('Expected three numbers below 256');
}
if (typeof alpha === 'number') {
if (!isPercent && alpha >= 0 && alpha <= 1) {
alpha = Math.round(255 * alpha);
} else if (isPercent && alpha >= 0 && alpha <= 100) {
alpha = Math.round(255 * alpha / 100);
} else {
throw new TypeError(`Expected alpha value (${alpha}) as a fraction or percentage`);
}
alpha = (alpha | 1 << 8).toString(16).slice(1); // eslint-disable-line no-mixed-operators
} else {
alpha = '';
}
return toHex(red, green, blue, alpha);
}
const parseCssRgbString = input => {
const parts = input.replace(/rgba?\(([^)]+)\)/, '$1').split(/[,\s/]+/).filter(Boolean);
if (parts.length < 3) {
return;
}
const parseValue = (value, max) => {
value = value.trim();
if (value.endsWith('%')) {
return Math.min(Number.parseFloat(value) * max / 100, max);
}
return Math.min(Number.parseFloat(value), max);
};
const red = parseValue(parts[0], 255);
const green = parseValue(parts[1], 255);
const blue = parseValue(parts[2], 255);
let alpha;
if (parts.length === 4) {
alpha = parseValue(parts[3], 1);
}
return [red, green, blue, alpha];
};