随机颜色

[].forEach.call($$("*"),function(a){
  a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
})
(~~(Math.random()*(1<<24))).toString(16)

真正有趣的地方在于定义颜色部分:


~~(Math.random()*(1<<24))).toString(16)

天呐,上面的代码是什么意思?在JavaScript中,比特操作符并不是经常被使用,因此这里可能会让很多程序员感到很疑惑。


我们想达到的目的是活的一个十六进制格式的颜色例如白色对应的是FFFFFF,蓝色对应的是0000FF,或者随便一个颜色37f9ac。虽然我们人类喜欢十进制,但是我们的代码常常会需要十六进制的东西。


我们首先要学会如何使用toString函数将一个十进制的数组转换为一个十六进制整数。这个函数可以接受一个参数,如果参数缺省,默认为十进制,但是你完全可以使用别的数组:


(30).toString(); // "30"
(30).toString(10); // "30"
(30).toString(16); // "1e" 十六进制
(30).toString(2); // "11110" 二进制
(30).toString(36); // "u" 36是允许的最大参数值

除此之外,你可以使用parseInt函数将十六进制数字转换为十进制。


parseInt("30"); // "30"
parseInt("30", 10); // "30"
parseInt("1e", 16); // "30"
parseInt("11110", 2); // "30"
parseInt("u", 36); // "30"

因此,我们现在只需要一个位于0ffffff之间的十六进制数,由于:


parseInt("ffffff", 16) == 16777215

而这里的16777215实际上是2^24-1


如果你对二进制数学熟悉的话,你可能会知道1<<24 == 16777216


再进一步,你每在1后面添加一个0,你就相当于多做了一次2的乘方:


1 // 1 == 2^0
100 // 4 == 2^2
10000 // 16 == 2^4
1000000000000000000000000 // 16777216 == 2^24

因此,在这里我们可以知道Math.random()*(1<<24)表示一个位于016777216之间的数。


但是这里并没有结束,因为Math.random返回的是一个浮点数,但是我们只想要整数部分。我们的代码中使用波浪号操作符来完成这件事。波浪操作符在JavaScript中被用来对一个变量进行取反。


但是我们在这里并不关心取反,我们指向获取整数部分。因此我们还可以知道两次取反可以去掉一个浮点数的小数部分,因此~~的作用相当于parseInt


var a = 12.34, // ~~a = 12
    b = -1231.8754, // ~~b = -1231
    c = 3213.000001 // ~~c = 3213
;

~~a == parseInt(a, 10); // true
~~b == parseInt(b, 10); // true
~~c == parseInt(c, 10); // true

当然,我们还有一种更加简洁的方法,使用OR操作符:


~~a == 0|a == parseInt(a, 10)
~~b == 0|b == parseInt(b, 10)
~~c == 0|c == parseInt(c, 10)

最终,我们获得了一个位于016777216之间的随机整数,也就是我们想要的随机颜色。此时我们只需要使用toString(16)将它转化为十六进制数即可。

 
posted @ 2016-03-25 11:20  还能再菜点吗?  阅读(287)  评论(0编辑  收藏  举报