source: extensions/piclens/farbtastic/farbtastic.js @ 31711

Last change on this file since 31711 was 3610, checked in by tiico, 15 years ago

Finalize advanced parameters for embeded wall
FR and EN Language
Add icones for custom icon toolbar

File size: 9.0 KB
Line 
1// $Id: farbtastic.js,v 1.2 2007/01/08 22:53:01 unconed Exp $
2// Farbtastic 1.2
3
4jQuery.fn.farbtastic = function (callback) {
5  $.farbtastic(this, callback);
6  return this;
7};
8
9jQuery.farbtastic = function (container, callback) {
10  var container = $(container).get(0);
11  return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
12}
13
14jQuery._farbtastic = function (container, callback) {
15  // Store farbtastic object
16  var fb = this;
17
18  // Insert markup
19  $(container).html('<div class="farbtastic"><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>');
20  var e = $('.farbtastic', container);
21  fb.wheel = $('.wheel', container).get(0);
22  // Dimensions
23  fb.radius = 84;
24  fb.square = 100;
25  fb.width = 194;
26
27  // Fix background PNGs in IE6
28  if (navigator.appVersion.match(/MSIE [0-6]\./)) {
29    $('*', e).each(function () {
30      if (this.currentStyle.backgroundImage != 'none') {
31        var image = this.currentStyle.backgroundImage;
32        image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
33        $(this).css({
34          'backgroundImage': 'none',
35          'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
36        });
37      }
38    });
39  }
40
41  /**
42   * Link to the given element(s) or callback.
43   */
44  fb.linkTo = function (callback) {
45    // Unbind previous nodes
46    if (typeof fb.callback == 'object') {
47      $(fb.callback).unbind('keyup', fb.updateValue);
48    }
49
50    // Reset color
51    fb.color = null;
52
53    // Bind callback or elements
54    if (typeof callback == 'function') {
55      fb.callback = callback;
56    }
57    else if (typeof callback == 'object' || typeof callback == 'string') {
58      fb.callback = $(callback);
59      fb.callback.bind('keyup', fb.updateValue);
60      if (fb.callback.get(0).value) {
61        fb.setColor(fb.callback.get(0).value);
62      }
63    }
64    return this;
65  }
66  fb.updateValue = function (event) {
67    if (this.value && this.value != fb.color) {
68      fb.setColor(this.value);
69    }
70  }
71
72  /**
73   * Change color with HTML syntax #123456
74   */
75  fb.setColor = function (color) {
76    var unpack = fb.unpack(color);
77    if (fb.color != color && unpack) {
78      fb.color = color;
79      fb.rgb = unpack;
80      fb.hsl = fb.RGBToHSL(fb.rgb);
81      fb.updateDisplay();
82    }
83    return this;
84  }
85
86  /**
87   * Change color with HSL triplet [0..1, 0..1, 0..1]
88   */
89  fb.setHSL = function (hsl) {
90    fb.hsl = hsl;
91    fb.rgb = fb.HSLToRGB(hsl);
92    fb.color = fb.pack(fb.rgb);
93    fb.updateDisplay();
94    return this;
95  }
96
97  /////////////////////////////////////////////////////
98
99  /**
100   * Retrieve the coordinates of the given event relative to the center
101   * of the widget.
102   */
103  fb.widgetCoords = function (event) {
104    var x, y;
105    var el = event.target || event.srcElement;
106    var reference = fb.wheel;
107
108    if (typeof event.offsetX != 'undefined') {
109      // Use offset coordinates and find common offsetParent
110      var pos = { x: event.offsetX, y: event.offsetY };
111
112      // Send the coordinates upwards through the offsetParent chain.
113      var e = el;
114      while (e) {
115        e.mouseX = pos.x;
116        e.mouseY = pos.y;
117        pos.x += e.offsetLeft;
118        pos.y += e.offsetTop;
119        e = e.offsetParent;
120      }
121
122      // Look for the coordinates starting from the wheel widget.
123      var e = reference;
124      var offset = { x: 0, y: 0 }
125      while (e) {
126        if (typeof e.mouseX != 'undefined') {
127          x = e.mouseX - offset.x;
128          y = e.mouseY - offset.y;
129          break;
130        }
131        offset.x += e.offsetLeft;
132        offset.y += e.offsetTop;
133        e = e.offsetParent;
134      }
135
136      // Reset stored coordinates
137      e = el;
138      while (e) {
139        e.mouseX = undefined;
140        e.mouseY = undefined;
141        e = e.offsetParent;
142      }
143    }
144    else {
145      // Use absolute coordinates
146      var pos = fb.absolutePosition(reference);
147      x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
148      y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
149    }
150    // Subtract distance to middle
151    return { x: x - fb.width / 2, y: y - fb.width / 2 };
152  }
153
154  /**
155   * Mousedown handler
156   */
157  fb.mousedown = function (event) {
158    // Capture mouse
159    if (!document.dragging) {
160      $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
161      document.dragging = true;
162    }
163
164    // Check which area is being dragged
165    var pos = fb.widgetCoords(event);
166    fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
167
168    // Process
169    fb.mousemove(event);
170    return false;
171  }
172
173  /**
174   * Mousemove handler
175   */
176  fb.mousemove = function (event) {
177    // Get coordinates relative to color picker center
178    var pos = fb.widgetCoords(event);
179
180    // Set new HSL parameters
181    if (fb.circleDrag) {
182      var hue = Math.atan2(pos.x, -pos.y) / 6.28;
183      if (hue < 0) hue += 1;
184      fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
185    }
186    else {
187      var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
188      var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
189      fb.setHSL([fb.hsl[0], sat, lum]);
190    }
191    return false;
192  }
193
194  /**
195   * Mouseup handler
196   */
197  fb.mouseup = function () {
198    // Uncapture mouse
199    $(document).unbind('mousemove', fb.mousemove);
200    $(document).unbind('mouseup', fb.mouseup);
201    document.dragging = false;
202  }
203
204  /**
205   * Update the markers and styles
206   */
207  fb.updateDisplay = function () {
208    // Markers
209    var angle = fb.hsl[0] * 6.28;
210    $('.h-marker', e).css({
211      left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
212      top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
213    });
214
215    $('.sl-marker', e).css({
216      left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
217      top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
218    });
219
220    // Saturation/Luminance gradient
221    $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
222
223    // Linked elements or callback
224    if (typeof fb.callback == 'object') {
225      // Set background/foreground color
226      $(fb.callback).css({
227        backgroundColor: fb.color,
228        color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
229      });
230
231      // Change linked value
232      $(fb.callback).each(function() {
233        if (this.value && this.value != fb.color) {
234          this.value = fb.color;
235        }
236      });
237    }
238    else if (typeof fb.callback == 'function') {
239      fb.callback.call(fb, fb.color);
240    }
241  }
242
243  /**
244   * Get absolute position of element
245   */
246  fb.absolutePosition = function (el) {
247    var r = { x: el.offsetLeft, y: el.offsetTop };
248    // Resolve relative to offsetParent
249    if (el.offsetParent) {
250      var tmp = fb.absolutePosition(el.offsetParent);
251      r.x += tmp.x;
252      r.y += tmp.y;
253    }
254    return r;
255  };
256
257  /* Various color utility functions */
258  fb.pack = function (rgb) {
259    var r = Math.round(rgb[0] * 255);
260    var g = Math.round(rgb[1] * 255);
261    var b = Math.round(rgb[2] * 255);
262    return '#' + (r < 16 ? '0' : '') + r.toString(16) +
263           (g < 16 ? '0' : '') + g.toString(16) +
264           (b < 16 ? '0' : '') + b.toString(16);
265  }
266
267  fb.unpack = function (color) {
268    if (color.length == 7) {
269      return [parseInt('0x' + color.substring(1, 3)) / 255,
270        parseInt('0x' + color.substring(3, 5)) / 255,
271        parseInt('0x' + color.substring(5, 7)) / 255];
272    }
273    else if (color.length == 4) {
274      return [parseInt('0x' + color.substring(1, 2)) / 15,
275        parseInt('0x' + color.substring(2, 3)) / 15,
276        parseInt('0x' + color.substring(3, 4)) / 15];
277    }
278  }
279
280  fb.HSLToRGB = function (hsl) {
281    var m1, m2, r, g, b;
282    var h = hsl[0], s = hsl[1], l = hsl[2];
283    m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
284    m1 = l * 2 - m2;
285    return [this.hueToRGB(m1, m2, h+0.33333),
286        this.hueToRGB(m1, m2, h),
287        this.hueToRGB(m1, m2, h-0.33333)];
288  }
289
290  fb.hueToRGB = function (m1, m2, h) {
291    h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
292    if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
293    if (h * 2 < 1) return m2;
294    if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
295    return m1;
296  }
297
298  fb.RGBToHSL = function (rgb) {
299    var min, max, delta, h, s, l;
300    var r = rgb[0], g = rgb[1], b = rgb[2];
301    min = Math.min(r, Math.min(g, b));
302    max = Math.max(r, Math.max(g, b));
303    delta = max - min;
304    l = (min + max) / 2;
305    s = 0;
306    if (l > 0 && l < 1) {
307      s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
308    }
309    h = 0;
310    if (delta > 0) {
311      if (max == r && max != g) h += (g - b) / delta;
312      if (max == g && max != b) h += (2 + (b - r) / delta);
313      if (max == b && max != r) h += (4 + (r - g) / delta);
314      h /= 6;
315    }
316    return [h, s, l];
317  }
318
319  // Install mousedown handler (the others are set on the document on-demand)
320  $('*', e).mousedown(fb.mousedown);
321
322    // Init color
323  fb.setColor('#000000');
324
325  // Set linked elements/callback
326  if (callback) {
327    fb.linkTo(callback);
328  }
329}
Note: See TracBrowser for help on using the repository browser.