分析:
rgb的色值是rgb+三个数字+两个括号;
hex色值是#+数字或者字母(A-F);
所以我们需要把rgb中的数字取出来,再把数字转成16进制字符,拼接上#号就得到了hex颜色。
步骤:
1.提取rgb中的数字;
2.把数字转为16进制;
3.拼接#号。
那么数字转16进制应该怎么实现呢?
这里利用toString(16)将上面得到的10进制转为16进制。
toString介绍
toString:
从上例子可以看到toString(16)把255转成了ff正是我们想要的结果。
接下来我们就按照步骤来一步一步实现
假设有一个rgb(255, 255, 255)
1.使用正则获取rgb中的数字
let reg = /d+/g;
let str = 'rgb(255, 255, 255)';
let arr = str.match(reg);
2.将arr中的字符转为16进制
注意:这里得到的arr是字符串,我们再转换的时候需要先将arr中的字符串转为数字
let hexArr = arr.map(n => Number(n).toString(16))
通常我们使用hex是大写的字符
let hexArr = arr.map(n => Number(n).toString(16).toUpperCase())
3.将的到的hexArr拼接成字符
let result = `#${hexArr.join('')}`
别以为这样就完了,还得考虑一种情况
当我们的rgb颜色是rgb(0, 0, 0)时,也就是色值数字是一位数或者16以下的两位数时,如:
当16以下的数字转换得到的结果是一位数,hex色值是两位数组成,除非rgb色值数字一样才可简写。
所以我们这里在得到的一位16进制字符时,需在该字符前补0。
这里介绍一个方法padStart
:
第一个参数是返回的字符的长度,第二个参数是在字符前面补上的字符,其中对应在字符后补字符的方法还有padEnd
。
至此,我们以上第2步中,在.toUpperCase()后加上.toUpperCase().padStart(2, '0')。
回顾一下,第一是取出rgb中的数字,第二是把数字转为16进制,第三拼接#。
完整代码:
const rgb2Hex = (rgb) =>`#${rgb.match(/\d+/g)?.map(d => (Number(d).toString(16).toUpperCase()).padStart(2,'0')).join('')}`;