home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / CMS / drupal-6.0.exe / drupal-6.0 / misc / farbtastic / farbtastic.js < prev    next >
Encoding:
JavaScript  |  2007-06-01  |  9.0 KB  |  329 lines

  1. // $Id: farbtastic.js,v 1.4 2007/06/01 09:05:45 unconed Exp $
  2. // Farbtastic 1.2
  3.  
  4. jQuery.fn.farbtastic = function (callback) {
  5.   $.farbtastic(this, callback);
  6.   return this;
  7. };
  8.  
  9. jQuery.farbtastic = function (container, callback) {
  10.   var container = $(container).get(0);
  11.   return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
  12. };
  13.  
  14. jQuery._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. };