Bu cevap kendi canavarı oldu. Birçok yeni versiyon, aptallaşmaya başlamıştı. Bu cevaba katkıda bulunan çok sayıda herkese çok teşekkürler. Ama kitleler için basit tutmak için. Bu cevabın evriminin tüm versiyonlarını / geçmişini github'ım için arşivledim . Ve burada en yeni sürümle StackOverflow üzerinde temiz başladı. Bu sürüm için Mike 'Pomax' Kamermans'a özel bir teşekkürler . Bana yeni bir matematik verdi.
Bu işlev ( pSBC
) bir HEX veya RGB web rengi alacaktır. pSBC
daha koyu veya daha açık bir şekilde gölgeleyebilir veya ikinci bir renkle karıştırabilir ve aynı zamanda Hex'ten RGB'ye (Hex2RGB) veya RGB'den Hex'e (RGB2Hex) dönüştürebilir. Hangi renk formatını kullandığınızı bile bilmeden hepsi.
Bu, özellikle birçok özelliği göz önüne alındığında gerçekten hızlı, muhtemelen en hızlı çalışır. Yapımı uzun zaman aldı. Bütün hikayeyi github'ımda görün . Gölgelendirmek veya karıştırmak için mümkün olan en küçük ve en hızlı yolu istiyorsanız, aşağıdaki Mikro İşlevlere bakın ve 2 katmanlı hız iblislerinden birini kullanın. Yoğun animasyonlar için harikalar, ancak buradaki bu sürüm çoğu animasyon için yeterince hızlı.
Bu işlev Günlük Karıştırma veya Doğrusal Karıştırma kullanır. Bununla birlikte, bir rengi düzgün bir şekilde aydınlatmak veya koyulaştırmak için HSL'ye dönüşmez. Bu nedenle, bu işlevden elde edilen sonuçlar HSL kullanan çok daha büyük ve daha yavaş işlevlerden farklı olacaktır .
psBC ile jsFiddle
github> pSBC Wiki
Özellikleri:
- Standart Hex renklerini dizeler biçiminde otomatik olarak algılar ve kabul eder. Örneğin:
"#AA6622"
veya "#bb551144"
.
- Dizeler biçimindeki standart RGB renklerini otomatik olarak algılar ve kabul eder. Örneğin:
"rgb(123,45,76)"
veya "rgba(45,15,74,0.45)"
.
- Renkleri yüzde beyaz veya siyah olarak gölgeler.
- Renkleri yüzde olarak harmanlar.
- Hex2RGB ve RGB2Hex aynı anda mı, yoksa solo mu.
- #RGB (veya #RGBA) biçiminde 3 basamaklı (veya 4 basamaklı alfa) HEX renk kodlarını kabul eder. Onları genişletecek. Örneğin:
"#C41"
olur "#CC4411"
.
- Kabul eder ve (Doğrusal) alfa kanallarını karıştırır. Ya durumunda
c0
(arasından), renk ya da c1
(to) renk bir alfa kanalı, daha sonra dönen bir renk bir alfa kanalı olacaktır. Her iki renk de alfa kanalına sahipse, döndürülen renk, verilen yüzdeyi (tıpkı normal bir renk kanalı gibi) kullanarak iki alfa kanalının doğrusal bir karışımı olacaktır. İki renkten yalnızca birinin alfa kanalı varsa, bu alfa sadece döndürülen renge geçirilir. Bu, saydamlık seviyesini korurken saydam bir rengi karıştırmaya / gölgelemeye izin verir. Saydamlık düzeylerinin de karışması gerekiyorsa, her iki rengin de alfa olduğundan emin olun. Gölgelendirirken, alfa kanalını düz geçirir. Ayrıca alfa kanalı gölgelendirir temel gölgeleme isterseniz, o zaman kullanabilir rgb(0,0,0,1)
veya rgb(255,255,255,1)
senkronize ederc1
renk (veya onaltılık eşdeğerleri). RGB renkleri için, döndürülen rengin alfa kanalı 3 ondalık basamağa yuvarlanır.
- RGB2Hex ve Hex2RGB dönüşümleri, karıştırma kullanılırken örtüktür.
c0
Rengi ne olursa olsun ; döndürülen renk, varsa (daima c1
) rengin renk formatında olacaktır. c1
(To) rengi yoksa, renk 'c'
olarak c1
iletin ve c0
renk ne olursa olsun gölgede kalır ve dönüşür . Yalnızca dönüşüm isteniyorsa, 0
yüzde ( p
) olarak da iletin. Eğer c1
renk atlanırsa veya olmayan string
geçilen, bu dönüştürmek olmaz.
- Global'e de ikincil bir fonksiyon eklenir.
pSBCr
Hex veya RGB renginden geçirilebilir ve bu renk bilgisini içeren bir nesne döndürür. Bu, {r: XXX, g: XXX, b: XXX, a: X.XXX} biçimindedir. Nerede .r
, .g
ve .b
0 ila 255 aralığındadır. Ve alfa olmadığında: .a
-1'dir. Aksi takdirde: .a
0.000 ila 1.000 aralığındadır.
- RGB çıkış için, bu çıkışları
rgba()
üzerinde rgb()
bir alfa kanalı ile bir renk geçirildi zaman c0
ve / veya () c1
(to).
- Küçük Hata Kontrolü eklendi. Mükemmel değil. Hala çökebilir veya jibberish oluşturabilir. Ama bazı şeyleri yakalayacak. Temel olarak, yapı bazı şekillerde yanlışsa veya yüzde bir sayı veya kapsam dışı değilse, geri döner
null
. Bir örnek:, pSBC(0.5,"salt") == null
düşündüğü gibi #salt
geçerli bir renktir. return null;
Bu özelliği kaldırmak ve daha hızlı ve daha küçük yapmak için biten dört satırı silin .
- Günlük Karıştırma kullanır. Geçiş
true
için de l
Doğrusal Blending kullanmak (4 parametre).
Kod:
// 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)
}
Kullanımı:
// 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}
Aşağıdaki resim, iki karıştırma yöntemindeki farkı göstermeye yardımcı olacaktır:
Mikro Fonksiyonlar
Gerçekten hız ve boyut istiyorsanız, HEX yerine RGB kullanmanız gerekir. RGB daha basit ve basittir, HEX çok yavaş yazıyor ve basit bir iki astar için çok fazla lezzet içeriyor (IE. 3, 4, 6 veya 8 haneli HEX kodu olabilir). Ayrıca bazı özellikleri feda etmeniz gerekir, hata kontrolü, HEX2RGB veya RGB2HEX yoktur. Ayrıca, renk harmanlama matematiği için ve gölgelendirme veya karıştırma istiyorsanız, belirli bir işlev seçmeniz gerekecektir (aşağıdaki işlev adına göre). Bu işlevler alfa kanallarını destekler. Ve her iki giriş rengi de alfa içerdiğinde, bunları Doğrusal Karıştıracaktır. İki renkten yalnızca birinde alfa varsa, doğrudan ortaya çıkan renge doğru geçirir. Aşağıda inanılmaz derecede hızlı ve küçük olan iki astar işlevi bulunmaktadır:
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:")");
}
Daha fazla bilgi mi istiyorsunuz? Tam writeup oku github .
PT
(Ps Başka bir karıştırma yöntemi için matematik varsa, lütfen paylaşın.)