I have been busy completing business needs recently and haven't written a blog for a long time. I have a little time today and looked at some of the front-end codes in recent projects. When I saw the web color conversion function, I suddenly thought that when we were doing some color settings/editing requirements, it often involved interchange of various color value formats. So I decided to record how I implemented this part of the function, write it down and share it with you, and hope that readers will express their opinions and communicate more.
Look at the problem first
Question 1. When we are developing the front-end web page, we often use dom.style.backgroundColor = "#f00" to set the background color of a DOM element. We will also use the code similar (why is the same? There are many cases, so we can freely use our imagination here) var bgc = dom.style.backgroundColor to get the background color of a DOM element. So the question is, please see the picture below:
If the comparison here is not obvious enough, let's continue to look:
Obviously, the same color value should be equal, but the result is not. This is not an isolated case. The results I get in Chrome development tools and Firefox console are the same.
Question 2: Front-end development often starts with restoring the UI design draft. During the encoding process, we often find such a design: a box background solid color (assuming: #f00), but with 75% opacity. Obviously, we cannot simply set this situation through dom.style.backgroundColor = "#f00" because the translucent effect cannot be achieved. As we turn around, we know that there is an rgba thing in CSS3, which means we can set a translucent background color through dom.style.backgroundColor = "rgba(255, 0, 0, 0.75)" in this way. Then, the question is again: this conversion is easy to do in Photoshop, but if we are in Javascript, how should we convert ("#f00", 75) to rgba(255, 0, 0, 0.75)?
Next, let’s see how I do it.
rgb(a) color value converted to hex color (hex)
They are all for development, we understand! It’s better to just upload the code directly, but here’s a piece of the original one:
<!-- lang: js -->
The code copy is as follows:
var rgbToHex = function(rgb) {
var rRgb = /rgb/((/d{1,3}),(/d{1,3}),(/d{1,3})/)/,
rRgba = /rgba/((/d{1,3}),(/d{1,3}),(/d{1,3}),([./d]+)/)/,
r, g, b, a, rs = rgb.replace(//s+/g, "").match(rRgb),
rsa = rgb.replace(//s+/g, "").match(rRgba);
if (rs) {
r = (+rs[1]).toString(16);
r = r.length == 1 ? "0" + r : r;
g = (+rs[2]).toString(16);
g = g.length == 1 ? "0" + g : g;
b = (+rs[3]).toString(16);
b = b.length == 1 ? "0" + b : b;
return {hex: "#" + r + g + b, alpha: 100};
} else if (rsa) {
r = (+rsa[1]).toString(16);
r = r.length == 1 ? "0" + r : r;
g = (+rsa[2]).toString(16);
g = g.length == 1 ? "0" + g : g;
b = (+rsa[3]).toString(16);
b = b.length == 1 ? "0" + b : b;
a = (+rsa[4]) * 100
return {hex: "#" + r + g + b, alpha: Math.ceil(a)};
} else {
return {hex: rgb, alpha: 100};
}
};
Why is it the most primitive? Because when I review the code today, I found that there is still room for evolution here. Let’s compare the evolved (optimized) code:
<!-- lang: js -->
The code copy is as follows:
var rgbToHex = function(rgb) {
var rRgba = /rgba?/((/d{1,3}),(/d{1,3}),(/d{1,3})(,([./d]+))?/)/,
r, g, b, a
rsa = rgb.replace(//s+/g, "").match(rRgba);
if (rsa) {
r = (+rsa[1]).toString(16);
r = r.length == 1 ? "0" + r : r;
g = (+rsa[2]).toString(16);
g = g.length == 1 ? "0" + g : g;
b = (+rsa[3]).toString(16);
b = b.length == 1 ? "0" + b : b;
a = (+(rsa[5] ? rsa[5] : 1)) * 100
return {hex: "#" + r + g + b, alpha: Math.ceil(a)};
} else {
return {hex: rgb, alpha: 100};
}
};
Not to mention that there is one if branch missing, it is obvious from the perspective of code volume alone! Next, let's see if the conversion result is as we wish, and for this I executed a few lines of code shown in the following figure in the console:
Judging from the execution results, our method seems to have achieved our goal. However, careful friends should notice that there are two red arrows in the picture. Is there any pitfalls here? good. Let's take a closer look at the color parameter rgb(255, 0, 0, 2) passed in the first arrow. In fact, this is not a legal color value. The color value in the rgb format does not have the fourth (transparency) parameter; then look at the second arrow rgba(255, 0, 0, 1.48) in the second arrow. There is no problem with the format here, but the transparency is 1.48, which is actually not a legal transparency value. Our method has been executed normally and returned normally, indicating that our method still has room for further evolution, so we will leave it to everyone to perform!
Convert hex color (hex) to rgba format
In daily development, the color value we use most often should be the color value in hexadecimal format (#ff0000, #f00, etc.). If we need to convert it to rgba format when using color values, what should we do?
<!-- lang: js -->
The code copy is as follows:
var hexToRgba = function(hex, al) {
var hexColor = /^#/.test(hex) ? hex.slice(1): hex,
alp = hex === 'transparent' ? 0 : Math.ceil(al),
r, g, b;
hexColor = /^[0-9a-f]{3}|[0-9a-f]{6}$/i.test(hexColor) ? hexColor : 'ffffff';
if (hexColor.length === 3) {
hexColor = hexColor.replace(/(/w)(/w)(/w)/gi, '$1$1$2$2$3$3');
}
r = hexColor.slice(0, 2);
g = hexColor.slice(2, 4);
b = hexColor.slice(4, 6);
r = parseInt(r, 16);
g = parseInt(g, 16);
b = parseInt(b, 16);
return {
hex: '#' + hexColor,
alpha: alp,
rgba: 'rgba(' + r + ', ' + g + ', ' + b + ', ' + (alp / 100).toFixed(2) + ')'
};
};
Similarly, we also write a verification code to test whether our conversion is normal:
Judging from the execution results, our method has no problem and can get the conversion results we want. But here we still leave two red arrows, illegal transparency and illegal color values. This part of the evolutionary function is also left for everyone, haha...
Finally, the mutual conversion between web page color values is actually a cliché issue. I have just listed one of them here. I believe there are more and better methods to use. Everyone is welcome to propose it, communicate and make progress together~~