这是我正在使用的功能,用于以编程方式使十六进制颜色变亮或变暗特定数量。只需传入一个"3F6D2A"颜色字符串(col)和一个amt以10为底的整数()来表示要变亮或变暗的数量。要变暗,请输入负数(即-20)。
"3F6D2A"
col
amt
-20
我这样做的原因是因为我找到了所有解决方案,到目前为止,它们似乎使问题变得过于复杂。我觉得只需几行代码就可以完成。如果您发现任何问题或进行任何调整以加快速度,请告诉我。
function LightenDarkenColor(col, amt) { col = parseInt(col, 16); return (((col & 0x0000FF) + amt) | ((((col >> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16); } // TEST console.log( LightenDarkenColor("3F6D2A",40) );
对于开发使用,这里是一个易于阅读的版本:
function LightenDarkenColor(col, amt) { var num = parseInt(col, 16); var r = (num >> 16) + amt; var b = ((num >> 8) & 0x00FF) + amt; var g = (num & 0x0000FF) + amt; var newColor = g | (b << 8) | (r << 16); return newColor.toString(16); } // TEST console.log(LightenDarkenColor("3F6D2A", -40));
最后是处理可能(或可能没有)开头带有“#”的颜色的版本。加上调整不正确的颜色值:
function LightenDarkenColor(col,amt) { var usePound = false; if ( col[0] == "#" ) { col = col.slice(1); usePound = true; } var num = parseInt(col,16); var r = (num >> 16) + amt; if ( r > 255 ) r = 255; else if (r < 0) r = 0; var b = ((num >> 8) & 0x00FF) + amt; if ( b > 255 ) b = 255; else if (b < 0) b = 0; var g = (num & 0x0000FF) + amt; if ( g > 255 ) g = 255; else if ( g < 0 ) g = 0; return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16); }
好的,所以现在它不仅是几行,而且看起来要简单得多,如果您不使用“#”并且不需要检查颜色是否超出范围,则只需几行。
如果不使用“#”,则可以将其添加到以下代码中:
var myColor = "3F6D2A"; myColor = LightenDarkenColor(myColor,10); thePlaceTheColorIsUsed = ("#" + myColor);
我想我的主要问题是,我在这里正确吗?这不包括某些(正常)情况吗?
此功能(pSBC)将采用十六进制或RGB网页颜色。pSBC可以将其变暗或变亮,或将其与第二种颜色混合,也可以将其直接传递但从十六进制转换为RGB(Hex2RGB)或从RGB转换为十六进制(RGB2Hex)。所有这些甚至都不知道您使用的是哪种颜色格式。
pSBC
这运行得非常快,可能是最快的,特别是考虑到它的许多功能。制作时间很长。在我的github上查看整个故事。如果要使用绝对最小和最快的方式来着色或混合,请参阅下面的“微功能”并使用2线速度恶魔之一。它们非常适合用于激烈的动画,但是此处的此版本对于大多数动画而言足够快。
此功能使用对数混合或线性混合。但是,它不能转换为HSL来适当地使颜色变暗或变暗。因此, 此函数的结果将不同于 使用HSL的更大,更慢的函数。
jsFiddle与pSBC github> pSBC维基
jsFiddle与pSBC
github> pSBC维基
特征:
"#AA6622"
"#bb551144"
"rgb(123,45,76)"
"rgba(45,15,74,0.45)"
"#C41"
"#CC4411"
c0
c1
rgb(0,0,0,1)
rgb(255,255,255,1)
'c'
0
p
string
pSBCr
.r
.g
.b
.a
rgba()
rgb()
null
pSBC(0.5,"salt") == null
#salt
return null;
true
l
// Version 4.0 const pSBC=(p,c0,c1,l)=>{ let r,g,b,P,f,t,h,i=parseInt,m=Math.round,a=typeof(c1)=="string"; if(typeof(p)!="number"||p<-1||p>1||typeof(c0)!="string"||(c0[0]!='r'&&c0[0]!='#')||(c1&&!a))return null; if(!this.pSBCr)this.pSBCr=(d)=>{ let n=d.length,x={}; if(n>9){ [r,g,b,a]=d=d.split(","),n=d.length; if(n<3||n>4)return null; x.r=i(r[3]=="a"?r.slice(5):r.slice(4)),x.g=i(g),x.b=i(b),x.a=a?parseFloat(a):-1 }else{ if(n==8||n==6||n<4)return null; if(n<6)d="#"+d[1]+d[1]+d[2]+d[2]+d[3]+d[3]+(n>4?d[4]+d[4]:""); d=i(d.slice(1),16); if(n==9||n==5)x.r=d>>24&255,x.g=d>>16&255,x.b=d>>8&255,x.a=m((d&255)/0.255)/1000; else x.r=d>>16,x.g=d>>8&255,x.b=d&255,x.a=-1 }return x}; h=c0.length>9,h=a?c1.length>9?true:c1=="c"?!h:false:h,f=this.pSBCr(c0),P=p<0,t=c1&&c1!="c"?this.pSBCr(c1):P?{r:0,g:0,b:0,a:-1}:{r:255,g:255,b:255,a:-1},p=P?p*-1:p,P=1-p; if(!f||!t)return null; if(l)r=m(P*f.r+p*t.r),g=m(P*f.g+p*t.g),b=m(P*f.b+p*t.b); else r=m((P*f.r**2+p*t.r**2)**0.5),g=m((P*f.g**2+p*t.g**2)**0.5),b=m((P*f.b**2+p*t.b**2)**0.5); a=f.a,t=t.a,f=a>=0||t>=0,a=f?a<0?t:t<0?a:a*P+t*p:0; if(h)return"rgb"+(f?"a(":"(")+r+","+g+","+b+(f?","+m(a*1000)/1000:"")+")"; else return"#"+(4294967296+r*16777216+g*65536+b*256+(f?m(a*255):0)).toString(16).slice(1,f?undefined:-2) }
// Setup: let color1 = "rgb(20,60,200)"; let color2 = "rgba(20,60,200,0.67423)"; let color3 = "#67DAF0"; let color4 = "#5567DAF0"; let color5 = "#F3A"; let color6 = "#F3A9"; let color7 = "rgb(200,60,20)"; let color8 = "rgba(200,60,20,0.98631)"; // Tests: /*** Log Blending ***/ // Shade (Lighten or Darken) pSBC ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(166,171,225) pSBC ( -0.4, color5 ); // #F3A + [40% Darker] => #c62884 pSBC ( 0.42, color8 ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(225,171,166,0.98631) // Shade with Conversion (use "c" as your "to" color) pSBC ( 0.42, color2, "c" ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #a6abe1ac // RGB2Hex & Hex2RGB Conversion Only (set percentage to zero) pSBC ( 0, color6, "c" ); // #F3A9 + [Convert] => rgba(255,51,170,0.6) // Blending pSBC ( -0.5, color2, color8 ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(142,60,142,0.83) pSBC ( 0.7, color2, color7 ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(168,60,111,0.67423) pSBC ( 0.25, color3, color7 ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(134,191,208) pSBC ( 0.75, color7, color3 ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #86bfd0 /*** Linear Blending ***/ // Shade (Lighten or Darken) pSBC ( 0.42, color1, false, true ); // rgb(20,60,200) + [42% Lighter] => rgb(119,142,223) pSBC ( -0.4, color5, false, true ); // #F3A + [40% Darker] => #991f66 pSBC ( 0.42, color8, false, true ); // rgba(200,60,20,0.98631) + [42% Lighter] => rgba(223,142,119,0.98631) // Shade with Conversion (use "c" as your "to" color) pSBC ( 0.42, color2, "c", true ); // rgba(20,60,200,0.67423) + [42% Lighter] + [Convert] => #778edfac // RGB2Hex & Hex2RGB Conversion Only (set percentage to zero) pSBC ( 0, color6, "c", true ); // #F3A9 + [Convert] => rgba(255,51,170,0.6) // Blending pSBC ( -0.5, color2, color8, true ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.83) pSBC ( 0.7, color2, color7, true ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423) pSBC ( 0.25, color3, color7, true ); // #67DAF0 + rgb(200,60,20) + [25% Blend] => rgb(127,179,185) pSBC ( 0.75, color7, color3, true ); // rgb(200,60,20) + #67DAF0 + [75% Blend] => #7fb3b9 /*** Other Stuff ***/ // Error Checking pSBC ( 0.42, "#FFBAA" ); // #FFBAA + [42% Lighter] => null (Invalid Input Color) pSBC ( 42, color1, color5 ); // rgb(20,60,200) + #F3A + [4200% Blend] => null (Invalid Percentage Range) pSBC ( 0.42, {} ); // [object Object] + [42% Lighter] => null (Strings Only for Color) pSBC ( "42", color1 ); // rgb(20,60,200) + ["42"] => null (Numbers Only for Percentage) pSBC ( 0.42, "salt" ); // salt + [42% Lighter] => null (A Little Salt is No Good...) // Error Check Fails (Some Errors are not Caught) pSBC ( 0.42, "#salt" ); // #salt + [42% Lighter] => #a5a5a500 (...and a Pound of Salt is Jibberish) // Ripping pSBCr ( color4 ); // #5567DAF0 + [Rip] => [object Object] => {'r':85,'g':103,'b':218,'a':0.941}
下图将帮助显示两种混合方法的区别:
如果您确实想要速度和大小,则必须使用RGB而不是HEX。RGB更直接,更简单,HEX写入速度太慢,并且对于简单的两行代码(IE。可能是3、4、6或8位数的HEX代码)有太多的风格。您还需要牺牲一些功能,没有错误检查,没有HEX2RGB或RGB2HEX。同样,您将需要选择一个特定的功能(基于下面的功能名称)用于颜色混合数学,以及是否要着色或混合。这些功能确实支持Alpha通道。并且当两种输入颜色都具有Alpha时,它将线性混合它们。如果两种颜色中只有一种具有alpha值,它将直接将其直接传递给所得颜色。以下是两个非常快而又小巧的班轮功能:
const RGB_Linear_Blend=(p,c0,c1)=>{ var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,j=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")"; return"rgb"+(x?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+i(e[3]=="a"?e.slice(5):e.slice(4))*p)+","+r(i(b)*P+i(f)*p)+","+r(i(c)*P+i(g)*p)+j; } const RGB_Linear_Shade=(p,c)=>{ var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:255*p,P=P?1+p:1-p; return"rgb"+(d?"a(":"(")+r(i(a[3]=="a"?a.slice(5):a.slice(4))*P+t)+","+r(i(b)*P+t)+","+r(i(c)*P+t)+(d?","+d:")"); } const RGB_Log_Blend=(p,c0,c1)=>{ var i=parseInt,r=Math.round,P=1-p,[a,b,c,d]=c0.split(","),[e,f,g,h]=c1.split(","),x=d||h,j=x?","+(!d?h:!h?d:r((parseFloat(d)*P+parseFloat(h)*p)*1000)/1000+")"):")"; return"rgb"+(x?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+p*i(e[3]=="a"?e.slice(5):e.slice(4))**2)**0.5)+","+r((P*i(b)**2+p*i(f)**2)**0.5)+","+r((P*i(c)**2+p*i(g)**2)**0.5)+j; } const RGB_Log_Shade=(p,c)=>{ var i=parseInt,r=Math.round,[a,b,c,d]=c.split(","),P=p<0,t=P?0:p*255**2,P=P?1+p:1-p; return"rgb"+(d?"a(":"(")+r((P*i(a[3]=="a"?a.slice(5):a.slice(4))**2+t)**0.5)+","+r((P*i(b)**2+t)**0.5)+","+r((P*i(c)**2+t)**0.5)+(d?","+d:")"); }
需要更多信息吗?阅读github上的完整文章。
PT
(请注意,如果有人对另一种混合方法有所了解,请分享。)