[转帖]Mootools源码分析-41 -- Color

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-408885

原作者:我佛山人

 

代码
/*
关于颜色的知识,可以参考:
http://space.flash8.net/space/?18713/action_viewspace_itemid_385613.html
利用本类实现的颜色拾取器:
http://wfsr.net/widgets/colorpicker.html
更多颜色转换的代码库:
http://easyrgb.com/math.php?MATH=M21#text21
*/
//颜色的相关处理
var Color = new Native({

    
//构造函数,需要传两个参数
    //color为type参数指定格式下的颜色表示值
    initialize: function(color, type)    {
        
//如果参数个数在3个或以上,按rgb表示处理,前三个参数为颜色值
        if (arguments.length >= 3)    {
            type 
= "rgb"; color = Array.slice(arguments, 03);
            
//如果color参数为字符类型,转为RGB数组
        }    else if (typeof color == 'string')    {
            
//如果是rgb表示
            if (color.match(/rgb/))    color = color.rgbToHex().hexToRgb(true);
            
//如果是hsb表示
            else if (color.match(/hsb/)) color = color.hsbToRgb();
            
//如果是十六进制表示
            else color = color.hexToRgb(true);
        }
        
//颜色表示类型,默认为rgb
        type = type || 'rgb';
        
switch (type)    {
            
//如果是hsb表示
            case 'hsb':
                
var old = color;
                
//转为RGB数组
                color = color.hsbToRgb();
                color.hsb 
= old;
                
break;
            
//如果是十六进制表示
            case 'hex':
                color 
= color.hexToRgb(true);
                
break;
        }
        color.rgb 
= color.slice(03);
        color.hsb 
= color.hsb || color.rgbToHsb();
        color.hex 
= color.rgbToHex();
        
//返回扩展后的对象,其实类型是数组
        return $extend(color, this);
    }
});

//针对Color类的扩展实现
Color.implement({

    
//根据透明度混合多种颜色
    mix: function()    {
        
var colors = Array.slice(arguments);
        
//取透明度
        var alpha = ($type(colors.getLast()) == 'number'? colors.pop() : 50;
        
//取当前颜色的RGB数组表示
        var rgb = this.slice();
        
//遍历
        colors.each(function(color)    {
            
//解释当前项的颜色
            color = new Color(color);
            
//颜色混合算法,取当前颜色的补充透明度跟当前项颜色的透明度之和
            for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
        });
        
//返回混合之后的颜色对象
        return new Color(rgb, 'rgb');
    },

    
//颜色反转,对RGB各值分别取255的补
    invert: function()    {
        
return new Color(this.map(function(value)    {
            
//取补代替原值
            return 255 - value;
        }));
    },

    
//设置色调,HSB中的H值,取值从0-360
    setHue: function(value)    {
        
return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
    },

    
//设置饱和度,HSB中的S值,取值从0-100
    setSaturation: function(percent)    {
        
return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
    },

    
//设置亮度,HSB中的B值,取值从0-100
    setBrightness: function(percent)    {
        
return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
    }
});

//RGB方式创建Color实例的快捷方式
function $RGB(r, g, b)    {
    
return new Color([r, g, b], 'rgb');
};

//HSB方式创建Color实例的快捷方式
function $HSB(h, s, b)    {
    
return new Color([h, s, b], 'hsb');
};

//HEX方式创建Color实例的快捷方式
function $HEX(hex)    {
    
return new Color(hex, 'hex');
};

//根据Color类的需要,为Array添加的扩展实现
Array.implement({

    
//rgb转hsb算法
    rgbToHsb: function()    {
        
var red = this[0], green = this[1], blue = this[2];
        
var hue, saturation, brightness;
        
var max = Math.max(red, green, blue), min = Math.min(red, green, blue);
        
var delta = max - min;
        brightness 
= max / 255;
        saturation 
= (max != 0? delta / max : 0;
        
if (saturation == 0)    {
            hue 
= 0;
        }    
else    {
            
var rr = (max - red) / delta;
            
var gr = (max - green) / delta;
            
var br = (max - blue) / delta;
            
if (red == max) hue = br - gr;
            
else if (green == max)    hue = 2 + rr - br;
            
else    hue = 4 + gr - rr;
            hue 
/= 6;
            if (hue < 0)    hue++;
        }
        
return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
    },

    
//hsb转rgb算法
    hsbToRgb: function()    {
        
var br = Math.round(this[2/ 100 * 255);
        
if (this[1== 0)    {
            
return [br, br, br];
        }    
else    {
            
var hue = this[0% 360;
            
var f = hue % 60;
            
var p = Math.round((this[2* (100 - this[1])) / 10000 * 255);
            
var q = Math.round((this[2* (6000 - this[1* f)) / 600000 * 255);
            
var t = Math.round((this[2* (6000 - this[1* (60 - f))) / 600000 * 255);
            
switch (Math.floor(hue / 60))    {
                
case 0return [br, t, p];
                
case 1return [q, br, p];
                
case 2return [p, br, t];
                
case 3return [p, q, br];
                
case 4return [t, p, br];
                
case 5return [br, p, q];
            }
        }
        
return false;
    }
});

//根据Color类的需要,为String添加的扩展实现
String.implement({
//rgb转hsb
rgbToHsb: function()    {
    
var rgb = this.match(/\d{1,3}/g);
    
return (rgb) ? hsb.rgbToHsb() : null;
},
//hsb转rgb
hsbToRgb: function()    {
    
var hsb = this.match(/\d{1,3}/g);
    
return (hsb) ? hsb.hsbToRgb() : null;
}
});

 

posted @ 2009-12-01 11:26  webgis松鼠  阅读(259)  评论(0编辑  收藏  举报