package diomas.utils { /** * Color class manipulates RGB and HSV values * @author http://diomas.ru/ */ public class Color { private var _rgb:uint = 0xFF0000; private var _r:Number = 1.0; private var _g:Number = 0; private var _b:Number = 0; private var _h:Number = 0; private var _hRYB:Number = 0; private var _s:Number = 1; private var _v:Number = 1; /** * uint color representation */ public function get rgb():uint { if( isNaN( _r ) ) { calculateRGB(); } var _rbyte:uint = uint( _r * 255 ) << 16; var _gbyte:uint = uint( _g * 255 ) << 8; var _bbyte:uint = uint( _b * 255 ); _rgb = _rbyte + _gbyte + _bbyte; return _rgb; } public function set rgb( value:uint ):void { _r = ( value >> 16 ) / 255; _g = ( ( value && 0xFF00 ) >> 8 ) / 255; _b = ( value && 0xFF ) / 255; resetHSV(); } /** * Red component */ public function set red( value:Number ):void { _r = value; if ( _r < 0 ) _r = 0; if ( _r > 1 ) _r = 1; resetHSV(); } public function get red():Number { if( isNaN( _r ) ) { calculateRGB(); } return _r; } /** * Green component */ public function set green( value:Number ):void { _g = value; if ( _g < 0 ) _g = 0; if ( _g > 1 ) _g = 1; resetHSV(); } public function get green():Number { if( isNaN( _g ) ) { calculateRGB(); } return _g; } /** * Blue component */ public function set blue( value:Number ):void { _b = value; if ( _b < 0 ) _b = 0; if ( _b > 1 ) _b = 1; resetHSV(); } public function get blue():Number { if( isNaN( _b ) ) { calculateRGB(); } return _b; } /** * Hue component from 0.0 to 359.9999 */ public function set rgbHue( value:Number ):void { _h = value; while ( _h >= 360 ) _h -= 360; while ( _h < 0 ) _h += 360; _hRYB = ( _h < 60 ) ? _h * 2 : ( _h < 120 ) ? _h + 60 : ( _h < 240 ) ? _h * 0.5 + 180 : _h; resetRGB(); } public function get rgbHue():Number { // check for _s cause _h may have NaN value if( isNaN( _s ) ) { calculateHSV(); } return _h; } /** * Hue component from 0.0 to 359.9999 */ public function set rybHue( value:Number ):void { _hRYB = value; while( _hRYB >= 360 ) _hRYB -= 360; while ( _hRYB < 0 ) _hRYB += 360; _h = ( _hRYB < 120 ) ? _hRYB * 0.5 : ( _hRYB < 180 ) ? _hRYB - 60 : ( _hRYB < 240 ) ? ( _hRYB - 180 ) * 2 + 120 : _hRYB; resetRGB(); } public function get rybHue():Number { // check for _s cause _h may have NaN value if( isNaN( _s ) ) { calculateHSV(); } return _hRYB; } /** * Saturation component */ public function set saturation( value:Number ):void { _s = value; if ( _s < 0 ) _s = 0; if ( _s > 1 ) _s = 1; resetRGB(); } public function get saturation():Number { if( isNaN( _s ) ) { calculateHSV(); } return _s; } /** * Value component */ public function set value( value:Number ):void { _v = value; if ( _v < 0 ) _v = 0; if ( _v > 1 ) _v = 1; resetRGB(); } public function get value():Number { if( isNaN( _v ) ) { calculateHSV(); } return _v; } private function resetHSV():void { _h = NaN; _hRYB = NaN; _s = NaN; _v = NaN; } private function resetRGB():void { _r = NaN; _g = NaN; _b = NaN; _rgb = NaN; } private function calculateHSV():void { _v = Math.max( _r, _g, _b ); var min:Number = Math.min( _r, _g, _b ); _s = 0; _h = NaN; _hRYB = NaN; var k:Number = 1 / ( _v - min ); if( _v > 0 ) _s = 1 / ( _v * k ) ; if( _s > 0 ) { var cr:Number = ( _v - _r ) * k; var cg:Number = ( _v - _g ) * k; var cb:Number = ( _v - _b ) * k; if( _r == _v ) _h = cb - cg; if( _g == _v ) _h = 2 + cr - cb; if( _b == _v ) _h = 4 + cg - cr; _h *= 60; _hRYB = ( _h < 60 ) ? _h * 2 : ( _h < 120 ) ? _h + 60 : ( _h < 240 ) ? _h * 0.5 + 180 : _h; if( _h < 0 ) throw new Error( "H < 0!" ); } } private function calculateRGB():void { if( isNaN( _h ) ) { _r = _v; _g = _v; _b = _v; } else { var h6:Number = _h / 60; var hSect:int = Math.floor( h6 ); var f:Number = h6 - hSect; if( hSect % 2 == 0 ) f = 1 - f; var m:Number = _v * ( 1 - _s ); var n:Number = _v * ( 1 - _s * f ); if( hSect == 0 ) { _r = _v; _g = n; _b = m; } else if( hSect == 1 ) { _r = n; _g = _v; _b = m; } else if( hSect == 2 ) { _r = m; _g = _v; _b = n; } else if( hSect == 3 ) { _r = m; _g = n; _b = _v; } else if( hSect == 4 ) { _r = n; _g = m; _b = _v; } else // if( hSect == 5 ) { _r = _v; _g = m; _b = n; } } } } }