2 * Farbtastic Color Picker 1.2
3 * © 2008 Steven Wittens
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //Adapted to uniform style with jQuery UI widgets and slightly change behavior
22 // - remove duplicated code by replacing it with jquery.colorUtils and modern jQuery
23 // - uniform code style
25 jQuery
.fn
.farbtastic = function (callback
) {
26 $.farbtastic(this, callback
);
30 jQuery
.farbtastic = function (container
, callback
) {
31 var container
= $(container
).get(0);
32 return container
.farbtastic
|| (container
.farbtastic
= new jQuery
._farbtastic(container
, callback
));
35 jQuery
._farbtastic = function (container
, callback
) {
36 // Store farbtastic object
40 $(container
).html('<div class="farbtastic ui-widget-content"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
41 $(container
).addClass('ui-widget');
42 var e
= $('.farbtastic', container
);
43 fb
.wheel
= $('.wheel', container
).get(0);
49 // Fix background PNGs in IE6
50 if (navigator
.appVersion
.match(/MSIE [0-6]\./)) {
51 $('*', e
).each(function () {
52 if (this.currentStyle
.backgroundImage
!= 'none') {
53 var image
= this.currentStyle
.backgroundImage
;
54 image
= this.currentStyle
.backgroundImage
.slice(5, image
.length
- 2);
56 backgroundImage
: 'none',
57 filter
: "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image
+ "')"
64 * Link to the given element(s) or callback.
66 fb
.linkTo = function (callback
) {
67 // Unbind previous nodes
68 if (typeof fb
.callback
== 'object') {
69 $(fb
.callback
).unbind('keyup', fb
.updateValue
);
75 // Bind callback or elements
76 if (typeof callback
== 'function') {
77 fb
.callback
= callback
;
79 else if (typeof callback
== 'object' || typeof callback
== 'string') {
80 fb
.callback
= $(callback
);
81 fb
.callback
.bind('keyup', fb
.updateValue
);
82 if (fb
.callback
.get(0).value
) {
83 fb
.setColor(fb
.callback
.get(0).value
);
88 fb
.updateValue = function (event
) {
89 if (this.value
!= fb
.color
) {
90 fb
.setColor(this.value
);
95 * Change color with HTML syntax #123456
97 fb
.setColor = function (color
) {
98 var rgb
= $.colorUtil
.getRGB( color
);
99 if (fb
.color
!= color
&& rgb
) {
100 rgb
= rgb
.slice( 0 ); //make a clone
101 //TODO: rewrite code so that this is not needed
107 fb
.hsl
= fb
.RGBToHSL(fb
.rgb
);
114 * Change color with HSL triplet [0..1, 0..1, 0..1]
116 fb
.setHSL = function (hsl
) {
118 fb
.rgb
= fb
.HSLToRGB(hsl
);
119 fb
.color
= fb
.pack(fb
.rgb
);
124 /////////////////////////////////////////////////////
127 * Retrieve the coordinates of the given event relative to the center
130 fb
.widgetCoords = function (event
) {
131 var ref
= $( fb
.wheel
).offset();
133 x
: event
.pageX
- ref
.left
- fb
.width
/ 2,
134 y
: event
.pageY
- ref
.top
- fb
.width
/ 2
141 fb
.mousedown = function (event
) {
143 if (!document
.dragging
) {
144 $(document
).bind('mousemove', fb
.mousemove
).bind('mouseup', fb
.mouseup
);
145 document
.dragging
= true;
148 // Check which area is being dragged
149 var pos
= fb
.widgetCoords(event
);
150 fb
.circleDrag
= Math
.max(Math
.abs(pos
.x
), Math
.abs(pos
.y
)) * 2 > fb
.square
;
160 fb
.mousemove = function (event
) {
161 // Get coordinates relative to color picker center
162 var pos
= fb
.widgetCoords(event
);
164 // Set new HSL parameters
166 var hue
= Math
.atan2(pos
.x
, -pos
.y
) / 6.28;
167 if (hue
< 0) hue
+= 1;
168 fb
.setHSL([hue
, fb
.hsl
[1], fb
.hsl
[2]]);
171 var sat
= Math
.max(0, Math
.min(1, -(pos
.x
/ fb
.square
) + .5));
172 var lum
= Math
.max(0, Math
.min(1, -(pos
.y
/ fb
.square
) + .5));
173 fb
.setHSL([fb
.hsl
[0], sat
, lum
]);
181 fb
.mouseup = function () {
183 $(document
).unbind('mousemove', fb
.mousemove
);
184 $(document
).unbind('mouseup', fb
.mouseup
);
185 document
.dragging
= false;
189 * Update the markers and styles
191 fb
.updateDisplay = function () {
193 var angle
= fb
.hsl
[0] * 6.28;
194 $('.h-marker', e
).css({
195 left
: Math
.round(Math
.sin(angle
) * fb
.radius
+ fb
.width
/ 2) + 'px',
196 top
: Math
.round(-Math
.cos(angle
) * fb
.radius
+ fb
.width
/ 2) + 'px'
199 $('.sl-marker', e
).css({
200 left
: Math
.round(fb
.square
* (.5 - fb
.hsl
[1]) + fb
.width
/ 2) + 'px',
201 top
: Math
.round(fb
.square
* (.5 - fb
.hsl
[2]) + fb
.width
/ 2) + 'px'
204 // Saturation/Luminance gradient
205 $('.color', e
).css('backgroundColor', fb
.pack(fb
.HSLToRGB([fb
.hsl
[0], 1, 0.5])));
207 // Linked elements or callback
208 if (typeof fb
.callback
== 'object') {
209 // Set background/foreground color
211 backgroundColor
: fb
.color
,
212 color
: fb
.hsl
[2] > 0.5 ? '#000' : '#fff'
215 // Change linked value
216 $(fb
.callback
).each(function() {
217 if ( $( this ).val() != fb
.color
) {
218 $( this ).val( fb
.color
).change();
222 else if (typeof fb
.callback
== 'function') {
223 fb
.callback
.call(fb
, fb
.color
);
227 /* Various color utility functions */
228 fb
.pack = function (rgb
) {
229 var r
= Math
.round(rgb
[0] * 255);
230 var g
= Math
.round(rgb
[1] * 255);
231 var b
= Math
.round(rgb
[2] * 255);
232 return '#' + (r
< 16 ? '0' : '') + r
.toString(16) +
233 (g
< 16 ? '0' : '') + g
.toString(16) +
234 (b
< 16 ? '0' : '') + b
.toString(16);
237 fb
.HSLToRGB = function (hsl
) {
239 var h
= hsl
[0], s
= hsl
[1], l
= hsl
[2];
240 m2
= (l
<= 0.5) ? l
* (s
+ 1) : l
+ s
- l
*s
;
242 return [this.hueToRGB(m1
, m2
, h
+0.33333),
243 this.hueToRGB(m1
, m2
, h
),
244 this.hueToRGB(m1
, m2
, h
-0.33333)];
247 fb
.hueToRGB = function (m1
, m2
, h
) {
248 h
= (h
< 0) ? h
+ 1 : ((h
> 1) ? h
- 1 : h
);
249 if (h
* 6 < 1) return m1
+ (m2
- m1
) * h
* 6;
250 if (h
* 2 < 1) return m2
;
251 if (h
* 3 < 2) return m1
+ (m2
- m1
) * (0.66666 - h
) * 6;
255 fb
.RGBToHSL = function (rgb
) {
256 var min
, max
, delta
, h
, s
, l
;
257 var r
= rgb
[0], g
= rgb
[1], b
= rgb
[2];
258 min
= Math
.min(r
, Math
.min(g
, b
));
259 max
= Math
.max(r
, Math
.max(g
, b
));
263 if (l
> 0 && l
< 1) {
264 s
= delta
/ (l
< 0.5 ? (2 * l
) : (2 - 2 * l
));
268 if (max
== r
&& max
!= g
) h
+= (g
- b
) / delta
;
269 if (max
== g
&& max
!= b
) h
+= (2 + (b
- r
) / delta
);
270 if (max
== b
&& max
!= r
) h
+= (4 + (r
- g
) / delta
);
276 // Install mousedown handler (the others are set on the document on-demand)
277 $('*', e
).mousedown(fb
.mousedown
);
280 fb
.setColor('#000000');
282 // Set linked elements/callback