color pick ui
/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xJ3E
*/
package
{
import com.bit101.components.HUISlider;
import com.bit101.components.VBox;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
/**
* http://matrix3d.github.io/
* @author lizhi
*/
[SWF(frameRate=60)]
public class TestColor extends Sprite
{
private var vSlider:HUISlider;
private var sSlider:HUISlider;
private var hSlider:HUISlider;
private var bSlider:HUISlider;
private var gSlider:HUISlider;
private var rSlider:HUISlider;
private var c:Color;
private var cimage:Sprite = new Sprite;
private var btnimage1:ImageWithBtn;
private var btnimage2:ImageWithBtn;
private var btnimage3:ImageWithBtn;
private var hsvArr:Array=[.99,.5,.99];
private var lastHsvArr:Array=[-1,-1,-1];
public function TestColor()
{
btnimage1 = new ImageWithBtn(100, 10, false, true);
addChild(btnimage1);
btnimage1.addEventListener(Event.CHANGE, btnimage1_change);
var bmd:BitmapData = btnimage1.bmd;
c = new Color;
for (var x:int = 0; x < bmd.width;x++ ) {
var hex:uint= c.fromHSV(x / bmd.width, 1, 1).toHex();
for (var y:int = 0; y < bmd.height;y++ ) {
bmd.setPixel(x, y, hex);
}
}
btnimage2 = new ImageWithBtn(100, 100, false, false);
addChild(btnimage2);
btnimage2.y = 20;
btnimage2.addEventListener(Event.CHANGE, btnimage2_change);
btnimage3 = new ImageWithBtn(100, 100, false, false);
addChild(btnimage3);
btnimage3.y = 130;
btnimage3.addEventListener(Event.CHANGE, btnimage3_change);
addChild(cimage);
cimage.x = 110;
var vbox:VBox = new VBox(this,170);
rSlider = new HUISlider(vbox, 0, 0, "r");
gSlider = new HUISlider(vbox, 0, 0, "g");
bSlider = new HUISlider(vbox, 0, 0, "b");
hSlider = new HUISlider(vbox, 0, 0, "h");
sSlider = new HUISlider(vbox, 0, 0, "s");
vSlider = new HUISlider(vbox, 0, 0, "v");
rSlider.addEventListener(Event.CHANGE, rgbSlider_change);
gSlider.addEventListener(Event.CHANGE, rgbSlider_change);
bSlider.addEventListener(Event.CHANGE, rgbSlider_change);
hSlider.addEventListener(Event.CHANGE, hsvSlider_change);
sSlider.addEventListener(Event.CHANGE, hsvSlider_change);
vSlider.addEventListener(Event.CHANGE, hsvSlider_change);
rSlider.maximum =
gSlider.maximum =
bSlider.maximum =
0xff;
hSlider.maximum =
sSlider.maximum =
vSlider.maximum =
0.99;
update();
/*var s:Stats = new Stats;
addChild(s);
s.x = 400;*/
}
private function hsvSlider_change(e:Event):void
{
hsvArr[0] = hSlider.value;
hsvArr[1] = sSlider.value;
hsvArr[2] = vSlider.value;
update();
}
private function rgbSlider_change(e:Event):void
{
c.fromRGB(rSlider.value, gSlider.value, bSlider.value);
hsvArr = c.toHSV();
update();
}
private function btnimage2_change(e:Event):void
{
hsvArr[1] = btnimage2.pos.x / btnimage2.w;
hsvArr[2] =1- btnimage2.pos.y / btnimage2.h;
update();
}
private function btnimage3_change(e:Event):void
{
var cx:Number = btnimage3.w / 2;
var cy:Number = btnimage3.h / 2;
var r:Number = cx;
var dx:Number = cx - btnimage3.pos.x;
var dy:Number = cy - btnimage3.pos.y;
var d:Number = Math.sqrt(dx * dx + dy * dy);
var nh:Number = Math.atan2(dy, dx) / Math.PI/2;
if (nh < 0) nh += 1;
hsvArr[0] = nh;
hsvArr[1] = Math.min(.99, d / r);
update();
}
private function btnimage1_change(e:Event):void
{
hsvArr[0] = btnimage1.pos.x / btnimage1.w;
update();
}
private function update():void {
var h:Number = hsvArr[0];
var s:Number = hsvArr[1];
var v:Number = hsvArr[2];
hSlider.value = h;
sSlider.value = s;
vSlider.value = v;
btnimage1.pos.x = h * btnimage1.w;
btnimage1.update();
btnimage2.pos.x = s * btnimage2.w;
btnimage2.pos.y = (1-v) * btnimage2.h;
btnimage2.update();
if(lastHsvArr[0]!=h){
var bmd:BitmapData = btnimage2.bmd;
var bmdVec:Vector.<uint> = btnimage2.bmdVec;
var bmdw:int = btnimage2.w;
//h
for (var i:int = 0, len:int = bmdVec.length; i < len;i++ ) {
var x:int = i % bmdw;
var y:int = i / bmdw;
bmdVec[i] = c.fromHSV(h, x / bmd.width, 1 - y / bmd.height).toHex();
}
bmd.setVector(bmd.rect, bmdVec);
}
bmd = btnimage3.bmd;
var cx:Number = btnimage3.w / 2;
var cy:Number = btnimage3.h / 2;
var r:Number = cx;
var a:Number = h * 2 * Math.PI;
a += Math.PI;
btnimage3.pos.x = cx + r * Math.cos(a)*s;
btnimage3.pos.y = cy + r * Math.sin(a)*s;
btnimage3.update();
//v
if(lastHsvArr[2]!=v){
bmdVec = btnimage3.bmdVec;
bmdw = btnimage3.w;
for (i = 0, len = bmdVec.length; i < len;i++ ) {
x = i % bmdw;
y = i / bmdw;
var dx:Number = cx - x;
var dy:Number = cy - y;
var d:Number = Math.sqrt(dx * dx + dy * dy);
if (d < r) {
var nh:Number = Math.atan2(dy, dx) / Math.PI/2;
if (nh < 0) nh += 1;
bmdVec[i]= c.fromHSV(nh, d / r, v).toHex();
}else {
bmdVec[i] = 0;
}
}
bmd.setVector(bmd.rect, bmdVec);
}
c.fromHSV(h, s, v);
rSlider.value = c.r;
gSlider.value = c.g;
bSlider.value = c.b;
cimage.graphics.clear();
cimage.graphics.beginFill(c.toHex());
cimage.graphics.drawRect(0, 0, 50, 50);
lastHsvArr = [].concat(hsvArr);
}
}
}
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
class ImageWithBtn extends Sprite {
private var lockX:Boolean;
private var lockY:Boolean;
public var w:Number;
public var h:Number;
public var bmd:BitmapData;
public var bmdVec:Vector.<uint>;
private var btn:Sprite;
private var _pos:Point = new Point;
private var startPos:Point = new Point;
private var startMousePos:Point = new Point;
public function ImageWithBtn(w:Number,h:Number,lockX:Boolean,lockY:Boolean) {
this.h = h;
this.w = w;
this.lockY = lockY;
this.lockX = lockX;
bmd = new BitmapData(w, h, false, 0);
bmdVec = bmd.getVector(bmd.rect);
addChild(new Bitmap(bmd));
btn = new Sprite;
btn.graphics.beginFill(0, .5);
btn.graphics.lineStyle(0, 0xffffff);
btn.graphics.drawCircle(0, 0, 5);
addChild(btn);
addEventListener(MouseEvent.MOUSE_DOWN, btn_mouseDown);
update();
}
private function btn_mouseDown(e:MouseEvent):void
{
pos.x = mouseX;
pos.y=mouseY
startPos.x = pos.x;
startPos.y = pos.y;
startMousePos.x = mouseX;
startMousePos.y = mouseY;
btn.stage.addEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove);
btn.stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseUp);
stage_mouseMove(null);
}
private function stage_mouseUp(e:MouseEvent):void
{
btn.stage.removeEventListener(MouseEvent.MOUSE_MOVE, stage_mouseMove);
btn.stage.removeEventListener(MouseEvent.MOUSE_UP, stage_mouseUp);
}
private function stage_mouseMove(e:MouseEvent):void
{
pos.x = startPos.x + mouseX - startMousePos.x;
pos.y = startPos.y + mouseY - startMousePos.y;
update();
dispatchEvent(new Event(Event.CHANGE));
}
public function get pos():Point
{
return _pos;
}
public function set pos(value:Point):void
{
_pos = value;
}
public function update():void {
if (lockX) {
pos.x = w/2;
}
if (lockY) {
pos.y = h/2;
}
pos.x = Math.min(Math.max(0, pos.x), w-1);
pos.y = Math.min(Math.max(0, pos.y), h-1);
btn.x = pos.x;
btn.y = pos.y;
}
}
//http://baike.baidu.com/subview/541362/8445478.htm
class Color {
public var r:Number;
public var g:Number;
public var b:Number;
public function fromHex(hex:uint=0):void {
r = (hex >> 16) & 0xff;
g = (hex >> 8) & 0xff;
b = hex & 0xff;
}
public function fromRGB(r:Number=0, g:Number=0, b:Number=0):Color {
this.r = r;
this.g = g;
this.b = b;
return this;
}
public function fromHSV(h:Number, s:Number, v:Number):Color {
var R:Number, G:Number, B:Number;
if (s == 0) {
R = G = B = v;
}else{
var h6:Number = h * 6;
var i:int = h6;
var f:Number = h6 - i;
var a:Number = v * ( 1 - s )
var b:Number = v * ( 1 - s * f )
var c:Number = v * ( 1 - s * (1 - f ) )
switch(i){
case 0: R = v; G = c; B = a; break;
case 1: R = b; G = v; B = a;break;
case 2: R = a; G = v; B = c;break;
case 3: R = a; G = b; B = v;break;
case 4: R = c; G = a; B = v;break;
case 5: R = v; G = a; B = b;break;
}
}
r = R * 0xff;
g = G * 0xff;
this.b = B * 0xff;
return this;
}
public function toHSV():Array {
var R:Number = r / 0xff;
var G:Number = g / 0xff;
var B:Number = b / 0xff;
var max:Number = Math.max(R, G, B);
var min:Number = Math.min(R, G, B);
var v:Number = max;
if(max==min)return [0,0,max]
var s:Number = (max - min) / max;
if (R == max) var h:Number = (G - B) / (max - min) / 6;
if (G == max) h = 1/3 + (B - R) / (max - min) / 6;
if (B == max) h = 2 / 3 +(R - G) / (max - min) / 6;
if (h < 0) h += 1;
return [h, s, v];
}
public function toHex():uint {
return (Math.round(r) << 16) | (Math.round(g) << 8) | Math.round(b);
}
}