HLS ⇔ RGB ⇔ HSV
♥4 |
Line 197 |
Modified 2010-03-15 03:27:11 |
MIT License
archived:2017-03-08 13:02:57
ActionScript3 source code
/**
* Copyright matacat ( http://wonderfl.net/user/matacat )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/dtn8
*/
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"
applicationComplete="slideChanged()">
<mx:Script><![CDATA[
private var rgb:uint;
private var h:Number = 0;
private var l:Number = 0.5;
private var s:Number = 1;
private var v:Number = 1;
private function slideChanged():void
{
if (tabNav.selectedIndex == 0) hls2rgb();
else hsv2rgb();
colorWindow.setStyle("backgroundColor", rgb);
var colorText:String = rgb.toString(16).toUpperCase();
for (var i:int = colorText.length; i < 6; i++) colorText = "0" + colorText;
colorValue.text = "0x" + colorText;
}
private function tabChanged(index:Number):void
{
if (index == 0) {
rgb2hls();
hlsHue.value = hsvHue.value;
hlsLum.value = l;
hlsSat.value = s;
} else {
rgb2hsv();
hsvHue.value = hlsHue.value;
hsvSat.value = s;
hsvVal.value = v;
}
}
private function hsv2rgb():void
{
s = s > 1 ? 1 : (s < 0 ? 0 : s);
v = v > 1 ? 1 : (v < 0 ? 0 : v);
if (s == 0) { // gray scale
rgb = 0xFF * v << 16 | 0xFF * v << 8 | 0xFF * v << 0;
return;
}
h = h >= 360 ? h % 360 : (h < 0 ? h % 360 + 360 : h);
var i:int = int(h / 60);
var f:Number = h / 60 - i;
var p:Number = v * (1 - s);
var q:Number = v * (1 - s * f);
var t:Number = v * (1 - s * (1 - f));
switch (i) {
case 0: rgb = 0xFF * v << 16 | 0xFF * t << 8 | 0xFF * p << 0; break;
case 1: rgb = 0xFF * q << 16 | 0xFF * v << 8 | 0xFF * p << 0; break;
case 2: rgb = 0xFF * p << 16 | 0xFF * v << 8 | 0xFF * t << 0; break;
case 3: rgb = 0xFF * p << 16 | 0xFF * q << 8 | 0xFF * v << 0; break;
case 4: rgb = 0xFF * t << 16 | 0xFF * p << 8 | 0xFF * v << 0; break;
case 5: rgb = 0xFF * v << 16 | 0xFF * p << 8 | 0xFF * q << 0;
}
}
private function rgb2hsv():void
{
var c:Vector.<uint> = Vector.<uint>([ rgb >> 16 & 0xFF, rgb >> 8 & 0xFF, rgb & 0xFF ]);
if (c[0] == c[1] && c[0] == c[2]) { // gray scale
h = 0;
s = 0;
v = c[0] / 255;
return;
}
var max:int, min:int;
if (c[0] > c[1]) { // R > G
if (c[1] > c[2]) { max = 0; min = 2; } // R > G > B
else if (c[2] > c[0]) { max = 2; min = 1; } // B > R > G
else { max = 0; min = 1; } // R >=B>= G
} else { // G > = R
if (c[2] > c[1]) { max = 2; min = 0; } // B > G > = R
else if (c[0] > c[2]) { max = 1; min = 2; } // G > = R > B
else { max = 1; min = 0; } // G >=B>= R
}
v = c[max] / 255;
s = (c[max] - c[min]) / c[max];
switch (max) {
case 0:
h = 60 * (c[1] - c[2]) / (c[max] - c[min]) ; break;
case 1:
h = 60 * (c[2] - c[0]) / (c[max] - c[min]) + 120; break;
case 2:
h = 60 * (c[0] - c[1]) / (c[max] - c[min]) + 240;
}
if (h < 0) h += 360;
}
private function hls2rgb():void
{
l = l > 1 ? 1 : (l < 0 ? 0 : l);
s = s > 1 ? 1 : (s < 0 ? 0 : s);
if (s == 0) { // gray scale
rgb = 0xFF * l << 16 | 0xFF * l << 8 | 0xFF * l << 0;
return;
}
var max:Number, min:Number;
if (l <= 0.5) max = l * (1 + s);
else max = l * (1 - s) + s;
min = 2 * l - max;
rgb = 0xFF * c(h + 120) << 16 | 0xFF * c(h) << 8 | 0xFF * c(h - 120) << 0;
function c(d:Number):Number
{
d = d >= 360 ? d % 360 : (d < 0 ? d % 360 + 360 : d);
if (d < 60) return min + (max - min) * d / 60;
else if (d < 180) return max;
else if (d < 240) return min + (max - min) * (240 - d) / 60;
else return min;
}
}
private function rgb2hls():void
{
var c:Vector.<uint> = Vector.<uint>([ rgb >> 16 & 0xFF, rgb >> 8 & 0xFF, rgb & 0xFF ]);
if (c[0] == c[1] && c[0] == c[2]) { // gray scale
h = 0;
l = c[0] / 255;
s = 0;
return;
}
var max:int, min:int;
if (c[0] > c[1]) { // R > G
if (c[1] > c[2]) { max = 0; min = 2; } // R > G > B
else if (c[2] > c[0]) { max = 2; min = 1; } // B > R > G
else { max = 0; min = 1; } // R >=B>= G
} else { // G > = R
if (c[2] > c[1]) { max = 2; min = 0; } // B > G > = R
else if (c[0] > c[2]) { max = 1; min = 2; } // G > = R > B
else { max = 1; min = 0; } // G >=B>= R
}
l = (c[max] + c[min]) / 510; // (max + min) / (2 * 0xFF)
if (l <= 0.5) s = (c[max] - c[min]) / (c[max] + c[min]) ;
else s = (c[max] - c[min]) / (510 - (c[max] + c[min]));
switch (max) {
case 0:
h = 60 * (c[1] - c[2]) / (c[max] - c[min]) ; break;
case 1:
h = 60 * (c[2] - c[0]) / (c[max] - c[min]) + 120; break;
case 2:
h = 60 * (c[0] - c[1]) / (c[max] - c[min]) + 240;
}
if (h < 0) h += 360;
}
]]></mx:Script>
<mx:Panel title="GetColor" layout="horizontal" verticalAlign="middle"
paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5">
<mx:VBox horizontalAlign="center">
<mx:Box id="colorWindow" width="70" height="60" borderStyle="outset" />
<mx:Text id="colorValue" width="70" fontSize="12" />
</mx:VBox>
<mx:TabNavigator id="tabNav" creationPolicy="all" resizeToContent="true"
change="tabChanged(event.newIndex)">
<mx:VBox label="HLS" paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5">
<Hslns id="hlsHue" title="H:" max="360" step="1" slideTick="60" slideLabels="['0°', '180°', '360°']"
change="h = hlsHue.value; slideChanged()" />
<Hslns id="hlsLum" title="L:" value="0.5" change="l = hlsLum.value; slideChanged()" />
<Hslns id="hlsSat" title="S:" value="1" change="s = hlsSat.value; slideChanged()" />
</mx:VBox>
<mx:VBox label="HSV" paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5">
<Hslns id="hsvHue" title="H:" max="360" step="1" slideTick="60" slideLabels="['0°', '180°', '360°']"
change="h = hsvHue.value; slideChanged()" />
<Hslns id="hsvSat" title="S:" value="1" change="s = hsvSat.value; slideChanged()" />
<Hslns id="hsvVal" title="V:" value="1" change="v = hsvVal.value; slideChanged()" />
</mx:VBox>
</mx:TabNavigator>
</mx:Panel>
<mx:Component className="Hslns">
<mx:HBox borderStyle="solid" verticalAlign="middle" horizontalAlign="right" width="100%"
paddingTop="5" paddingBottom="5" paddingLeft="5" paddingRight="5"
creationComplete="init()">
<mx:Metadata>
[Event(name="change", type="flash.events.Event")]
</mx:Metadata>
<mx:Script><![CDATA[
public var title:String = "";
[Bindable] public var value:Number = 0;
public var min:Number = 0;
public var max:Number = 1;
public var step:Number = 0.01;
public var slideTick:Number = 0.1;
public var slideLabels:Array = ["0", "0.5", "1"];
private var e:Event = new Event("change");
private function init():void
{
lab.text = title;
sld.value = num.value = value;
sld.minimum = num.minimum = min;
sld.maximum = num.maximum = max;
sld.snapInterval = num.stepSize = step;
sld.tickInterval = slideTick;
sld.labels = slideLabels;
}
]]></mx:Script>
<mx:Label id="lab" />
<mx:HSlider id="sld" value="{value}" liveDragging="true" change="value = sld.value; dispatchEvent(e)" />
<mx:NumericStepper id="num" value="{value}" width="60" change="value = num.value; dispatchEvent(e)" />
</mx:HBox>
</mx:Component>
</mx:Application>