最近用js做了个调色器, 功能和xp自带的调色器一样.
似乎CSDN博客不能跑JS,就发个干巴图上来,可以去alimama发布个广告位看看:).
做这个的过程我主要的工作就是上网查寻了色彩模式HSB(有的地方叫HSL)和RGB的转换算法
最终我找到了颜色方面的算法大全 http://www.easyrgb.com/math.php?MATH=M18#text18
老外还是有一套,这里有几乎所有颜色模式之间相互转换的代码XYZ,Yxy,Hunter-Lab,CIE-L*ab,CIE-L*CH°,CIE-L*uv,CMY,CMYk,HSV等等,基本上我都不知道是什么模式,那是另一门学问,
为什么要H(色调)S(饱和度)L(亮度)和R(红色)G(绿色)B(蓝色)的转换呢,因为如上图,x轴表示色调,y轴表示饱和度,阶梯则表示确定了色调和饱和度之后,不同亮度时我们得到的颜色.
所以找到了HSL到RGB的转换算法,其他拖拖拽拽,晃晃点点都是JavaScript的常用伎俩了.
这里也想到了另一个问题,取反色,或者取互补色,如何得到和一种颜色的反差最大的颜色.
网上一搜不知哪个天才设计的算法用rgb的每个255一减当前值得到差就是了,可不黑对白,白对黑岂知128算出的是127
关于这个问题easyrgb这个网站上有没有算法我还不知道,无奈英文太差
至少以HSL色彩模式来看待颜色取反时H和L会有比较清晰的思路
对于亮度0对1 0.5对0.5
对于色调它形成的是一个色环,只要在环上转180度即可
对于饱和度就比较麻烦了,饱和度很低的时候大家都灰不垃圾的,
所有最饱和的颜色的反色都是灰色看上去也比较荒唐
但无论怎样就当S值不变,HL取反得到的结果对于大多数颜色而言反差还是够大的,毕竟如果没有基于算法的颜色取反的定义,我们的需求一般只是要有一定的反差,避免字和底色太相近结果什么都看不清而已
最后突然一个想法,现在的框架是越来越多了,百家争鸣,万马奇谙,以后做些看来要不只要有个标签"跨浏览器"还要"跨前端框架"了,不然为了小东西你本来是jquery的,非要引入个dojo,岂不麻烦透了.呵呵
说白了就是纯JavaScript吧,各种框架把js打扮的越来越像java像perl.当然是好事
可到最后当我们还区分不开DOM和BOM,区分不开Arrry和window的时候,就已经跨越到区分不开prototype和prototype.js,不知道js有没有trim()的另一个层次了.是否也算一种悲哀.
附翻译成js的rgb<->hsl转换算法
rgb取值范围(0-255),hsl取值范围成(0-240)(和windows保持一致)
function rgb2hsl(rgb){
var hsl={};
var H,S,L;
var r = rgb.r/255;
var g = rgb.g/255;
var b = rgb.b/255;
var vmin = (r<((g<b)?g:b))?r:((g<b)?g:b);
var vmax = (r>((g>b)?g:b))?r:((g>b)?g:b);
var del = vmax-vmin;
var L = (vmax+vmin)/2;
if(del==0){
H = 0;
S = 0;
}else{
if(L<0.5){
S = del/(2*L)
}else{
S = del/(2-2*L)
}
dr = (((vmax-r)/6)+(del/2))/del;
dg = (((vmax-g)/6)+(del/2))/del;
db = (((vmax-b)/6)+(del/2))/del;
if(r==vmax){
H = db-dg;
}else if(g==vmax){
H = (1/3)+dr-db;
}else if(b==vmax){
H = (2/3)+dg-dr;
}
if(H<0)H+=1;
if(H>1)H-=1;
}
hsl.h = Math.round(H*240);
hsl.s = Math.round(S*240);
hsl.l = Math.round(L*240);
return hsl;
}
function hsl2rgb(hsl){
function h2rgb(v1,v2,vH){
if(vH<0)vH += 1;
if(vH>1)vH -= 1;
if((6*vH)<1)return(v1+(v2-v1)*6* vH );
if((2*vH)<1)return(v2);
if((3*vH)<2)return(v1+(v2-v1)*((2/3)-vH)*6);
return v1;
}
var rgb = {};
var H = hsl.h/240;
var S = hsl.s/240;
var L = hsl.l/240;
if(S==0){
rgb.r = Math.round(L*225);
rgb.g = Math.round(L*225);
rgb.b = Math.round(L*225);
}else{
var v1,v2;
if(L<0.5){
v2 = L*(1+S);
}else{
v2 = (L+S)-(S*L);
}
v1 = 2*L-v2;
rgb.r = Math.round(255*h2rgb(v1,v2,H+(1/3)));
rgb.g = Math.round(255*h2rgb(v1,v2,H));
rgb.b = Math.round(255*h2rgb(v1,v2,H-(1/3)));
}
return rgb;
}