基于Vue的颜色选择器
基于Vue的颜色选择器(一)
基于Vue的颜色选择器(二)
文章目录
- 基于Vue的颜色选择器
- 前言
- 一、颜色初了解
- 二、颜色格式
- 三、格式之间的转换
- 1.RGB转换HEX(即十六进制)
- 2.HEX转换RGB
- 3.RGB转换HSB/HSV
- 4.RGB转换HSL
- 5.HSB/HSV转换HSL
- 6.HSL转换HSB/HSV
- 四、验证输入的颜色值格式,并将输入的颜色值统一转换成HEX颜色值
前言
基于Vue的颜色选择器(一)
—— 各种颜色格式之间的转换
一、颜色初了解
作为一个没有学过美术同时对色彩不太敏感的前端开发,在开发UI组件库的时候,避免不了需要面对颜色选择器组件。 这里推荐几篇我看过的博客
- 色彩空间中的 HSL、HSV、HSB 有什么区别?
- RGB、HSB/HSV、HSL三种颜色空间的原理理解与转换
- 如何实现一个颜色选择器
二、颜色格式
以红色为例,使用不同的格式(不区分大小写)显示红色如下
- red
- rgb(255,0,0)或者rgb(100%,0%,0%)
- #f00或者#ff0000或者#f00f
- hsl(0,100%,50%)或者hsl(360, 100%, 50%)
- hsv(0, 100%, 100%)或者hsv(360, 100%, 100%)
三、格式之间的转换
1.RGB转换HEX(即十六进制)
代码如下(示例):
// 将rgb(255,0,0)转换成#ff0000
function rgb2hex(rgb){
// rgby颜色值的正则
var reg = /^(rgb|RGB)/;
// 判断是否为rgb格式
if(reg.test(rgb)){
// 将rgb的三个数值切割成数组 rgb(255,0,0) ——> ["255","0","0"]
var colorArr = rgb.replace(/(?:rgb|RGB|\(|\))*/g,"").split(',');
var hex = "#" + ((1 << 24) + (parseInt(colorArr[0]) << 16) + (parseInt(colorArr[1]) << 8) + parseInt(colorArr[2])).toString(16).slice(1);
return hex;
}else{
return rgb
}
}
console.log(rgb2hex('rgb(255,66,99)')) // #ff4263
2.HEX转换RGB
代码如下(示例):
// 将#f00转换成rgb(255,0,0)
hex2rgb(hex) {
// 16进制颜色值的正则
var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
// 把颜色值变成小写
var color = hex.toLowerCase();
// 判断是否为hex格式
if (reg.test(color)) {
// 如果只有三位的值,需变成六位,如:#fff => #ffffff
if (color.length === 4) {
var colorNew = "#";
for (var i = 1; i < color.length; i += 1) {
colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1));
}
color = colorNew;
}
var colorChange = [];
for (var i = 1; i < color.length; i += 2) {
colorChange.push(parseInt("0x" + color.slice(i, i + 2)));
}
return "rgb(" + colorChange.join(",") + ")";
} else {
return color;
}
}
console.log(hex2rgb('#ff4263')) // rgb(255,66,99)
3.RGB转换HSB/HSV
其中,注意:
M = Math.max(R, G, B)
m = Math.min(R, G, B)
代码如下(示例):
// 将rgb(255,0,0)转换成hsb(360, 100%, 100%)
function rgb2hsb(rgb) {
// rgb颜色值的正则
var reg = /^(rgb|RGB)/;
// 判断是否为rgb格式
if (reg.test(rgb)) {
// 将rgb的三个数值切割成数组 rgb(255,0,0) ——> ["255","0","0"]
var colorArr = rgb.replace(/(?:rgb|RGB|\(|\))*/g, "").split(",");
var M = Math.max(colorArr[0], colorArr[1], colorArr[2]);
var m = Math.min(colorArr[0], colorArr[1], colorArr[2]);
var H = 0;
if (M == m) {
H = 0; //事实上,当max==min的时候,h无论为多少都无所谓
} else if (M == colorArr[0] && colorArr[1] >= colorArr[2]) {
H = 60 * ((colorArr[1] - colorArr[2]) / (M - m)) + 0;
} else if (M == colorArr[0] && colorArr[1] < colorArr[2]) {
H = 60 * ((colorArr[1] - colorArr[2]) / (M - m)) + 360;
} else if (M == colorArr[1]) {
H = 60 * ((colorArr[2] - colorArr[0]) / (M - m)) + 120;
} else if (M == colorArr[2]) {
H = 60 * ((colorArr[0] - colorArr[1]) / (M - m)) + 240;
}
var S = 0;
if (M == 0) {
S = 0;
} else {
S = parseInt(((M - m) / M) * 100);
}
return "hsb(" + parseInt(H) + "," + S + "%," + parseInt((M / 255) * 100) + "%)";
} else {
return rgb;
}
}
console.log(rgb2hsb('rgb(255,66,99)')) // hsb(349,74%,100%)
CSS 里头支持的是 HSL,而不是 HSB,因此不要直接使用HSB的数值,因此不推荐使用HSB
4.RGB转换HSL
HSB和HSL在H(色相)上完全一致,但是两者的S(饱和度)、L(亮度)和B(明度)都不一致
代码如下(示例):
// 将rgb(255,0,0)转换成hsl(360, 100%, 50%)
function rgb2hsb(rgb) {
// rgb颜色值的正则
var reg = /^(rgb|RGB)/;
// 判断是否为rgb格式
if (reg.test(rgb)) {
// 将rgb的三个数值切割成数组 rgb(255,0,0) ——> ["255","0","0"]
var colorArr = rgb.replace(/(?:rgb|RGB|\(|\))*/g, "").split(",");
var M = Math.max(colorArr[0], colorArr[1], colorArr[2]);
var m = Math.min(colorArr[0], colorArr[1], colorArr[2]);
var H = 0;
if (M == m) {
H = 0; //事实上,当max==min的时候,h无论为多少都无所谓
} else if (M == colorArr[0] && colorArr[1] >= colorArr[2]) {
H = 60 * ((colorArr[1] - colorArr[2]) / (M - m)) + 0;
} else if (M == colorArr[0] && colorArr[1] < colorArr[2]) {
H = 60 * ((colorArr[1] - colorArr[2]) / (M - m)) + 360;
} else if (M == colorArr[1]) {
H = 60 * ((colorArr[2] - colorArr[0]) / (M - m)) + 120;
} else if (M == colorArr[2]) {
H = 60 * ((colorArr[0] - colorArr[1]) / (M - m)) + 240;
}
return "hsl(" + parseInt(H) + "," + parseInt(((M - m) / (1 - Math.abs((M + m) / 255 - 1)) / 255) * 100) + "%," + parseInt(((M + m) / 2 / 255) * 100) + "%)";
} else {
return rgb;
}
}
console.log(rgb2hsl('rgb(255,66,99)')) // hsl(349,100%,62%)
5.HSB/HSV转换HSL
代码如下(示例):
// 将hsb(349,74%,100%)转换成hsl(349,100%,62%)
function hsb2hsl(hsb){
// hsb颜色值的正则
var reg = /^(hsb|HSB)/;
// 判断是否为hsb格式
if (reg.test(hsb)) {
var colorArr = hsb.replace(/(?:hsb|HSB|\(|\)|%)*/g, "").split(",");
return "hsl(" + parseInt(colorArr[0]) + "," + parseInt((((colorArr[1] / 100) * (colorArr[2] / 100)) / (1 - Math.abs((2 - colorArr[1] / 100) * (colorArr[2] / 100) - 1))) * 100) + "%," + parseInt(((2 - colorArr[1] / 100) * (colorArr[2] / 100) * 100) / 2) + "%)";
} else {
return hsb;
}
}
console.log(hsb2hsl('hsb(127, 93%, 80%)')) // hsl(127,86%,42%)
6.HSL转换HSB/HSV
代码如下(示例):
// 将hsl(349,100%,62%)转换成hsb(349,74%,100%)
function hsl2hsb(hsl){
// hsl颜色值的正则
var reg = /^(hsl|HSL)/;
// 判断是否为hsl格式
if (reg.test(hsl)) {
var colorArr = hsb.replace(/(?:hsl|HSL|\(|\)|%)*/g, "").split(",");
return "hsb(" + parseInt(colorArr[0]) + "," + parseInt((((colorArr[1] / 100) * (1 - Math.abs(2 * (colorArr[2] / 100) - 1)) * 2) / (2 * (colorArr[2] / 100) + (colorArr[1] / 100) * (1 - Math.abs(2 * (colorArr[2] / 100) - 1)))) * 100) + "%," + parseInt(((2 * (colorArr[2] / 100) + (colorArr[1] / 100) * (1 - Math.abs(2 * (colorArr[2] / 100) - 1))) * 100) / 2) + "%)";
} else {
return hsl;
}
}
console.log(hsl2hsb('hsl(127, 93%, 80%)')) // hsb(127,37%,98%)
四、验证输入的颜色值格式,并将输入的颜色值统一转换成HEX颜色值
function parseColor(color) {
var hexReg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
var rgbReg = /^(rgb|RGB)/;
var hsbReg = /^(hsb|HSB|hsv|HSV)/;
var hslReg = /^(hsl|HSL)/;
if (hexReg.test(color)) {
// 十六进制颜色值
return color;
} else if (rgbReg.test(color)) {
// RGB颜色值
return rgb2hex(color);
} else if (hsbReg.test(color)) {
// HSB颜色值
return rgb2hex(hsb2rgb(color));
} else if (hslReg.test(color)) {
// HSL颜色值
return rgb2hex(hsb2rgb(hsl2hsb(color)));
}
}