js 让颜色变深或变浅,返回新的色值
需求:在实际开发中,如果我们想动态的将颜色变深或变浅,但是用rgba这种带透明度的话,碰到定位的样式,则内容会重叠显示,所以有没有一种方法可以直接改变他的色值而不是用透明度
思路:通过访阅大量方法后,得知一种hsl色彩模式,更加符合我们的要求,hsl一种更以人们理解的色彩模式
废话不说上代码,直接运行便可看到效果,我对这个方法做了高度封装,所以使用起来更顺手,相应的解释也在代码中体现
辛辛苦苦很长时间,也否决了很多方案,做了不少优化,也是借鉴了不少网上的代码,所以可以随意使用,但不希望作为知识付费产物
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="https://cdn.bootcdn.net/ajax/libs/mathjs/11.7.0/math.js"></script> <style> #aa{ width: 200px; height: 200px; } #bb{ width: 200px; height: 200px; } </style> </head> <body> <div id="aa">aa</div> <div id="bb">bb</div> <script> /** * hsl模式:分为了3个部分,色值(360度圆形的方式呈现),饱和度(100),明度(100),我们就是改变明度 * 思路,将rgb转成hsl模式,通过hsl模式将颜色变浅,然后在转成rgb方式 * color 传递的颜色,支持rgb与十六进制(可以不带#)的字符串,rgba将自动转成rgb,如果想在rgba的基础上变色,请调两次函数 * opacity 阈值:0-100 -》 0 最暗(黑色) 100 最亮(白色) * 返回值:如果是rgb则返回处理后的rgb,如果是十六进制则返回处理后的十六进制 */ function colorutils(color, opacity){ // 将rgb或者十六进制颜色统一转成hsl模式 function allhsl(color){ // 首先对颜色判断,如果是rgb则走rgb模式,因为#号是特殊字符,网址传参都有限制,所以不判断# if(color.indexOf('rgb') != -1){ var start = color.indexOf('(')+1; var startval = color.substr(color.indexOf('(')+1) var end = startval.indexOf(')'); var val = startval.substr(0, end) var colorarr = val.split(","); return rgbtohsl(colorarr[0],colorarr[1],colorarr[2]) } else { return colorToRgb(color); } } // 然后就是转化成处理后的颜色 如果传rgb就返rgb模式,如果是十六进制就返十六进制 function resultRgb(color, opacity){ var arr = allhsl(color); var result = hsltorgb(arr[0], arr[1], opacity); if(color.indexOf('rgb') != -1){ return "rgb("+result[0]+","+result[1]+","+result[2]+")"; } else { return colorToHex(result); } } // 将十六进制转成rgb function colorToRgb(color){ if(color.indexOf("#") != -1){ color = color.replace("#", "", color) } var color1 = parseInt(color.substr(0, 2), 16); var color2 = parseInt(color.substr(2, 2), 16); var color3 = parseInt(color.substr(4, 2), 16); var str = "rgb("+color1+","+color2+","+color3+")"; console.log(str) return rgbtohsl(color1, color2, color3); } // 将rgb转成hsl模式 function rgbtohsl(r,g,b){ r=math.divide(r, 255); g=math.divide(g, 255); b=math.divide(b, 255); var min=Math.min(r,g,b); var max=Math.max(r,g,b); var l= math.divide(math.add(min,max), 2); var difference = math.subtract(max, min); var h,s,l; if(max==min){ h=0; s=0; }else{ s=l>0.5? math.divide(difference, math.subtract(math.subtract(2.0, max), min)) : math.divide(difference, math.add(max,min)); switch(max){ case r: h= math.add(math.divide(math.subtract(g, b), difference), (g < b ? 6 : 0));break; case g: h=math.add(2.0, math.divide(math.subtract(b, r), difference));break; case b: h=math.add(4.0, math.divide(math.subtract(r, g), difference));break; } h=Math.round(math.multiply(h, 60)); } s=Math.round(math.multiply(s, 100));//转换成百分比的形式 l=Math.round(math.multiply(l, 100)); return [h,s,l]; } // 将hsl模式转成rgb function hsltorgb(h,s,l){ var h=math.divide(h, 360); var s=math.divide(s, 100); var l=math.divide(l, 100); var rgb=[]; if(s==0){ rgb=[Math.round(math.multiply(l, 255)),Math.round(math.multiply(l, 255)),Math.round(math.multiply(l, 255))]; }else{ var q=l>=0.5?math.subtract(math.add(l, s), math.multiply(l, s)):math.multiply(l, math.add(1, s)); var p=math.subtract(math.multiply(2, l), q); var tr=rgb[0]=math.add(h, math.divide(1, 3)); var tg=rgb[1]=h; var tb=rgb[2]=math.subtract(h, math.divide(1, 3)); for(var i=0; i<rgb.length;i++){ var tc=rgb[i]; if(tc<0){ tc=math.add(tc, 1); }else if(tc>1){ tc=math.subtract(tc, 1); } switch(true){ case (tc<math.divide(1, 6)): tc=math.add(p, math.multiply(math.multiply(math.subtract(q, p), 6), tc)); break; case (math.divide(1, 6)<=tc && tc<0.5): tc=q; break; case (0.5<=tc && tc<math.divide(2, 3)): tc=math.add(p, math.multiply(math.subtract(q, p), math.subtract(4, math.multiply(6, tc)))); break; default: tc=p; break; } rgb[i]=Math.round(math.multiply(tc, 255)); } } return rgb; } // rgb转十六进制 color 为[r,b,g]的格式 function colorToHex(color){ function componentToHex(c) { var hex = c.toString(16); return hex.length == 1 ? "0" + hex : hex; } return "#" + componentToHex(color[0]) + componentToHex(color[1]) + componentToHex(color[2]); } return resultRgb(color, opacity) } var strcolor = "rgb(0,102,0)"; aa.style.background=strcolor; bb.style.background = colorutils(strcolor, 80); </script> </body> </html>