需要实现一个随机生成颜色的需求,要求是生成的颜色要避免白色等浅色区域,且不能出现重复颜色值。颜色值最常用的有RGB格式,形如rgb(247,246,42) ,还有Hex十六进制的格式,形如#c17313 。要解决两个问题,第一个就是随机生成颜色,第二个就是排除浅色区域颜色。那要怎么做呢?
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>javascript随机获取颜色</title> <style type="text/css"> #rotaDeptUl li{ border: 1px solid; float: left; width: 19%; height: 34px; line-height: 34px; overflow: hidden; text-align: center; margin: 5px 0; background-color: white; margin-right: 1%; } #rotaDeptUl li:nth-child(5n){ margin-right:0; } </style> </head> <script src="https://cdn.staticfile.org/jquery/2.2.4/jquery.min.js"></script> <ul id="rotaDeptUl"> </ul> <script type="text/javascript"> var html=""; //十六进制颜色数组 var colorHexArray=[]; //RGB颜色数组 var colorRgbArray=[]; //获取随机颜色十六进制 /*** 实现方法:‘0123456789abcdef’[Math.floor(Math.random()*16)])随意截取字符串中的一个字符, 然后判断字符串的长度是否为6,如果是,则返回color, 如果不是,color : arguments.callee(color)返回正在执行的函数, 即(color += ‘0123456789abcdef’[Math.floor(Math.random()*16)])并将color作为参数传进去; */ function getRandomColor(){ return '#' + ( function(color){ return (color += '0123456789abcdef'[Math.floor(Math.random()*16)]) && (color.length == 6) ? color : arguments.callee(color); } )(''); } /** * 获取随机颜色RGB格式 */ function getRandomColorRGB(){ let r = parseInt(Math.random() * 256), //0-255 g = parseInt(Math.random() * 256), //0-255 b = parseInt(Math.random() * 256); //0-255 return `rgb(${r},${g},${b})` //使用了es6的模板字符串 } //获取指定项数十六进制随机颜色 for(var i=0;i<6000;i++){ var a=getRandomColor(); if(colorHexArray.indexOf(a)==-1){ colorHexArray.push(a); } } //获取指定项数RGB随机颜色 for(var i=0;i<100;i++){ var a=getRandomColorRGB(); if(colorRgbArray.indexOf(a)==-1){ colorRgbArray.push(a); } } //Hex(十六进制)转RGB function hex2rgb(color) { color = color.slice(1); var rgb = ""; for(var i = 0; i < color.length; i += 2 ) { var end = i+2 rgb += parseInt(color.slice(i, end), 16).toString()+","; } rgb = rgb.slice(0, rgb.length-1) rgb = "rgb("+rgb+")" return rgb; } //RGB转Hex function rgb2hex(color1) { var rgb = color1.split(','); var r = parseInt(rgb[0].split('(')[1]); var g = parseInt(rgb[1]); var b = parseInt(rgb[2].split(')')[0]); var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); return hex; } function getMid(str) { var left = str.indexOf('(')+1; var right = str.indexOf(')'); return str.slice(left, right); } function toNum(str) { var rex = /[0-9]+/g; if(str.indexOf('%') > 0) { return (str.match(rex)[0]) / 100; } else { if(typeof(+str) === "number") { return +str; } } } //HEL转RGB function hel2rgb(color) { var arr = getMid(color).split(','); var r, g, b; var h = toNum((arr[0] / 360)+'' ), s = toNum(arr[1]), light = toNum(arr[2]); // h(色相) s(饱和度) l(亮度) var temp2, temp1; if (s == 0) { r = g = b = light; } else { temp2 = light < 0.5 ? light * (1 + s) : light + s - light * s; temp1 = 2 * light - temp2; var h2rgb = function(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1/6) return p + (q - p) * 6 * t; if (t < 1/2) return q; if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; return p } r = h2rgb(temp1, temp2, h + 1/3); g = h2rgb(temp1, temp2, h); b = h2rgb(temp1, temp2, h - 1/3); } return "rgb(" + Math.round(r * 255) + ',' + Math.round(g * 255) + ',' + Math.round(b * 255)+')'; } //RGB校验 function isRgb(color) { return /^rgb/.test(color) } //Hex校验 function isHex(color) { return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(color) } //HSL校验 function isHsl(color) { return /^hsl/.test(color); } //核心:var grayLevel = r0.299 + g0.587 + b*0.114; 根据当前颜色的灰度判断颜色深浅。 function grayLevel (color) { color = isRgb(color) ? color : (isHex(color) ? hex2rgb(color) : hel2rgb(color)); var arr = getMid(color).split(',') var r = arr[0], g = arr[1], b = arr[2]; return r*0.299 + g*0.587 + b*0.114 } //颜色值排序 function sortColor(colors) { return colors.sort(function(a, b){ return grayLevel(b) - grayLevel(a) }) } //方式一 RGB格式颜色排序 var result = sortColor(colorRgbArray); for(var i=0;i<result.length;i++){ var tempColor=result[i]; html+='<li style="background-color:'+tempColor+'">'+tempColor+'</li>'; } //$("ul").html(html); //方式二 Hex格式颜色排序 var html2=""; var result2 = sortColor(colorHexArray); for(var i=0;i<result2.length;i++){ //正整数正则 var r=/^\d+$/; //取后半部分颜色 且 是序号是10的倍数 if(i>(colorHexArray.length/2) && r.test(i/10)){ var tempColor=result2[i]; html2+='<li style="background-color:'+tempColor+'">'+tempColor+'</li>'; } } $("ul").html(html2); </script>
参考资料:写一个色值深浅排序方法、JavaScript获取随机颜色的方法、javascript获取随机颜色
算法扩展:
//获取指定数量随机颜色Hex格式 function getRandomHexColor(randomCount){ //颜色倍数 增大范围 var param1=60; //颜色截取范围系数 0.5表示从一半的位置开始取颜色 var param2=0.5; //颜色缩小倍数 获取颜色 0.1为 十分之一 每十个取一个 var param3=0.1; //比如随机取100个颜色,则从100*60个随机颜色中 截取第100*60*0.5个到最后 并且每10个颜色取一个 共100*60*0.5*0.1个颜色 再从100*60*0.5*0.1个中随机取100个 //原始十六进制颜色数组 var allColorHexArray=[]; //部分十六进制颜色数组 var colorHexArray=[]; //获取指定项数十六进制随机颜色 for(var i=0;i<randomCount*param1;i++){ var color=getRandomColor(); if(allColorHexArray.indexOf(color)==-1){ allColorHexArray.push(color); } } //Hex格式颜色排序 var result = sortColor(allColorHexArray); for(var i=0;i<result.length;i++){ //正整数正则 var r=/^\d+$/; // if(i>(result.length*param2) && r.test(i*param3)){ var tempColor=result[i]; colorHexArray.push(tempColor); } } //返回结果颜色集合 var resultColorArray=[]; //随机数数组 取randomCount个范围是[0,colorHexArray.length]的不重复随机数 var randomArray=getRandom(new Array(),randomCount,0,colorHexArray.length); //遍历随机数数组 for(var i=0;i<randomArray.length;i++){ //获取随机数 var random=randomArray[i]; //将随机颜色添加到结果集合中 resultColorArray.push(colorHexArray[random]); } //返回结果集 return resultColorArray; } //获取指定个数不重复随机数,指定范围 function getRandom(array,count,min,max){ //数量不够时 if(array.length<count){ //获取指定范围随机数 var random=randomNum(min, max); //判断随机数不存在,才添加到数组中 if(array.indexOf(random)==-1){ //添加随机数到数组 array.push(random); } //再次调用 array=getRandom(array,count,min,max); return array; //数量够时,返回随机数数组 }else{ return array; } } //生成[n,m]的随机整数的函数 function randomNum(minNum, maxNum) { switch (arguments.length) { case 1: return parseInt(Math.random() * minNum + 1, 10); break; case 2: return parseInt(Math.random() * ( maxNum - minNum + 1 ) + minNum, 10); //或者 Math.floor(Math.random()*( maxNum - minNum + 1 ) + minNum ); break; default: return 0; break; } }
示例:
示例中使用到了
layui、layer、semantic ui、spectrum
其中spectrum为github开源项目,颜色调色板插件
示例源码下载链接:https://cloudreve.zjh336.cn/s/zqqTe
此处为隐藏内容,请评论后查看隐藏内容,谢谢!
发表评论