RtoGtoB Test
/**
* Copyright esukei ( http://wonderfl.net/user/esukei )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vphY
*/
package {
import flash.display.Sprite;
import flash.events.Event;
public class FlashTest extends Sprite {
private var colorPalette:ColorPalette;
private var counter:Number = 0.0;
public function FlashTest() {
// write as3 code here..
colorPalette = new ColorPalette([0xff0000,0x00ff00,0x0000ff]);
addEventListener(Event.ENTER_FRAME, function(e:Event):void
{
if(counter > 1.0)
{
counter = 0.0;
}
var rnd:Number = Math.random();
graphics.clear();
graphics.beginFill(colorPalette.pick(rnd), 1.0);
graphics.drawRect(0,0,200,200);
graphics.endFill();
graphics.beginFill(colorPalette.pick(rnd,'hsv'), 1.0);
graphics.drawRect(250,0,200,200);
graphics.endFill();
graphics.beginFill(colorPalette.pick(counter), 1.0);
graphics.drawRect(0,250,200,200);
graphics.endFill();
graphics.beginFill(colorPalette.pick(counter,'hsv'), 1.0);
graphics.drawRect(250,250,200,200);
graphics.endFill();
counter += 0.01;
});
}
}
}
class ColorPalette {
static public const GRADIENT_RGB:String = 'rgb';
static public const GRADIENT_HSV:String = 'hsv';
private var colors:Array;
public function ColorPalette(colors:Array, isGradient:Boolean = true, isLoop:Boolean = true)
{
this.colors = colors;
if(isLoop)
{
this.colors.push(this.colors[0]);
}
}
private var tmpPointer:uint;
private var tmpRatio:Number;
public function pick(pointer:Number, mode:String = GRADIENT_RGB):uint
{
//trim 0.0 to 1.0
pointer = (pointer < 0) ? 0 : ((pointer > 1.0) ? 1.0 : pointer);
if(pointer == 0.0)
{
return colors[0];
}
else if(pointer == 1.0)
{
return colors[colors.length -1];
}
tmpPointer = uint((colors.length - 1) * pointer);
tmpRatio = ( pointer - tmpPointer / (colors.length - 1) ) / ((tmpPointer+1) / (colors.length-1) - (tmpPointer / (colors.length-1)));
if(mode == GRADIENT_RGB)
{
var rA:uint = (colors[tmpPointer] & 0xFF0000) >> 16;
var gA:uint = (colors[tmpPointer] & 0x00FF00) >> 8;
var bA:uint = (colors[tmpPointer] & 0x0000FF);
var rB:uint = (colors[tmpPointer+1] & 0xFF0000) >> 16;
var gB:uint = (colors[tmpPointer+1] & 0x00FF00) >> 8;
var bB:uint = (colors[tmpPointer+1] & 0x0000FF);
var rR:uint = uint(rA + (rB - rA) * tmpRatio);
var gR:uint = uint(gA + (gB - gA) * tmpRatio);
var bR:uint = uint(bA + (bB - bA) * tmpRatio);
return rR << 16 | gR << 8 | bR;
}
else(mode == GRADIENT_HSV)
{
var hsvA:HSV = HSVColor.RGBtoHSV(colors[tmpPointer]);
var hsvB:HSV = HSVColor.RGBtoHSV(colors[tmpPointer+1]);
var hT:Number = (Math.abs(hsvB.h - hsvA.h) < Math.abs(hsvB.h + 360.0 - hsvA.h)) ? (hsvB.h - hsvA.h) : (hsvB.h + 360.0 - hsvA.h);
var h:Number = hsvA.h + hT * tmpRatio;
var s:Number = hsvA.s + (hsvB.s - hsvA.s) * tmpRatio;
var v:Number = hsvA.v + (hsvB.v - hsvA.v) * tmpRatio;
return HSVColor.HSVtoRGB(h,s,v);
}
}
}
class HSVColor
{
public function HSVColor(){}
/**
* rgbを放り込むとhsvオブジェクトを返してくれるメソッド
* @param rgb:uint - RGB値
* @return hsv:Object(HSV) - h:Number,s:Number,v:Numberを含むObject(HSV)
*/
public static function RGBtoHSV(rgb:uint):HSV
{
//rgbを分解して0.0~1.0になるようにする
var r:Number = ( (rgb & 0xFF0000) >> 16 ) / 0xFF;
var g:Number = ( (rgb & 0x00FF00) >> 8 ) / 0xFF;
var b:Number = ( (rgb & 0x0000FF) ) / 0xFF;
//HSVオブジェクトを作る
var hsv:HSV = new HSV();
hsv.h = 0.0;
hsv.s = 0.0;
hsv.v = 0.0;
//RGBの各色の最大、最小をとる
var max:Number = Math.max(r, Math.max(g, b) );
var min:Number = Math.min(r, Math.min(g, b) );
//最大、最小によってhの求め方を変える
switch(max)
{
case r:
{
if(max - min == 0)
{
hsv.h = 0;
}
else
{
hsv.h = 60 * (g - b) / (max - min);
}
break;
}
case g:
{
hsv.h = 60 * (b - r) / (max - min) + 120;
break;
}
case b:
{
hsv.h = 60 * (r - g) / (max - min) + 240;
break;
}
default:
{
break;
}
}
//sとvを求める
if(max == 0.0)
{
hsv.s = 0.0;
}
else
{
hsv.s = (max - min) / max;
}
hsv.v = max;
return hsv;
}
/**
* h,s,vを放り込むとrgbを返してくれるメソッド
* @param h:Number - 色相のディグリー値 (0.0~360.0)
* @param s:Number - 彩度 (0.0~1.0)
* @param v:Number - 明度 (0.0~1.0)
* @return rgb:uint - RGB値
*/
public static function HSVtoRGB(h:Number, s:Number, v:Number):uint
{
var tmpR:uint = 0;
var tmpG:uint = 0;
var tmpB:uint = 0;
//0.0~360.0に丸める
h = (h % 360.0 + 360.0) % 360.0;
//0.0~1.0に丸める
s = Math.min( Math.max(s, 0.0) , 1.0);
v = Math.min( Math.max(v, 0.0) , 1.0);
//sが0.0の時はすべての値がvに等しい
if(s == 0.0)
{
tmpR = v * 255;
tmpG = v * 255;
tmpB = v * 255;
}
else
{
var hi:uint = (h / 60) % 6;
var f:Number = h / 60 - hi;
var p:Number = v * (1.0 - s);
var q:Number = v * (1.0 - f * s);
var t:Number = v * (1.0 - (1.0 - f) * s);
switch(hi)
{
case 0:
{
tmpR = v * 255;
tmpG = t * 255;
tmpB = p * 255;
break;
}
case 1:
{
tmpR = q * 255;
tmpG = v * 255;
tmpB = p * 255;
break;
}
case 2:
{
tmpR = p * 255;
tmpG = v * 255;
tmpB = t * 255;
break;
}
case 3:
{
tmpR = p * 255;
tmpG = q * 255;
tmpB = v * 255;
break;
}
case 4:
{
tmpR = t * 255;
tmpG = p * 255;
tmpB = v * 255;
break;
}
case 5:
{
tmpR = v * 255;
tmpG = p * 255;
tmpB = q * 255;
break;
}
default:
{
tmpR = 0;
tmpG = 0;
tmpB = 0;
break;
}
}
}
return tmpR << 16 | tmpG << 8 | tmpB;
}
}
//HSV型を作っておく
//Objectってクラスにする以外に中身に型指定って出来なかったっけ?
class HSV extends Object
{
public var h:Number;
public var s:Number;
public var v:Number;
function HSV(){}
}