Javascript实现Web颜色值转换


Posted in Javascript onFebruary 05, 2015

最近一直忙碌于完成业务需求,好长时间没有写博客了。今天稍微有些时间,翻看了一下最近项目中的一些前端代码,看到Web颜色转换功能的时候,突然想到当我们在做一些颜色设置/编辑的需求时,经常会涉及到各种颜色值格式的互换。于是我决定记录一下我在做这一部分功能的时候是如何实现的,写下来和大家分享一下,希望读者们各抒己见,多多交流。

先看看问题

问题一,当我们在进行网页前端开发的时候,经常会使用 dom.style.backgroundColor = "#f00" 来设置某个 DOM 元素的背景颜色,也会通过类似(为什么是类似?情况比较多,这里可以自由发挥想象) var bgc = dom.style.backgroundColor 的代码来获取某个 DOM 元素的背景颜色。那么问题来了,请看下图:

Javascript实现Web颜色值转换

如果这里的对比还不够明显,我们再继续往下看:

Javascript实现Web颜色值转换

很显然,同一个颜色值,本来应该相等,但结果却并非如此。而这并非个例,笔者在Chrome开发工具和Firefox控制台,得到的结果是一致的。

问题二,前端开发工作,往往是从还原UI设计稿开始。而在编码过程中我们经常会发现这样的设计:某个盒子背景纯色(假设:#f00),但带有 75% 的不透明度。很显然,这种情况我们不能简单的通过 dom.style.backgroundColor = "#f00"来设置,因为达不到半透明的效果。话锋回转,我们知道 CSS3 里面出现了一个 rgba 的东西,也就是说我们可以通过 dom.style.backgroundColor = "rgba(255, 0, 0, 0.75)" 这样来设置带有半透明的背景颜色。那么,问题又来了:这一转换在Photoshop中很容易做到,但若在Javascript中,我们又该如何将(“#f00”, 75)转换成 rgba(255, 0, 0, 0.75) 呢?

接下来,我们一起来看看我是怎么做的。

rgb(a)颜色值转成十六进制颜色(hex)

都是做开发的,咱懂!说啥也不如直接上代码来得痛快,不过这里先放一段最原始的:

<!-- lang: js -->

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};

    }

};

为什么说是最原始的呢?因为在我今天review代码的时候,发现这里还有进化的空间,接下来对比一下进化(优化)后的代码:

<!-- lang: js -->

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};

    }

};

且不说少了一个if分支,单从代码量上看,就很明显了吧!接下来,我们看看转换的结果是否如我们所愿的那样,为此我在控制台中执行了下图所示的几行代码:

Javascript实现Web颜色值转换

从执行结果来看,我们的方法似乎已经能够达到我们的目的了。但是,细心的朋友应该注意到了图中有两个红色箭头,这里是不是有什么坑?不错。我们仔细看看第一个箭头中传入的颜色参数 rgb(255, 0, 0, 2),其实这里并不是一个合法的颜色值,rgb格式的颜色值,是没有第四个(透明度)参数的;再看第二个箭头中 rgba(255, 0, 0, 1.48),这里格式是没问题了,但是透明度却为1.48,其实不是一个合法的透明度值。这两种情况,我们的方法都正常执行了,也正常返回了,说明,我们的方法还有进一步进化的空间,就交给大家自行发挥了!

十六进制颜色(hex)转成rgba格式

在日常开发中,我们最常使用的颜色值应该就是十六进制格式的颜色值了(#ff0000、#f00等),如果我们在使用颜色值的时候需要转换成rgba格式,我们该怎么做呢?

<!-- lang: js -->

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 : 'fffff';

    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) + ')'

    };

};

同样,我们也写一写验证代码,来测试一下,我们的转换是否正常:

Javascript实现Web颜色值转换

从执行结果来看,我们的方法,没有问题了,都能拿到我们想要的转换结果。但这里依然留给了大家两个红色箭头,非法的透明度和非法的颜色值。这部分进化功能也留给大家了,哈哈…

最后,网页颜色值之间的相互转换,其实是一个老生常谈的问题,我这里也只是简单的列出了一种,相信还有更多更好的方法可以使用,欢迎大家提出来,大家交流,共同进步~~

Javascript 相关文章推荐
Javascript 函数对象的多重身份
Jun 28 Javascript
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
Nov 30 Javascript
js动态添加onload、onresize、onscroll事件(另类方法)
Dec 26 Javascript
jquery在项目中做复选框时遇到的一些问题笔记
Nov 17 Javascript
javascript实现给定半径求出圆的面积
Jun 26 Javascript
jQuery实现仿QQ空间装扮预览图片的鼠标提示效果代码
Oct 30 Javascript
JSP防止网页刷新重复提交数据的几种方法
Nov 19 Javascript
vue.js实现仿原生ios时间选择组件实例代码
Dec 21 Javascript
js实现符合国情的日期插件详解
Jan 19 Javascript
js canvas实现橡皮擦效果
Dec 20 Javascript
Vue-Cli项目优化操作的实现
Oct 27 Javascript
JS实现斐波那契数列的五种方式(小结)
Sep 09 Javascript
JS表的模拟方法
Feb 05 #Javascript
JS的数组迭代方法
Feb 05 #Javascript
js实现照片墙功能实例
Feb 05 #Javascript
js实现仿百度瀑布流的方法
Feb 05 #Javascript
JS函数this的用法实例分析
Feb 05 #Javascript
IE下使用jQuery重置iframe地址时内存泄露问题解决办法
Feb 05 #Javascript
js关于命名空间的函数实例
Feb 05 #Javascript
You might like
PHP中检索字符串的方法分析【strstr与substr_count方法】
2017/02/17 PHP
使用ucenter实现多站点同步登录的讲解
2019/03/21 PHP
PHP错误提示It is not safe to rely on the system……的解决方法
2019/03/25 PHP
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
动态载入/删除/更新外部 JavaScript/Css 文件的代码
2010/07/03 Javascript
用jQuery实现的智能隐藏、滑动效果的返回顶部代码
2014/03/18 Javascript
js控制再次点击按钮之间的间隔时间可防止重复提交
2014/08/01 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
jQuery实现DIV层收缩展开的方法
2015/02/27 Javascript
jQuery easyui的validatebox校验规则扩展及easyui校验框validatebox用法
2016/01/18 Javascript
js判断输入字符串是否为空、空格、null的方法总结
2016/06/14 Javascript
详解node+express+ejs+bootstrap构建项目
2017/09/27 Javascript
vue中阻止click事件冒泡,防止触发另一个事件的方法
2018/02/08 Javascript
nodejs实现解析xml字符串为对象的方法示例
2018/03/14 NodeJs
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
2018/11/28 Javascript
详解JavaScript的内存空间、赋值和深浅拷贝
2019/04/17 Javascript
vue项目出现页面空白的解决方案
2019/10/31 Javascript
前端开发之便利店收银系统代码
2019/12/27 Javascript
浅谈在vue-cli3项目中解决动态引入图片img404的问题
2020/08/04 Javascript
搭建vscode+vue环境的详细教程
2020/08/31 Javascript
[05:10]2014DOTA2国际邀请赛 通往胜利之匙赛场探秘之旅
2014/07/18 DOTA
[00:44]华丽开场!DOTA2勇士令状带来全新对阵画面
2019/05/15 DOTA
Python 抓取动态网页内容方案详解
2014/12/25 Python
Python之父谈Python的未来形式
2016/07/01 Python
Python 装饰器使用详解
2017/07/29 Python
python对离散变量的one-hot编码方法
2018/07/11 Python
PyQt 图解Qt Designer工具的使用方法
2019/08/06 Python
python 实现图片上传接口开发 并生成可以访问的图片url
2019/12/18 Python
使用Python操作MySQL的小技巧
2020/09/10 Python
python Protobuf定义消息类型知识点讲解
2021/03/02 Python
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
美国购买当代和现代家具网站:MODTEMPO
2018/07/20 全球购物
彪马日本官网:PUMA日本
2019/01/31 全球购物
企业宣传工作方案
2014/06/02 职场文书
中学感恩教育活动总结
2015/05/05 职场文书
2015年高一班主任工作总结
2015/05/13 职场文书