Today, we are going to take a look at how to create an interactive color picker using javascript, css, and html. There are a number of color picker packages out there on the web, but there isn't nearly as much on how to write one yourself and the mechanics behind how it works. Hopefully, after reading this article, you would be able to go off and write one yourself.
This tutorial builds on a number of other javascript articles on this site, including Javascript Objects - A Useful Example (which covers some basics about how objects work in javascript - and we will be using the color object created in that tutorial), Javascript - Working With Events (which covers how to work with events and event objects), and Javascript - Draggable Elements (which covers how to do dragging in javascript). So, if you are relatively new to javascript, I would suggest at least skimming those before you continue.
Below, you can see the result of what we will create today. You can adjust the hue by dragging the arrows on the color bar, and can adjust saturation and value by dragging around the small circle in the gradient square. The hex, RGB, and HSV values are output in the textboxes on the right, as well as a div containing the color picked. You can also enter values in the hex, RGB and HSV text boxes, and the correct color will show up (and the arrows and circle will move to the correct position). What we are going to create today is not a package, but it could be made into one very easily. Play around a bit - I know you want to.
Ok, now that you've had your fun, lets dive right in. Right below, we have the html required to create the color picker:
<div style="position:relative;height:286px;width:531px;border:1px solid black;">
<div id="gradientBox" style="cursor:crosshair;top:15px;position:absolute;
left:15px;width:256px;height:256px;">
<img id="gradientImg" style="display:block;width:256px;height:256px;"
src="/Color_Picker/color_picker_gradient.png" />
<img id="circle" style="position:absolute;height:11px;width:11px;"
src="/Color_Picker/color_picker_circle.gif" />
</div>
<div id="hueBarDiv" style="position:absolute;left:310px;width:35px;
height:256px;top:15px;">
<img style="position:absolute;height:256px; width:19px;left:8px;"
src="/Color_Picker/color_picker_bar.png" />
<img id="arrows" style="position:absolute;height:9px;width:35px;left:0px;"
src="/Color_Picker/color_picker_arrows.gif" />
</div>
<div style="position:absolute;left:370px;width:145px;height:256px;top:15px;">
<div style="position:absolute;border: 1px solid black;
height:50px;width:145px;top:0px;left:0px;">
<div id="quickColor" style="position:absolute;height:50px;width:73px;
top:0px;left:0px;">
</div>
<div id="staticColor" style="position:absolute;height:50px;width:72px;
top:0px;left:73px;">
</div>
</div>
<br />
<table width="100%" style="position:absolute;top:55px;">
<tr>
<td>Hex: </td>
<td>
<input size="8" type="text" id="hexBox" onchange="hexBoxChanged();" />
</td>
</tr>
<tr>
<td>Red: </td>
<td>
<input size="8" type="text" id="redBox" onchange="redBoxChanged();" />
</td>
</tr>
<tr>
<td>Green: </td>
<td>
<input size="8" type="text" id="greenBox" onchange="greenBoxChanged();" />
</td>
</tr>
<tr>
<td>Blue: </td>
<td>
<input size="8" type="text" id="blueBox" onchange="blueBoxChanged();" />
</td>
</tr>
<tr>
<td>Hue: </td>
<td>
<input size="8" type="text" id="hueBox" onchange="hueBoxChanged();" />
</td>
</tr>
<tr>
<td>Saturation: </td>
<td>
<input size="8" type="text" id="saturationBox"
onchange="saturationBoxChanged();" />
</td>
</tr>
<tr>
<td>Value: </td>
<td>
<input size="8" type="text" id="valueBox" onchange="valueBoxChanged();" />
</td>
</tr>
</table>
</div>
</div>
The stuff in the bottom half is really simple - it is just a table for
the text boxes and their labels. Of course, each of them has a
javascript function attached to their onchange event - but we will go
into what those function do later. For now, we want to take a look at
the top part - the divs that define the gradient box and the hue bar.
The gradient box is just a div with a 256x256 partially transparent
image inside of it. This partially transparent image is what gives the
gradient - the upper right corner is completely transparent, the bottom
right is solid white, and the left is solid black. Setting the
background color on this div creates the appearance of a
saturation-value gradient in that background color. This div also
contains the circle image that represents the selected point.
The hue bar doesn't require any gradient tricks - it is just a standard
hue bar, where the bottom is a hue of 0 and the top is a hue of 359. The
arrows are a single image sitting on top of the bar, where the center of
the arrow image is transparent. The other divs represent the color box
on the upper right of the color picker - it is split into two divs, one
which represents the current color that you are dragging over
(quickColor), and the other represents the last color that you picked
(staticColor). When you finish a drag operation - either on the
gradient or the bar - both divs will update to show the color that the
drag operation completed on.
So now that you have an idea of what is where in terms of the html elements, lets turn to the javascript. Below, we have the initialization code for the color picker:
fixGradientImg();
var currentColor = Colors.ColorFromRGB(64,128,128);
new dragObject("arrows", "hueBarDiv", arrowsLowBounds, arrowsUpBounds,
arrowsDown, arrowsMoved, endMovement);
new dragObject("circle", "gradientBox", circleLowBounds, circleUpBounds,
circleDown, circleMoved, endMovement);
colorChanged('box');
Obviously, not much of that makes sense at the moment, but we shall take
a look one line at a time. The first line, the call to
fixGradientImage, is what makes this color picker work in Internet
Explorer 6. IE6, as you probably know, does not support transparency on
pngs by default - and so we have to apply this hack to get the gradient
image to appear correctly. The function looks like the following:
function fixGradientImg()
{
fixPNG(document.getElementById("gradientImg"));
}
function fixPNG(myImage)
{
if(!document.body.filters)
return;
var arVersion = navigator.appVersion.split("MSIE");
var version = parseFloat(arVersion[1]);
if(version < 5.5 || version >= 7)
return;
var imgID = (myImage.id) ? "id='" + myImage.id + "' " : ""
var imgStyle = "display:inline-block;" + myImage.style.cssText
var strNewHTML = "<span " + imgID + " style=\"width:" + myImage.width
+ "px; height:" + myImage.height + "px;" + imgStyle + ";"
+ "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
+ "(src=\'" + myImage.src + "\', sizingMethod='scale');\"></span>"
myImage.outerHTML = strNewHTML
}
There is plenty of info on the web about what exactly this hack does in IE6, so I won't go over that here. Suffice it to say, where we had a opaque image, we now have a span with a partially transparent png.
The next line of initialization code
(var currentColor = Colors.ColorFromRGB(64,128,128);) sets up the
global object that will always hold the currently selected color, and
initializes it to a value smack dab in the middle of the spectrum. This
is probably a good time to re-introduce the color object from
Javascript Objects - A Useful
Example. And here it is
in all its glory:
var Colors = new function()
{
this.ColorFromHSV = function(hue, sat, val)
{
var color = new Color();
color.SetHSV(hue,sat,val);
return color;
}
this.ColorFromRGB = function(r, g, b)
{
var color = new Color();
color.SetRGB(r,g,b);
return color;
}
this.ColorFromHex = function(hexStr)
{
var color = new Color();
color.SetHexString(hexStr);
return color;
}
function Color()
{
//Stored as values between 0 and 1
var red = 0;
var green = 0;
var blue = 0;
//Stored as values between 0 and 360
var hue = 0;
//Strored as values between 0 and 1
var saturation = 0;
var value = 0;
this.SetRGB = function(r, g, b)
{
if (isNaN(r) || isNaN(g) || isNaN(b))
return false;
r = r/255.0;
red = r > 1 ? 1 : r < 0 ? 0 : r;
g = g/255.0;
green = g > 1 ? 1 : g < 0 ? 0 : g;
b = b/255.0;
blue = b > 1 ? 1 : b < 0 ? 0 : b;
calculateHSV();
return true;
}
this.Red = function()
{ return Math.round(red*255); }
this.Green = function()
{ return Math.round(green*255); }
this.Blue = function()
{ return Math.round(blue*255); }
this.SetHSV = function(h, s, v)
{
if (isNaN(h) || isNaN(s) || isNaN(v))
return false;
hue = (h >= 360) ? 359.99 : (h < 0) ? 0 : h;
saturation = (s > 1) ? 1 : (s < 0) ? 0 : s;
value = (v > 1) ? 1 : (v < 0) ? 0 : v;
calculateRGB();
return true;
}
this.Hue = function()
{ return hue; }
this.Saturation = function()
{ return saturation; }
this.Value = function()
{ return value; }
this.SetHexString = function(hexString)
{
if(hexString == null || typeof(hexString) != "string")
return false;
if (hexString.substr(0, 1) == '#')
hexString = hexString.substr(1);
if(hexString.length != 6)
return false;
var r = parseInt(hexString.substr(0, 2), 16);
var g = parseInt(hexString.substr(2, 2), 16);
var b = parseInt(hexString.substr(4, 2), 16);
return this.SetRGB(r,g,b);
}
this.HexString = function()
{
var rStr = this.Red().toString(16);
if (rStr.length == 1)
rStr = '0' + rStr;
var gStr = this.Green().toString(16);
if (gStr.length == 1)
gStr = '0' + gStr;
var bStr = this.Blue().toString(16);
if (bStr.length == 1)
bStr = '0' + bStr;
return ('#' + rStr + gStr + bStr).toUpperCase();
}
this.Complement = function()
{
var newHue = (hue>= 180) ? hue - 180 : hue + 180;
var newVal = (value * (saturation - 1) + 1);
var newSat = (value*saturation) / newVal;
var newColor = new Color();
newColor.SetHSV(newHue, newSat, newVal);
return newColor;
}
function calculateHSV()
{
var max = Math.max(Math.max(red, green), blue);
var min = Math.min(Math.min(red, green), blue);
value = max;
saturation = 0;
if(max != 0)
saturation = 1 - min/max;
hue = 0;
if(min == max)
return;
var delta = (max - min);
if (red == max)
hue = (green - blue) / delta;
else if (green == max)
hue = 2 + ((blue - red) / delta);
else
hue = 4 + ((red - green) / delta);
hue = hue * 60;
if(hue <0)
hue += 360;
}
function calculateRGB()
{
red = value;
green = value;
blue = value;
if(value == 0 || saturation == 0)
return;
var tHue = (hue / 60);
var i = Math.floor(tHue);
var f = tHue - i;
var p = value * (1 - saturation);
var q = value * (1 - saturation * f);
var t = value * (1 - saturation * (1 - f));
switch(i)
{
case 0:
red = value; green = t; blue = p;
break;
case 1:
red = q; green = value; blue = p;
break;
case 2:
red = p; green = value; blue = t;
break;
case 3:
red = p; green = q; blue = value;
break;
case 4:
red = t; green = p; blue = value;
break;
default:
red = value; green = p; blue = q;
break;
}
}
}
}
();
This code, as explained in that previous tutorial, creates a static Colors object which can be used to create color objects (which can take RGB, HSV, or Hex and produce RGB, HSV, or Hex). I'm not going to go into detail on how it works here - if you want to know more about it, read the tutorial.
The next two lines in the initialization hook the two elements that need to be draggable - the circle and the arrows.
new dragObject("arrows", "hueBarDiv", arrowsLowBounds, arrowsUpBounds,
arrowsDown, arrowsMoved, endMovement);
new dragObject("circle", "gradientBox", circleLowBounds, circleUpBounds,
circleDown, circleMoved, endMovement);
The first line here declares that the element arrows is draggable and
hueBarDiv is the handle. This means that if you click anywhere on the
hueBarDiv, the arrows will start dragging. Then we give it a lower and
an upper position bound for where we can drag the arrows, and three
functions, a function to call at the beginning of dragging, one after
each movement, and one when dragging completes. We set the same type of
thing up in the second line, for the circle on the gradient image - but
in this case the gradientBox is the drag handle - so if you click
anywhere on the gradient image, you start dragging the circle.
Just as a refresher, here is the main chunk of code behind dragObj:
function dragObject(element, attachElement, lowerBound, upperBound,
startCallback, moveCallback, endCallback, attachLater)
{
if(typeof(element) == "string")
element = document.getElementById(element);
if(element == null)
return;
if(lowerBound != null && upperBound != null)
{
var temp = lowerBound.Min(upperBound);
upperBound = lowerBound.Max(upperBound);
lowerBound = temp;
}
var cursorStartPos = null;
var elementStartPos = null;
var dragging = false;
var listening = false;
var disposed = false;
function dragStart(eventObj)
{
if(dragging || !listening || disposed)
return;
dragging = true;
if(startCallback != null)
startCallback(eventObj, element);
cursorStartPos = absoluteCursorPostion(eventObj);
elementStartPos = new Position(parseInt(element.style.left),
parseInt(element.style.top));
elementStartPos = elementStartPos.Check();
hookEvent(document, "mousemove", dragGo);
hookEvent(document, "mouseup", dragStopHook);
return cancelEvent(eventObj);
}
function dragGo(eventObj)
{
if(!dragging || disposed)
return;
var newPos = absoluteCursorPostion(eventObj);
newPos = newPos.Add(elementStartPos)
newPos = newPos.Subtract(cursorStartPos);
newPos = newPos.Bound(lowerBound, upperBound)
newPos.Apply(element);
if(moveCallback != null)
moveCallback(newPos, element);
return cancelEvent(eventObj);
}
function dragStopHook(eventObj)
{
dragStop();
return cancelEvent(eventObj);
}
function dragStop()
{
if(!dragging || disposed)
return;
unhookEvent(document, "mousemove", dragGo);
unhookEvent(document, "mouseup", dragStopHook);
cursorStartPos = null;
elementStartPos = null;
if(endCallback != null)
endCallback(element);
dragging = false;
}
this.Dispose = function()
{
if(disposed)
return;
this.StopListening(true);
element = null;
attachElement = null
lowerBound = null;
upperBound = null;
startCallback = null;
moveCallback = null
endCallback = null;
disposed = true;
}
this.StartListening = function()
{
if(listening || disposed)
return;
listening = true;
hookEvent(attachElement, "mousedown", dragStart);
}
this.StopListening = function(stopCurrentDragging)
{
if(!listening || disposed)
return;
unhookEvent(attachElement, "mousedown", dragStart);
listening = false;
if(stopCurrentDragging && dragging)
dragStop();
}
this.IsDragging = function(){ return dragging; }
this.IsListening = function() { return listening; }
this.IsDisposed = function() { return disposed; }
if(typeof(attachElement) == "string")
attachElement = document.getElementById(attachElement);
if(attachElement == null)
attachElement = element;
if(!attachLater)
this.StartListening();
}
This code is from the Javascript - Draggable Elements tutorial. Again, since there is a very detailed discussion of the draggable code in that tutorial, I'm just going to gloss right over it here.
So back to those drag object initializations - what are the upper and lower bounds of the arrows and the circle? They are position objects (and if you don't know what our position object is, go read the draggable elements tutorial again). And here is what they are defined as:
var arrowsLowBounds = new Position(0, -4);
var arrowsUpBounds = new Position(0, 251);
var circleLowBounds = new Position(-5, -5);
var circleUpBounds = new Position(250, 250);
The fact that both the lower and the upper X value for the arrows is the same number means that it can't be dragged left or right, but only up or down. The reason the other numbers aren't quite what you might expect is that these positions represent the upper left corner of the circle/arrow elements. This means that they are offset by the half the width and half the height so that the center of the elements can reach the edge of its bounding area.
So those are the bounds - now what about the callbacks? Well, first we
have the start callbacks - circleDown and arrowsDown. Lets see what
they do:
function arrowsDown(e, arrows)
{
var pos = getMousePos(e);
if(getEventTarget(e) == arrows)
pos.Y += parseInt(arrows.style.top);
pos = correctOffset(pos, arrowsOffset, true);
pos = pos.Bound(arrowsLowBounds, arrowsUpBounds);
pos.Apply(arrows);
arrowsMoved(pos);
}
function circleDown(e, circle)
{
var pos = getMousePos(e);
if(getEventTarget(e) == circle)
{
pos.X += parseInt(circle.style.left);
pos.Y += parseInt(circle.style.top);
}
pos = correctOffset(pos, circleOffset, true);
pos = pos.Bound(circleLowBounds, circleUpBounds);
pos.Apply(circle);
circleMoved(pos);
}
These two functions may be small but they accomplish a lot. Lets go over
the arrowsDown one step by step. First we get the current mouse
position from the event object. This is done with the following
function:
function getMousePos(eventObj)
{
eventObj = eventObj ? eventObj : window.event;
var pos;
if(isNaN(eventObj.layerX))
pos = new Position(eventObj.offsetX, eventObj.offsetY);
else
pos = new Position(eventObj.layerX, eventObj.layerY);
return correctOffset(pos, pointerOffset, true);
}
Here we get the correct event object (see Javascript - Working With
Events for an explanation of
why), and then we get the current mouse position, relative to the
element that triggered the event. Of course, Internet Explorer and
Firefox do this differently, so we have the two different ways of
getting the number here. Once we have that position we call the function
correctOffset, and get a new position back (which we then return).
This correctOffset function is rather simplistic, but serves an
important purpose:
function correctOffset(pos, offset, neg)
{
if(neg)
return pos.Subtract(offset);
return pos.Add(offset);
}
All it does is take a position and an offset (both position objects),
and either applies or unapplies that offset (according to the third
argument). We use it in the getMousePos function with the
pointerOffset:
var pointerOffset = new Position(0, navigator.userAgent.indexOf("Firefox") >= 0 ? 1 : 0);
var circleOffset = new Position(5, 5);
var arrowsOffset = new Position(0, 4);
For whatever horrible reason, where Firefox reports the tip of the pointer to be is not actually the tip of the pointer - it is 1 pixel off in the X direction. So, we need this pointer offset value. The other two offsets listed here are much more acceptable - they are the values to get from the upper left pixel of the circle/arrow to the center point value that we need (we will be using these two offsets a bunch later).
Ok, so back to the arrowsDown code. We now have the current mouse
position relative to the element that triggered the event. The next
thing we do is check what element triggered the event - and if it is the
arrows themselves, we add the current position of the arrows (in the Y
direction) to the Y mouse position. This way we now have the mouse
position relative to the hue bar. The reason we don't do anything with
the X position here is that the X position of the arrows never changes.
Now we call correctOffset again, but this time it is to adjust for the
height of the arrows image (i.e., we adjust it using the
arrowsOffset). This is so that the current mouse position ends up at
the center of the arrows image, instead of at the top. Now that we have
what will become the new position for the arrows, we bound it to make
sure it falls within the correct range (using the lower and upper arrow
bounds). Then we apply the new position to the arrows element. Finally,
we call the function arrowsMoved with the new position. What all this
code essentially accomplishes is to move the arrows to the point at
which you clicked on the hue bar. The code for circleDown accomplishes
the exact same task, but for the circle on the gradient image.
Now on to the functions arrowsMoved and circleMoved. They are called
at the end of their respective 'Down' functions, and they are also
called after every movement during a drag. So lets see what they do:
function arrowsMoved(pos, element)
{
pos = correctOffset(pos, arrowsOffset, false);
currentColor.SetHSV((256 - pos.Y)*359.99/255, currentColor.Saturation(),
currentColor.Value());
colorChanged("arrows");
}
function circleMoved(pos, element)
{
pos = correctOffset(pos, circleOffset, false);
currentColor.SetHSV(currentColor.Hue(), 1-pos.Y/255.0, pos.X/255.0);
colorChanged("circle");
}
Again, the two functions look extremely similar. They start by
offsetting the position (the position passed in is the one for the new
upper-left position of the element, so we are bringing it back to the
center of the their respective elements). Next we set the new current
color, based on the position. For the arrows, the Y position transforms
into the hue - first we flip it (since in coordinate space, 0 is at the
top, but in the space of the hue bar, 0 is at the bottom), and then we
scale it from the range 0-255 (the range of the hue bar image) to the
range 0-359.99 (the actual range of hue that we deal with). For the
circle, the Y position becomes the saturation (where again, it is
flipped) and we scale it from the range 0-255 to the range 0-1. The X
position becomes the new value, and here we just scale it from 0-255 to
0-1. Finally, we call a function called colorChanged:
function colorChanged(source)
{
document.getElementById("hexBox").value = currentColor.HexString();
document.getElementById("redBox").value = currentColor.Red();
document.getElementById("greenBox").value = currentColor.Green();
document.getElementById("blueBox").value = currentColor.Blue();
document.getElementById("hueBox").value = Math.round(currentColor.Hue());
var str = (currentColor.Saturation()*100).toString();
if(str.length > 4)
str = str.substr(0,4);
document.getElementById("saturationBox").value = str;
str = (currentColor.Value()*100).toString();
if(str.length > 4)
str = str.substr(0,4);
document.getElementById("valueBox").value = str;
if(source == "arrows" || source == "box")
document.getElementById("gradientBox").style.backgroundColor=
Colors.ColorFromHSV(currentColor.Hue(), 1, 1).HexString();
if(source == "box")
{
var el = document.getElementById("arrows");
el.style.top = (256 - currentColor.Hue()*255/359.99 - arrowsOffset.Y) + 'px';
var pos = new Position(currentColor.Value()*255,
(1-currentColor.Saturation())*255);
pos = correctOffset(pos, circleOffset, true);
pos.Apply("circle");
endMovement();
}
document.getElementById("quickColor").style.backgroundColor =
currentColor.HexString();
}
This function is where we synchronize all the various elements of the
color picker. The one argument, source is a string representing where
the new values have come from. This string has three possible values -
"arrows", "circle", and "box" - where "arrows" means the position of the
arrows has changes, "circle" means the position of the circle has
changed, and "box" means that one of the input boxes has changed.
So first in this function, we update the various text boxes - because
these always need to be updated, no matter what changed. The saturation
and value text boxes get multiplied up to be a percentage and then
rounded to look nicer. If the source was the arrows or the box, we
update the background color of the gradient div - whose color we get by
taking the current hue and giving it a value and saturation of 1. If the
source was a text box, we update the position of the arrows and the
circle, from the current color. Essentially, we do the reverse of the
calculation that we used to get from position to color. We also call a
function endMovement in this case, which I will explain in a moment.
Finally, we update the current color of the quickColor div to be the
currently selected color.
So now we have the function endMovement, which is called after a drag
operation completes on the arrows or circle, and is also called whenever
a text box causes something to change. It is pretty simple, all it does
is set the staticColor div to the new color:
function endMovement()
{
document.getElementById("staticColor").style.backgroundColor =
currentColor.HexString();
}
We are actually almost done now! The final call in initialization was to
call colorChanged('box');, which you understand now is to get all the
color picker components synced with the initial color choice. There are
only a couple more functions - and they are all extremely simple. They
are the onchange functions for each of the text boxes:
function hexBoxChanged(e)
{
currentColor.SetHexString(document.getElementById("hexBox").value);
colorChanged("box");
}
function redBoxChanged(e)
{
currentColor.SetRGB(parseInt(document.getElementById("redBox").value),
currentColor.Green(), currentColor.Blue());
colorChanged("box");
}
function greenBoxChanged(e)
{
currentColor.SetRGB(currentColor.Red(),
parseInt(document.getElementById("greenBox").value), currentColor.Blue());
colorChanged("box");
}
function blueBoxChanged(e)
{
currentColor.SetRGB(currentColor.Red(), currentColor.Green(),
parseInt(document.getElementById("blueBox").value));
colorChanged("box");
}
function hueBoxChanged(e)
{
currentColor.SetHSV(parseFloat(document.getElementById("hueBox").value),
currentColor.Saturation(), currentColor.Value());
colorChanged("box");
}
function saturationBoxChanged(e)
{
currentColor.SetHSV(currentColor.Hue(),
parseFloat(document.getElementById("saturationBox").value)/100.0,
currentColor.Value());
colorChanged("box");
}
function valueBoxChanged(e)
{
currentColor.SetHSV(currentColor.Hue(), currentColor.Saturation(),
parseFloat(document.getElementById("valueBox").value)/100.0);
colorChanged("box");
}
Each of those functions just takes the new value from its repective text
box, pushes that new value into the current color object, and then calls
colorChanged("box") in order to update everyone else.
And that covers it for how to make a color picker using javascript! Hope you enjoyed it, and if you would like the raw javascript code to play around with, feel free to download it here. The html and couple lines of initialization javascript are not in that file, but you can copy all that from the boxes above or the source of this page.
Source Files:
could you please give links to the .png and .gif files that are in your code?
Sure! Here are all the links: Gradient, Hue Bar, Arrows, Circle
Is it possible, via javascript, to rotate the hue of an entire image, dynamicly? the ideal would be to provide a color pallete or a slider and according to the values(of the slider) that the user provides, the hue/saturation/brightness of the entire image, to change accordingly. if you know how to do so a tutorial would be just about great! :D
I play with this code but the drag object did not work. Do I miss something?
I second oasis' motion. The drag object is not working... Have I done something wrong?
Perhaps you forgot to include the chunk on initialization javascript at the end. Here is what the full html code should look like:
Here's an enhanced version of this color picker: http://walidator.info/?s=colorpicker_en
I also had a bizarre problem with this. It turns out that the link to the javascript *must* be like
not like
Anyway, it's a great script. Thanks ferret.
Um, that is, like \\
not
\
Kniffler, I've done that by accident way too many times. Also, you can refer to this post on how to embed code into any comments.
Hi. I'd just ask for some advise on how I could modify this script to reduce the size of the color picker and still get the correct values? I've tried limiting the bounds during initialization and resized the image. However, it doesn't provide the correct values. Which part of the script should I modify? Thanks a lot!
Ok, it has been a while since I looked at this code, but I'm pretty sure you will need to change some numbers in three different functions:
arrowsMoved,circleMoved, andcolorChanged.Essentially, you want to replace references to 256 with your new size, and references to 255 with your size minus 1.
Oh, and you'll want to change the bounds on the arrows and circle to your new numbers. So this code:
Should become this:
In retrospect, I should have pulled the size out as a constant.
+1 ? ??????!
I can not able to concatenate the code properly...so it give so many errors...can any one send me the complete code structure in 1/2 file(s) plz.....
Thank you
Thank you so much for this tutorial. I will plug-in this to a project I am working on. It works will with asp.net and it does not conflict with AJAX for .net.
thx a million -Ray
It works on my nokia e70!!! -)
This is a great script, thanks!
Is it ok to use the code found here on a commercial site also as long as I modify the design a little?
Sure, go ahead, use it for whatever you would like. That's why it is out here :)
Excellent! Thanks for a good site, we are going to use this colorpicker for users to control the design of their own templates! Again, many thanks!
Thanks for this excellent tutorial and script!
I included the color picker into a Greasemonkey script that highlights movie links on IMDb.com: http://userscripts.org/scripts/show/35145
???????, ???????? ??????!!! Thank you, excelent script!! =)
Hi The code is very useful. But the images are not displaying. Can you please send me the full code with images.
Thanking you.
awesome code! thanks for sharing
Great script, and amazing tutorial(s)! Thank you so much!
You are awesome!!!!! I had another color picker but it was way too many files to download and upload to the server for my taste and your code rocks!!!!!!
Excellent script(s) !! I am new to JavaScript - had a question - how do I set the selected color in the opener page ? On the page I have a "color picker" graphic next to a textbox that opens up the color picker in a pop-up window. I have added a button just under the color picker (in the popup) that says "Set Color". I would like to add code to the "onclick" event of the button and be able to set the selected color in the text box.
Any help will be greatly appreciated.
Nevermind, figured it out.
Hi "The Tallest".
It's appropriate that your icon is Father Xmas because this script is an absolute gift.
Thanks and well done.
I will plug-in this to a project I am working on. It works will with asp.net and it does not conflict with AJAX for .net. club penguin cheats
Thanks for this fantastic piece of code.
Can you think of any reason this wouldn't work inside a 'lightbox' style jquery page? Possible variable name conflicts? anything like that?
I have a modular lightbox setup to run through a series of pages and render them in a lightbox type div. This code works fine outside jquery, but inside of it, the dragObject doesn't seem to get instantiated.
Yea, just noticed the author hasn't been here in around 2 years.Good luck Feck!
Thanks man i make this color picker on my site
@amko_sa... (or any expert) can you make this for my site? which is powered by microsoft... it is more like a blog spot. Pls quote your fee. pls email to nahoku44@gmail.com thank you.
haha thanks but i will go with YUI http://developer.yahoo.com/yui/examples/colorpicker/colorpicker-fromscript.html ;)
Hey how do you tell which color the user has chosen? I mean how does it read from circle in the image? O_o
Check out the functions arrowsMoved and circleMoved. The vertical slider represents the hue and the large gradient square represents the saturation. Since we know the size of these elements the values can be calculated based on the position of the mouse. If we know the hue and the saturation, a color can be derived.
arrowsMoved and circleMoved have an extra, unused argument: element.
ive tried adding this to HTML 5 and is doesn't work what can i do to fix this?
thank you so much for this tutorial, it's really great script for me
Hi,
Getting it up and running was easy. But I would need the hex codes without the # sign, or a coupled module won't work. I found this function:
but if I remove the '#', the color picker doesn't work anymore in most browsers, only in IE. Can this still be done?
PS: to avoid mistakes: I only need the hex code to be without # sign in the form field. Whatever the color picker does internally is not important to me. In my setting, the hex code must be copied and pasted into a form field of external module. A module that I am neither able nor allowed to change.
Thanks for this tutorial, work fine on my site! http://www.imagemoz.com/rgb/