I'm trying to create some jQuery function that changes object bgcolor to lighter or darker (you set parameter as difference of tone of color). And as I think it should work, but it cracks.
$.fn.changeBg = function(difference){
var hexToRgb = function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
var rgbToHex = function(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
//returns color n-tones lighter or darker (for negavitve values) from given.
var changeColor = function(hex,tones){
var rgb = hexToRgb(hex);
rgb.r+=tones;
rgb.g+=tones;
rgb.b+=tones;
rgb.r=rgb.r>255?255:rgb.r;
rgb.r=rgb.r<0?0:rgb.r;
rgb.g=rgb.g>255?255:rgb.g;
rgb.g=rgb.g<0?0:rgb.g;
rgb.b=rgb.b>255?255:rgb.b;
rgb.b=rgb.b<0?0:rgb.b;
var hex = rgbToHex( rgb.r , rgb.g , rgb.b );
return hex;
}
var bgColor = $(this).css('background-color');
var secColor = changeColor(bgColor,difference);
$(this).css('background-color',secColor);
}
Fiddle - any idea what is wrong with that?
I'm trying to create some jQuery function that changes object bgcolor to lighter or darker (you set parameter as difference of tone of color). And as I think it should work, but it cracks.
$.fn.changeBg = function(difference){
var hexToRgb = function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
var rgbToHex = function(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
//returns color n-tones lighter or darker (for negavitve values) from given.
var changeColor = function(hex,tones){
var rgb = hexToRgb(hex);
rgb.r+=tones;
rgb.g+=tones;
rgb.b+=tones;
rgb.r=rgb.r>255?255:rgb.r;
rgb.r=rgb.r<0?0:rgb.r;
rgb.g=rgb.g>255?255:rgb.g;
rgb.g=rgb.g<0?0:rgb.g;
rgb.b=rgb.b>255?255:rgb.b;
rgb.b=rgb.b<0?0:rgb.b;
var hex = rgbToHex( rgb.r , rgb.g , rgb.b );
return hex;
}
var bgColor = $(this).css('background-color');
var secColor = changeColor(bgColor,difference);
$(this).css('background-color',secColor);
}
Fiddle - any idea what is wrong with that?
Share Improve this question asked Jan 25, 2013 at 21:52 KluskaKluska 453 silver badges7 bronze badges 2-
The javascript console has the answer ;) You may want to add
console.log(hex, result);
just after you're calling.exec()
. – Andreas Commented Jan 25, 2013 at 21:59 - Be nice to whoever will use this and pick a color space where there is a dedicate channel for the luminance, HSV, HSL, HSB, etc. – mmgp Commented Jan 28, 2013 at 2:45
4 Answers
Reset to default 2bgColor
isn't necessarily in #RRGBB
format, regardless of the original CSS. It could be any of:
- #RRGGBB
- #RGB
- rgb(R, G, B)
- rgba(R, G, B, A)
- name
And you would have to parse each of them.
It would be much easier if you could have the original colour in your JavaScript source somewhere in the right format.
I had a similar issue, which is why I was looking for a quick solution myself. Albeit, these solutions didn't meet my needs, so I did this:
const lighten = (color, lighten)=>{
const c = color.replace("#", "");
let rgb = [parseInt(c.substr(0, 2), 16), parseInt(c.substr(2, 2), 16), parseInt(c.substr(4, 2), 16)];
let returnstatement = "#";
rgb.forEach((color)=>{returnstatement+=Math.round(((255-color)*(1-Math.pow(Math.E, -lighten))+color)).toString(16)});
return returnstatement;
}
it takes a hex color code, and a lightening parameter. The color can't exceed #ffffff because of the negative exponential term, but sufficiently high values will get you there (where e^-lighten < 1/255, this is guaranteed).
negative values would cause it to darken, but the exponential safeguard doesn't work in that direction, they lead to a catastrophic failure rather quickly.
(from here on out, the code is not yet tested)
const darken = (color, darken)=>{
const c = color.replace("#", "");
let rgb = [parseInt(c.substr(0, 2), 16), parseInt(c.substr(2, 2), 16), parseInt(c.substr(4, 2), 16)];
let returnstatement = "#";
rgb.forEach((color)=>{returnstatement+=Math.round(color/(1-Math.pow(Math.E, -darken))).toString(16)});
return returnstatement;
}
if you bine them like this
const lightdark = (color, lparam)=>{
if(lparam>0){
return lighten(color, lparam);
}
return darken(color, lparam);
}
you will avoid the exponential catastrophe in both directions
finally, concerning colors, if you already are getting rgb, you might want tocheck if the color data is in an array, in which case you could
const parseColor = (color) => {
let rgb;
if (!Array.isArray(color)){
if(color.includes("#")||color.includes("0x")){
const c = color.replace("#", "").replace("0x", "");
rgb = [parseInt(c.substr(0, 2), 16), parseInt(c.substr(2, 2), 16), parseInt(c.substr(4, 2), 16)];
}else{
rgb=color.split(",").map((item)=>parseInt(item.trim()));
}
}
return rgb;
}
this code could be made more efficient overall, for sure. If you want to catch the possibility of it arriving as an object, like
color={r:0, b:0, g:0}
however the keys of the color object are named,
const rgb = Object.keys(color).map((key)=>color[key])
should make this case right, (just insert it in the parser with another else) since I haven't heard of any html colors being coded as cym
Well, my answer below doesn't use JQuery for anything. But it should work just fine as a JQuery function either way. As Niet the Dark Absol mentioned in his answer, the function below can parse the various types of color code, except the written names (like blue
). Unfortunately, this uses Linear interpolation and/or Log interpolation but not HSL. So its not 100% accurate, but pretty close. For this small inaccuracy we gain a lot of speed and a smaller size.
Programmatically Lighten or Darken a hex color (or rgb, and blend colors)
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)
}
Where p
is a float percentage from -1.0
to 1.0
and from
and to
are respectively the starting color and the ending color. And l
defaults to false
which is Log interpolation, if you want Linear interpolation pass true
in as l
.
This function can lighten, darken, blend and convert colors in these formats:
#RGB
#RRGGBB
#RGBA
#RRGGBBAA
rgb(R,G,B)
rgb(R,G,B,A)
Hex2RGB/RGB2Hex conversions are implicit. Check the link for more info and for other versions of this function. The main version has some Error Checking. Also there are versions without the Hex2RGB/RGB2Hex conversion; they are a bit smaller.
To use it the way that I think you want, do this:
var color1 = "rgb(114,93,20)";
var c2 = pSBC(0.3,color1); // rgb(114,93,20) + [30% Lighter] => rgb(156,142,91)
var c3 = pSBC(-0.13,"#F3A"); // #F3A + [13% Darker] => #de2c94
See link for more usage options. There are many.
PT
2023 answer, using ES6 and colorsea
import colorsea from "colorsea";
Assuming colorString
is color written as any type of CSS string.
const color = colorsea(colorString);
const darkerColor = color.darken(10);
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745194345a4616016.html
评论列表(0条)