Eh bien, cette réponse est devenue sa propre bête. Beaucoup de nouvelles versions, ça devenait stupide depuis longtemps. Un grand merci à tous les très nombreux contributeurs à cette réponse. Mais, afin de rester simple pour les masses. J'ai archivé toutes les versions / l'historique de l'évolution de cette réponse sur mon github . Et j'ai tout recommencé sur StackOverflow ici avec la dernière version. Un merci spécial à Mike «Pomax» Kamermans pour cette version. Il m'a donné le nouveau calcul.
Cette fonction ( pSBC
) prendra une couleur Web HEX ou RVB. pSBC
peut l'ombrer plus sombre ou plus clair, ou le mélanger avec une deuxième couleur, et peut également le passer à travers mais convertir de Hex en RGB (Hex2RGB) ou RGB en Hex (RGB2Hex). Le tout sans même savoir quel format de couleur vous utilisez.
Cela fonctionne très rapidement, probablement le plus rapide, surtout compte tenu de ses nombreuses fonctionnalités. Cela a pris beaucoup de temps. Voir toute l'histoire sur mon github . Si vous voulez le moyen le plus petit et le plus rapide possible de teinter ou de mélanger, consultez les Micro Fonctions ci-dessous et utilisez l'un des démons de vitesse à 2 lignes. Ils sont parfaits pour les animations intenses, mais cette version ici est assez rapide pour la plupart des animations.
Cette fonction utilise le mélange de journaux ou le mélange linéaire. Cependant, il ne se convertit PAS en HSL pour éclaircir ou assombrir correctement une couleur. Par conséquent, les résultats de cette fonction seront différents de ceux des fonctions beaucoup plus grandes et beaucoup plus lentes qui utilisent HSL.
jsFiddle avec pSBC
github> pSBC Wiki
Fonctionnalités:
- Détecte et accepte automatiquement les couleurs Hex standard sous forme de chaînes. Par exemple:
"#AA6622"
ou "#bb551144"
.
- Détecte automatiquement et accepte les couleurs RVB standard sous forme de chaînes. Par exemple:
"rgb(123,45,76)"
ou "rgba(45,15,74,0.45)"
.
- Nuances de couleurs au blanc ou au noir en pourcentage.
- Mélange les couleurs ensemble en pourcentage.
- Fait la conversion Hex2RGB et RGB2Hex en même temps ou en solo.
- Accepte les codes de couleur HEX à 3 chiffres (ou 4 chiffres avec alpha) sous la forme #RGB (ou #RGBA). Cela les élargira. Par exemple:
"#C41"
devient "#CC4411"
.
- Accepte et (linéaire) mélange les canaux alpha. Si la
c0
couleur (de) ou la couleur c1
(de) a un canal alpha, alors la couleur renvoyée aura un canal alpha. Si les deux couleurs ont un canal alpha, la couleur renvoyée sera un mélange linéaire des deux canaux alpha en utilisant le pourcentage donné (comme s'il s'agissait d'un canal de couleur normal). Si une seule des deux couleurs a un canal alpha, cet alpha sera simplement transmis à la couleur retournée. Cela permet de mélanger / ombrer une couleur transparente tout en maintenant le niveau de transparence. Ou, si les niveaux de transparence doivent également se fondre, assurez-vous que les deux couleurs ont des alphas. Lors de l'ombrage, il passera directement par le canal alpha. Si vous voulez un ombrage de base qui ombrage également le canal alpha, utilisez rgb(0,0,0,1)
ou rgb(255,255,255,1)
commec1
(à) couleur (ou leurs équivalents hexadécimaux). Pour les couleurs RVB, le canal alpha de la couleur renvoyée sera arrondi à 3 décimales.
- Les conversions RGB2Hex et Hex2RGB sont implicites lors de l'utilisation du mélange. Quelle que soit la
c0
couleur (de); la couleur renvoyée sera toujours au format de couleur de la couleur c1
(à), s'il en existe une. S'il n'y a pas de c1
(à) couleur, alors passez 'c'
comme c1
couleur et il nuancera et convertira quelle que soit la c0
couleur. Si seule la conversion est souhaitée, transmettez 0
également le pourcentage ( p
). Si la c1
couleur est omise ou si un non string
est transmis, il ne sera pas converti.
- Une fonction secondaire est également ajoutée au global.
pSBCr
peut être passé une couleur hexadécimale ou RVB et il renvoie un objet contenant ces informations de couleur. Il se présente sous la forme: {r: XXX, g: XXX, b: XXX, a: X.XXX}. Où .r
, .g
et .b
ont une plage de 0 à 255. Et quand il n'y a pas d'alpha: .a
est -1. Autrement:.a
a une plage de 0,000 à 1.000.
- Pour une sortie RVB, il émet en sortie
rgba()
sur rgb()
lorsqu'une couleur avec un canal alpha a été passé dans c0
(de) et / ouc1
(à).
- La vérification des erreurs mineures a été ajoutée. Ce n'est pas parfait. Il peut encore planter ou créer du charabia. Mais ça va attraper des trucs. Fondamentalement, si la structure est incorrecte à certains égards ou si le pourcentage n'est pas un nombre ou hors de portée, il reviendra
null
. Un exemple:, pSBC(0.5,"salt") == null
où comme il le pense #salt
est une couleur valide. Supprimez les quatre lignes qui se terminent par return null;
pour supprimer cette fonction et la rendre plus rapide et plus petite.
- Utilise le mélange de journaux. Passez
true
pour l
(le 4ème paramètre) pour utiliser le mélange linéaire.
Code:
// 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)
}
Usage:
// 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}
L'image ci-dessous aidera à montrer la différence entre les deux méthodes de mélange:
Micro fonctions
Si vous voulez vraiment de la vitesse et de la taille, vous devrez utiliser RGB et non HEX. RVB est plus simple et plus simple, HEX écrit trop lentement et se décline en trop de saveurs pour un simple deux lignes (IE. Il pourrait s'agir d'un code HEX à 3, 4, 6 ou 8 chiffres). Vous devrez également sacrifier certaines fonctionnalités, pas de vérification d'erreur, ni HEX2RGB ni RGB2HEX. De plus, vous devrez choisir une fonction spécifique (en fonction de son nom de fonction ci-dessous) pour les calculs de mélange de couleurs, et si vous souhaitez un ombrage ou un mélange. Ces fonctions prennent en charge les canaux alpha. Et lorsque les deux couleurs d'entrée ont des alphas, Linear les mélange. Si une seule des deux couleurs a un alpha, il la transmettra directement à la couleur résultante. Voici deux fonctions de revêtement incroyablement rapides et petites:
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:")");
}
Vous voulez plus d'informations? Lisez l'intégralité du texte sur github .
PT
(Ps Si quelqu'un a le calcul pour une autre méthode de mélange, veuillez partager.)