css3一个重要的部分就是引入了多种颜色格式。各种颜色的使用在透明度/css3渐变等应用非常广泛。(css3背景渐变的讲解可见)
但是我们写样式的时候常常被颜色的写法弄晕。
今天就教大家实现一个简单的颜色转换器。
关于css3颜色的详细介绍可以点击这里,也可以看看本站的玩转CSS3的颜色
目标:实现一个颜色转换器,支持rgba颜色,hex颜色与滤镜颜色互相转变。
思路:
我们首先要明确转换的规则。
rgb与hex的一个简单对照:
关键字 hex颜色 rgb yellow #FFFF00 255 255 0 white #FFFFFF 255 255 255 red #FF0000 255 0 0
更加详细的英文颜色对照表请参考网页颜色英文代码全集,大家可以看到rgb颜色其实是r g b 三个部分组成的。
其实是hex颜色 每两位分组,之后从16进制转为十进制即可。
同样,我如果知道rgb颜色,想把它转为hex,只需要把r,g,b三个部分分别转为十六进制即可。rgba的a主要是操纵的透明度。范围从0-1.
而ms渐变滤镜支持单一颜色。也支持透明度,他的形式是这样的
filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#4c000000', EndColorStr='#4c000000')
其中StartColorStr 和 EndColorStr颜色组成:
# + 透明度 + hex颜色。透明度是通过下列公式计算出来的:
算法: Math.floor(opacity(0-1)* 255).toString(16);
举个例子。我们想得到透明度30%的背景色#000000。则用Math.floor(0.3* 255).toString(16)=4c 之后拼起来:
#4c000000 filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#4c000000', EndColorStr='#4c000000')
关于ie滤镜的详细用法参考Gradient Filter
实现方法
可以看出上述思路的核心是“进制转换”,而进制转换在javascript中我们可以利用toString方法。
方法:Number.toString()
将数字转换为字符串。用它的参数指定的基数或底数(底数范围为2-36)。如果省略参数,则使用基数10。当参数值为2时,返回二进制数。
var a = 34; document.write(a.toString() + "<br />"); document.write(a.toString(2) + "<br />"); document.write(a.toString(8) + "<br />"); document.write(a.toString(16) + "<br />");
补充toString相关(javascript中,toString方法是每个对象都有的方法,并且是一个非常强大的方法。他的使用范围也很广 。方法的基本用法:JavaScript toString() 方法、JavaScript函数补完:toString()而实际应用的时候,javascript内部很多方法都会调用对象自身的toString方法。
- 如 alert() toString(),一个会自动调用的方法
- 如 加运算(javascript高级程序设计第二版 p42加性操作符之加法)
- 减运算(注意区别)(javascript高级程序设计第二版 p43加性操作符之减法)
- 一元加减操作符(注意与+号的区别)(javascript高级程序设计第二版 p31-p33 操作符部分第一节)
而对象自身的toString方法可以被重写。另外呢,覆盖对象的toString方法不会被for in遍历出来,这个感兴趣的可以自己了解。各浏览器中用 for in 可以遍历对象中被更新的内置方法存在差异
注意toString还有一点,数字的字面值(literal)不是对象
2.toString(); // 出错:SyntaxError
解决方法:
2..toString(); // 第二个点号可以正常解析 2 .toString(); // 注意点号前面的空格 (2).toString(); // 2先被计算
扯了这么多,我们来讲讲写法:首先呢,接收用户的参数。这个参数可能是hex颜色(#fff,#ffffff)之类,可能是rgba颜色 (rgba()),那么首先我们就要去分出三种情况。仍然可以利用正则表达式来判断。
- 可以利用/r/.test(val) 判断是否含有"r"这样就可以判断用户输入是rgba颜色。
- 可以利用/#/.test(val) 判断是否含有“#”(hex颜色)
- 之后可以用 val.match(/\d+/g),他的意思是,匹配一个或者多个数字。
那比如'rgba(255,255,255)'.match(/\d+/g),结果就是:["255", "255", "255"],利用数组下标就可以方便的进行处理。上代码吧~
/**这个函数主要是把rgb颜色转为hex颜色**/ function toHex(r, g, b) { Pr = r.toString(16).length == 1 ? (0 + r.toString(16)) : r.toString(16) Pg = g.toString(16).length == 1 ? (0 + g.toString(16)) : g.toString(16) Pb = b.toString(16).length == 1 ? (0 + b.toString(16)) : b.toString(16) return Pr + Pg + Pb } /**这个函数是主要入口**/ var parseColor = function (val, op) {//接收两个参数:颜色值跟透明度 var r, g, b, op = op || 1, hex, filter;//我们利用var 多个变量名逗号的方式定义多个变量 // 默认rgb if (/r/.test(val)) {//抽出rgb var arr = val.match(/\d+/g); r = parseInt(arr[0]); g = parseInt(arr[1]); b = parseInt(arr[2]); op = op; hex = '#' + toHex(r, g, b);//转到hex方法,拿到hex颜色。 filter = '#' + Math.floor(op * 255).toString(16) + toHex(r, g, b); } // 进制转换 else if (/#/.test(val)) { hex = val var len = val.length; // #ffffff if (len === 7) {//输入的是七位#ffffff 那么利用slice方法,每两位分组。去掉前面的# r = parseInt(val.slice(1, 3), 16); g = parseInt(val.slice(3, 5), 16); b = parseInt(val.slice(5), 16); op = op; filter = '#' + Math.floor(op * 255).toString(16) + toHex(r, g, b); } // #fff else if (len === 4) {//输入的是四位#fff 那么利用charAt方法,每一位分组,补全成两位,去掉前面的# r = parseInt(val.charAt(1) + val.charAt(1), 16); g = parseInt(val.charAt(2) + val.charAt(2), 16); b = parseInt(val.charAt(3) + val.charAt(3), 16); op = op; filter = '#' + Math.floor(op * 255).toString(16) + toHex(r, g, b); } } else {//容错 alert('颜色格式不正确,请重新输入'); } return {//这里我们的结果返回了一个对象。可以利用对象+属性名即可取到 'r' : r, 'g' : g, 'b' : b, 'op' : op, 'hex' : hex, 'filter' : filter } }; //console.log(parseColor('#ffffff',1)) //console.log(parseColor('#fff',0.5)) //console.log(parseColor('#000000',0.3)) //console.log(parseColor('rgb(122,34,214)',0.2))
以上函数有个很重要的就是结果返回的是一个对象是键值对的形式。我们取对象值的时候,既可以利用 a.r属性来取,也可以利用a['r']属性来取,注意a['r']的引号!另外这里我们用var定义了一个函数,这叫做函数表达式。以后的文章会讲解到。
如需转载,烦请注明出处:http://www.w3cplus.com/js/99js-color-converter.html