rgb和hex相互转换

929 阅读2分钟

前言

这里使用了一些位运算进行计算,如果对位运算不了解的,可以了解一下,位运算

hex(16进制):#FFF,#ffffff等等16进制颜色

rgb:rgb(255,255,255),rgb(123,125,241)等等

笔者第一次遇到颜色转换时,懵了,没有思路,害,想着放着后面再来看看,结果放着放着,哦豁,再一次遇到了它,唉,被它逮住了。

这题,必须得剿,不剿不行呀,码着代码看着题,结果它来了。哈哈哈哈

因为笔者想自己输入hex或者rgb然后转换,就想着写个输入框,获取转换前后颜色。

设计

  • test1和test2的背景颜色由输入颜色和转化后颜色决定
  • 需要一个输入框inChange来让我输入
  • 提交按钮colorBtn提交我输入颜色

html片段:

<div class="box">
    <div class="test1">
        输入颜色
    </div>
    <div class="test2">
        转换颜色
    </div>
</div>
<div class="boxin">
    <input class="inChange" type="text">
    <button class="colorBtn">提交</button>
</div>

css片段:

    * {
        padding: 0;
        margin: 0;
    }

    .box {
        display: flex;
        justify-content: center;
    }

    .test1,
    .test2 {
        width: 200px;
        height: 100px;
        text-align: center;
        border: 1px solid red;
        margin: 10px 20px;
    }

    .boxin {
        width: 100%;
        text-align: center;
    }

这里的js我把实现转换的核心代码在下面注释给分割出来,方便复制

注意:

  • 16进制每个字符所占4位,超过32位溢出.
  • hex有6个16进制字符,24位。

js

//hex转换成rgb
function hexToRgb(hex) {
    //用于判断hex的格式对不对
    let regExp = /^#([0-9A-F]{3}|[0-9A-F]{6})$/i;
    //判断hex的格式是否正确
    if (!regExp.test(hex)) {
        return false;
    }
    
    //-----hex到rgb转换核心代码
    //获取#后的16进制数
    let str = hex.substr(1,);
    //当str长度为3时,它是简写,需要把它装回6位
    if (str.length == 3) {
        let tempStr = "";
        for (let i = 0; i < 3; i++) {
            tempStr += str[i] + str[i];
        }
        str = tempStr;
    }
    //16进制
    str = "0x" + str;
    //16进制每个字符占4个字节,16/4=4,对应的是(例子:0xaf54ff)af
    let r = str >> 16;
    //对应af54在与运算符后,对应54
    let g = str >> 8 & 0xff;
    //对应ff
    let b = str & 0xff;
    let rgb = `rgb(${r}, ${g}, ${b})`;
    //-----hex到rgb转换完毕
    
    document.querySelector(".test1").style.backgroundColor = hex;
    document.querySelector(".test1").innerHTML = hex;
    document.querySelector(".test2").style.backgroundColor = rgb;
    document.querySelector(".test2").innerHTML = rgb;
}
​
function rgbToHex(rgb) {
    //正则太长,直接复制粘贴会有空格,请自行删除(有空格报错噢,嘿嘿嘿)
    let regExp = /^rgb(\s*((1\d{2}|2(5[0-5]|[0-4]\d))|\d{1,2})\s*,\s*((1\d{2}|2(5[0-5]|[0-4]\d))|\d{1,2})\s*,\s*((1\d{2}|2(5[0-5]|[0-4]\d))|\d{1,2})\s*)$/i;
    //判断rgb的格式是否正确
    if (!regExp.test(rgb)) {
        return false;
    }
    
    //-----rgb到hex转换核心代码
    //获取rgb的数字
    let arr = rgb.split(",");
    let r = + arr[0].split("(")[1];
    let g = + arr[1];
    let b = + arr[2].split(")")[0];
    //hex有6位,占了4*6=24字节,每一步将rgb还原
    let value = (1 << 24) + (r << 16) + (g << 8) + b;
    //只要24位,其实有25位,16进制转换后高位多出了一个1,提取1后面的16进制数。
    let hex = "#" + value.toString(16).slice(1);
    //-----rgb到hex转换完毕
    
    document.querySelector(".test1").style.backgroundColor = rgb;
    document.querySelector(".test1").innerHTML = rgb;
    document.querySelector(".test2").style.backgroundColor = hex;
    document.querySelector(".test2").innerHTML = hex;
}
function hexOrRgb() {
    //获取输入框的值
    let val = document.querySelector(".inChange").value;
    //调用,不是执行下一个
    hexToRgb(val) || rgbToHex(val);
}
function init() {
    //监听按钮的点击
    let btn = document.querySelector(".colorBtn");
    btn.addEventListener("click", () => {
        hexOrRgb();
    });
}
//入口
init();

结语

演示地址

希望小伙伴们在笔试遇见这种题时,分分钟拿捏~