jQuery

Fast colour selector (v2)

Works with:
FF3
Chrome
IE6
IE7
Opera
Safari

Description

Similar to v1 except only using one 0.2kb png file and one 3.6kb jpg used. Works in all modern browsers including support for ie6 with the png fix. The colour selector used in Adobe Fireworks inspired me to use two individual images for the hue/saturation and lightness levels.

Demo

*
-

Red:
Green:
Blue:

Hue:
Saturation:
Lightness:

JavaScript

  1. $(".colour_selector").ready(function() {
  2.     $(".colour_selector").each(function(i) {
  3.         //controls
  4.         var colour_chooser = $(this).find(".colour_chooser");
  5.         var brightness_changer = $(this).find(".brightness_changer");
  6.         var colour_preview = $(this).find(".colour_preview");
  7.         var hue_image = colour_chooser.find(".hue_image");
  8.         var colour_cursor = colour_chooser.find(".colour_cursor");
  9.         var brightness_cursor = brightness_changer.find(".brightness_cursor");
  10.        
  11.         var span_red_value = $(this).find(".red_value");
  12.         var span_green_value = $(this).find(".green_value");
  13.         var span_blue_value = $(this).find(".blue_value");
  14.         var hue_value = $(this).find(".hue_value");
  15.         var saturation_value = $(this).find(".saturation_value");
  16.         var lightness_value = $(this).find(".lightness_value");
  17.        
  18.         //variables
  19.         var lightness = 1.0, hue = 0.0, saturation = 1.0;
  20.         var red=256, green=256, blue=256;
  21.         var mouseDown = false;
  22.        
  23.         //when ready
  24.         updateColourDisplay();
  25.        
  26.         //methods
  27.         brightness_changer.select(function() { $(this).blur(); });
  28.         brightness_changer.bind("mousedown",function(event) { mouseDown=true; changeBrightness(event, $(this)); });
  29.         brightness_changer.bind("mousemove",function(event) { if (mouseDown) changeBrightness(event, $(this)); });
  30.         brightness_changer.bind("mouseup",function() { mouseDown=false; });
  31.  
  32.         function changeBrightness(mouseEvent, obj) {
  33.             yPos = (mouseEvent.pageY-obj.offset().top);
  34.             if (yPos<0) yPos=0;
  35.             if (yPos>obj.height()) yPos = obj.height();
  36.            
  37.             brightness_cursor.css("top", yPos);
  38.            
  39.             lightness = 1.0 - (yPos/(obj.height()));
  40.            
  41.             setColourFromHSV();
  42.             updateColourDisplay();
  43.         }
  44.  
  45.         colour_chooser.bind("mousedown" ,function(event) { mouseDown=true; changeColour(event, $(this)); });
  46.         colour_chooser.bind("mousemove" ,function(event) { if (mouseDown) changeColour(event, $(this)); });
  47.         colour_chooser.bind("mouseup" ,function(event) { mouseDown=false; });
  48.  
  49.         function changeColour(mouseEvent, obj) {
  50.             xPos = (mouseEvent.pageX-obj.offset().left);
  51.             yPos = (mouseEvent.pageY-obj.offset().top);
  52.            
  53.             if (xPos<0) xPos=0;
  54.             if (xPos>obj.height()) xPos = obj.Width();
  55.            
  56.             if (yPos<0) yPos=0;
  57.             if (yPos>obj.height()) yPos = obj.height();
  58.            
  59.             colour_cursor.css("top", yPos);
  60.             colour_cursor.css("left", xPos);
  61.  
  62.             hue = xPos/obj.width();
  63.             saturation = 1.0 - (yPos/obj.height());
  64.            
  65.             var newColour = hslToRGB(hue, saturation, 0.5);
  66.             brightness_changer.css("background-color","rgb(" + newColour[0] + "," + newColour[1] + "," + newColour[2] + ")");
  67.            
  68.             setColourFromHSV();
  69.             updateColourDisplay();
  70.         }
  71.        
  72.         $(".common_colours li").bind("click", function(event) {
  73.             colour_preview.css("background-color", $(this).css("background-color"));
  74.             return false;
  75.         });
  76.  
  77.         function setColourFromHSV() {
  78.             var newColour = hslToRGB(hue, saturation, lightness);
  79.            
  80.             red = newColour[0];
  81.             green = newColour[1];
  82.             blue = newColour[2];
  83.         }
  84.  
  85.         function updateColourDisplay() {
  86.             colour_preview.css("background-color", "rgb(" + red + "," + green + "," + blue + ")");
  87.            
  88.             span_red_value.text(red);
  89.             span_green_value.text(green);
  90.             span_blue_value.text(blue);
  91.            
  92.             hue_value.text(Math.floor(hue*100) + "%");
  93.             saturation_value.text(Math.floor(saturation*100) + "%");
  94.             lightness_value.text(Math.floor(lightness*100) + "%");
  95.         }
  96.     });
  97. });
  98.  
  99. /**
  100. * Maths used from Wikipedia
  101. */
  102. function hslToRGB(hue, saturation, lightness) {
  103.     var q = 0.0, p=0.0;
  104.     var newColour = new Array(3);
  105.    
  106.     if (lightness<0.5) {
  107.         q = lightness * (1+saturation);
  108.     } else {
  109.         q = lightness + saturation - (lightness*saturation);
  110.     }
  111.    
  112.     p = 2*lightness - q;
  113.    
  114.     newColour[0] = Math.floor(hslColourToRGBColour(hue+0.33,p,q)*256); //red
  115.     newColour[1] = Math.floor(hslColourToRGBColour(hue,p,q)*256); //green
  116.     newColour[2] = Math.floor(hslColourToRGBColour(hue-0.33,p,q)*256); //blue
  117.    
  118.     return newColour;
  119. }
  120.  
  121. function hslColourToRGBColour(hslColour, p, q) {
  122.     if (hslColour<0.0) hslColour+= 1.0;
  123.     if (hslColour>1.0) hslColour-= 1.0;
  124.    
  125.     if (hslColour<0.167) {
  126.         return p+((q-p) * 6 * hslColour);
  127.     } else if (hslColour<0.5) {
  128.         return q;
  129.     } else if (hslColour<0.67) {
  130.         return p+((q-p)*6*(0.67-hslColour));
  131.     } else {
  132.         return p;
  133.     }
  134. }

CSS

  1. .hue_image,
  2. .brightness_image {
  3.     position: absolute;
  4.     width: 100%;
  5.     height: 100%;
  6.     z-index: 0;
  7. }
  8.  
  9. .colour_chooser,
  10. .brightness_changer,
  11. .colour_preview {
  12.     float: left;
  13.     border: 1px solid black;
  14.     margin: 5px;
  15.     overflow: hidden;
  16. }
  17.  
  18. .colour_chooser {
  19.     float: left;
  20.     background: url("hue_saturation.jpg") white top left no-repeat;
  21.     width: 200px;
  22.     height: 200px;
  23.     padding: 0px;
  24.     cursor: crosshair;
  25. }
  26.  
  27. .brightness_changer {
  28.     background: url("hue_lightness.png") red top left repeat-x;
  29.     width: 10px;
  30.     height: 200px;
  31.     cursor: s-resize;
  32. }
  33.  
  34. .colour_preview {
  35.     width: 26px;
  36.     height: 26px;
  37.     clear: right;
  38.     background-color: white;
  39. }
  40.  
  41. .colour_cursor,
  42. .brightness_cursor {
  43.     position: absolute;
  44.     top: 0px;
  45.     left: 0px;
  46. }
  47.  
  48. .colour_cursor {
  49.     width: 8px;
  50.     height: 8px;
  51. }
  52.  
  53. .brightness_cursor {
  54.     width: 10px;
  55.     height: 5px;
  56. }
  57.  
  58. .drag_plane {
  59.     width: 100%;
  60.     height: 100%;
  61.     position: absolute;
  62.     z-index: 100;
  63. }
  64.  
  65. .common_colours {
  66.     float: left;
  67.     border: 1px solid black;
  68.     padding: 0px;
  69.     list-style: none;
  70.     margin: 5px;
  71.     margin-top: 8px;
  72. }
  73.  
  74. .common_colours li {
  75.     float: left;
  76.     clear: both;
  77.     width: 16px;
  78.     height: 15px;
  79.     border-top: 1px black solid;
  80.     cursor: pointer;
  81. }

XHTML

  1. <div class="colour_selector">
  2.     <ul class="common_colours">
  3.         <li style="background-color: #000000;"></li>
  4.         <li style="background-color: #333333;"></li>
  5.         <li style="background-color: #666666;"></li>
  6.         <li style="background-color: #999999;"></li>
  7.         <li style="background-color: #CCCCCC;"></li>
  8.         <li style="background-color: #FFFFFF;"></li>
  9.         <li style="background-color: #FF0000;"></li>
  10.         <li style="background-color: #00FF00;"></li>
  11.         <li style="background-color: #0000FF;"></li>
  12.         <li style="background-color: #00FFFF;"></li>
  13.         <li style="background-color: #FFFF00;"></li>
  14.         <li style="background-color: #FF00FF;"></li>
  15.     </ul>
  16.     <div class="colour_chooser"><img class="colour_cursor" src="cursor.gif" alt="*" /></div>
  17.     <div class="brightness_changer"><img class="brightness_cursor" src="slider.gif" alt="-" /></div>
  18.     <div class="colour_preview"></div>
  19.     <p style="float: left;">
  20.         Red: <span class="red_value"></span><br />
  21.         Green: <span class="green_value"></span><br />
  22.         Blue: <span class="blue_value"></span><br />
  23.         <br />
  24.         Hue: <span class="hue_value"></span><br />
  25.         Saturation: <span class="saturation_value"></span><br />
  26.         Lightness: <span class="lightness_value"></span>
  27.     </p>
  28. </div>