2 * Color Picker 0.1.0 - Raphael plugin
4 * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com)
5 * Based on Color Wheel (http://jweir.github.com/colorwheel) by John Weir (http://famedriver.com)
6 * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
9 Raphael
.colorpicker = function (x
, y
, size
, initcolor
, element
) {
10 return new ColorPicker(x
, y
, size
, initcolor
, element
);
12 Raphael
.fn
.colorPickerIcon = function (x
, y
, r
) {
13 var segments
= pi
* r
* 2 / Math
.min(r
/ 8, 4);
14 var a
= pi
/ 2 - pi
* 2 / segments
* 1.5,
15 path
= ["M", x
, y
- r
, "A", r
, r
, 0, 0, 1, r
* Math
.cos(a
) + x
, y
- r
* Math
.sin(a
), "L", x
, y
, "z"].join();
16 for (var i
= 0; i
< segments
; i
++) {
17 this.path(path
).attr({
19 fill
: "hsb(" + (segments
- i
) * (255 / segments
) / 255 + ", 1, 1)",
20 transform
: "r" + [90 + (360 / segments
) * i
, x
, y
]
23 return this.circle(x
, y
, r
).attr({
26 "stroke-width": Math
.round(r
* .03),
31 function angle(x
, y
) {
32 return (x
< 0) * 180 + Math
.atan(-y
/ -x
) * 180 / pi
;
34 var doc
= document
, win
= window
,
35 ColorPicker = function (x
, y
, size
, initcolor
, element
) {
37 var w3
= 3 * size
/ 200,
42 padding
= 2 * size
/ 200,
43 height
= size
+ size20
* 2 + padding
* 3,
45 H
= 1, S
= 1, B
= 1, s
= size
- (size20
* 4),
46 r
= element
? Raphael(element
, size
, height
) : Raphael(x
, y
, size
, height
),
47 xy
= s
/ 6 + size20
* 2 + padding
,
48 wh
= s
* 2 / 3 - padding
* 2;
53 r
.colorPickerIcon(size2
, size2
, size2
- padding
);
56 t
.cursor
.push(r
.circle(size2
, size2
, size20
/ 2).attr({
61 t
.cursor
.push(t
.cursor
[0].clone().attr({
66 t
.disc
= r
.circle(size2
, size2
, size2
- padding
).attr({
72 var style
= t
.disc
.node
.style
;
73 style
.unselectable
= "on";
74 style
.MozUserSelect
= "none";
75 style
.WebkitUserSelect
= "none";
78 var h
= size20
* 2 + 2;
79 t
.brect
= r
.rect(padding
+ h
/ fi
/ 2, size
+ padding
* 2, size
- padding
* 2 - h
/ fi
, h
- padding
* 2).attr({
84 t
.cursorb
.push(r
.rect(size
- padding
- h
/ fi
, size
+ padding
, ~~(h
/ fi
), h
, w3
).attr({
89 t
.cursorb
.push(t
.cursorb
[0].clone().attr({
94 t
.btop
= t
.brect
.clone().attr({
99 style
= t
.btop
.node
.style
;
100 style
.unselectable
= "on";
101 style
.MozUserSelect
= "none";
102 style
.WebkitUserSelect
= "none";
104 t
.bwidth
= ~~(h
/ fi
) / 2;
105 t
.minx
= padding
+ t
.bwidth
;
106 t
.maxx
= size
- h
/ fi
- padding
+ t
.bwidth
;
117 t
.disc
.drag(function (dx
, dy
, x
, y
) {
118 t
.docOnMove(dx
, dy
, x
, y
);
120 t
.hsOnTheMove
= true;
121 t
.setHS(x
- t
.x
, y
- t
.y
);
123 t
.hsOnTheMove
= false;
125 t
.btop
.drag(function (dx
, dy
, x
, y
) {
126 t
.docOnMove(dx
, dy
, x
, y
);
131 t
.bOnTheMove
= false;
134 t
.color(initcolor
|| "#fff");
135 this.onchanged
&& this.onchanged(this.color());
137 ColorPicker
.prototype.setB = function (x
) {
138 x
< this.minx
&& (x
= this.minx
);
139 x
> this.maxx
&& (x
= this.maxx
);
140 this.cursorb
.attr({x
: x
- this.bwidth
});
141 this.B
= (x
- this.minx
) / (this.maxx
- this.minx
);
142 this.onchange
&& this.onchange(this.color());
144 ColorPicker
.prototype.setHS = function (x
, y
) {
145 var X
= x
- this.size2
,
147 R
= this.size2
- this.size20
/ 2 - this.padding
,
151 if (X
* X
+ Y
* Y
> R
* R
) {
152 x
= R
* Math
.cos(rd
) + this.size2
;
153 y
= R
* Math
.sin(rd
) + this.size2
;
155 this.cursor
.attr({cx
: x
, cy
: y
});
156 this.H
= (1 - d
/ 360) % 1;
157 this.S
= Math
.min((X
* X
+ Y
* Y
) / R
/ R
, 1);
158 this.brect
.attr({fill
: "180-hsb(" + [this.H
, this.S
] + ",1)-#000"});
159 this.onchange
&& this.onchange(this.color());
161 ColorPicker
.prototype.docOnMove = function (dx
, dy
, x
, y
) {
162 if (this.hsOnTheMove
) {
163 this.setHS(x
- this.x
, y
- this.y
);
165 if (this.bOnTheMove
) {
166 this.setB(x
- this.x
);
169 ColorPicker
.prototype.remove = function () {
170 this.raphael
.remove();
171 this.color = function () {
175 ColorPicker
.prototype.color = function (color
) {
177 color
= Raphael
.getRGB(color
);
179 color
= Raphael
.rgb2hsb(color
.r
, color
.g
, color
.b
);
185 this.cursorb
.attr({x
: this.B
* (this.maxx
- this.minx
) + this.minx
- this.bwidth
});
186 this.brect
.attr({fill
: "180-hsb(" + [this.H
, this.S
] + ",1)-#000"});
188 var d
= (1 - this.H
) * 360,
190 R
= (this.size2
- this.size20
/ 2 - this.padding
) * this.S
,
191 x
= Math
.cos(rd
) * R
+ this.size2
,
192 y
= Math
.sin(rd
) * R
+ this.size2
;
193 this.cursor
.attr({cx
: x
, cy
: y
});
196 return Raphael
.hsb2rgb(this.H
, this.S
, this.B
).hex
;