发表于: 2017-03-31 20:31:49
1 520
【JS-01】随机的取一种颜色,随机的性能怎么样?
小课堂【武汉第118期】
1.背景介绍
在做饼状图,标签云等js效果时,经常需要随机获取颜色进行使用。这时通常有两种方法:一是准备一组漂亮的候选颜色, 二是随机生成颜色。在数量很多或不明确时,只能选择第二种方法。
2.知识剖析
知识点1:在CSS中一般怎么表示颜色?
①.使用颜色名:比如yellow,black,white,blue等等
②.使用十六进制值:比如#000000,#FFFFFF等。长度为6,值为16进制的从0到F。
③.使用 rgb 值:比如rgb(0,0,0),rgb(255,255,255)等。取值范围为0到255。
知识点2:取随机数用到的几个Math方法
①Math.random():生成大于 0 小于 1 的随机数。下面的代码可以生成 0~100 的随机数。
②Math.ceil(n):ceil() 可以把小数点以下部分舍去并使整数部分加 1 。举例来说,3.6 会进位到 4 ,-3.6 会进位到 -3 。
③Math.floor(n):floor() 可以把小数点以下部分舍去,即取整。举例来说,3.6 会取整为 3 ,-3.6 会取整为 -4 。
④Math.round(n):round() 可以把整数四舍五入。举例来说,3.6 会四舍五入为 4 ,-3.6 会四舍五入为 -4 。
知识点3:随机取一种颜色的几种函数写法及其优劣:
此处请查看demo
3.常见问题
我们看到在上个demo中,我使用了Math.random()配合Math.floor(n)取颜色。思考一下,这种方法去颜色有没有规律可循会不会存在某些颜色取到的概率大一点呢?使用Math.ceil(n),Math.round(n)呢?
我们写一个函数做一下测试:
var temp;
var arr=[0,0,0,0,0,0,0,0,0,0,0,0];
for(var i=0;i<1000000;i++){
temp=Math.floor(Math.random()*10+1);
arr[temp]=arr[temp]+1;
}
for (var j = 1; j < arr.length; j++) {
console.log("得到"+j+"的概率:" + arr[j]/1000000);
}
VM121:8 得到1的概率:0.099478
VM121:8 得到2的概率:0.100267
VM121:8 得到3的概率:0.100046
VM121:8 得到4的概率:0.100027
VM121:8 得到5的概率:0.099616
VM121:8 得到6的概率:0.100177
VM121:8 得到7的概率:0.099901
VM121:8 得到8的概率:0.099942
VM121:8 得到9的概率:0.100541
VM121:8 得到10的概率:0.100005
var temp;
var arr=[0,0,0,0,0,0,0,0,0,0,0,0];
for(var i=0;i<1000000;i++){
temp=Math.round(Math.random()*10+1);
arr[temp]=arr[temp]+1;
}
for (var j = 1; j < arr.length; j++) {
console.log("得到"+j+"的概率:" + arr[j]/1000000);
}
VM123:8 得到1的概率:0.049824
VM123:8 得到2的概率:0.100521
VM123:8 得到3的概率:0.100091
VM123:8 得到4的概率:0.099778
VM123:8 得到5的概率:0.10011
VM123:8 得到6的概率:0.099536
VM123:8 得到7的概率:0.100111
VM123:8 得到8的概率:0.099748
VM123:8 得到9的概率:0.100135
VM123:8 得到10的概率:0.100121
VM123:8 得到11的概率:0.050025
分别将Math.round(n),Math.ceil(n)代入测试。
可以看到,使用Math.round(n)时,在取一头一尾两个数的概率只有其他数的一半,这是为什么呢?
因为我们要每个数字出现的概率相等,就要保证每个区间长度相等,使用 round 取整后(可以把整数四舍五入),映射到1的区间为(1,1.5) 映射到2的区间为(1.5, 2.5)...... (9.5,10.5),(10.5,11) 可见其区间长度是不同的,即1和11出现的概率为其他数字出现概率的一半。
4.解决方案
5.编码实战
此处请查看demo
6.扩展思考
还有其他随机取颜色的方法么?
其实css表示颜色,还有一种hsb模型,hsb( (0~360°),(0~100%), (0~100%)).
跟之前rgb方法类似,将内部数随机取值,拼接起来,不过涉及到角度,实现起来较麻烦,有兴趣的小课堂过后可以去试试
7.参考文献
8.更多讨论
刚才我们谈到取随机数的概率要一样,那么不一样怎么实现呢?比如我们常见的转盘抽奖.
评论