ColorPicker = new Class({
initialize: function(objParent, InitialColor){
//if this is a color us it if not try to make a color out of it.
if(InitialColor.isColor)
this.CurColor = InitialColor;
else
this.CurColor = new Color(InitialColor);
//If the object was passed as a string get and Element with that ID otherwise use the element.
if(typeof objParent == 'string')
this.Parent = $(objParent);
else
this.Parent = objParent;
//These are member variables to hold function pointers to be called with the
//buttons in the color dialog.
this.OKCallback = null;
this.CancelCallback = null;
//Create the main container for our color picker.
this.Container = new Element("div");
this.Container.setStyle("border", "solid 1px #000000");
this.Container.setStyle("background-color", "#aaa");
this.Container.setStyle("width", "460px");
this.Container.setStyle("padding", "5px");
this.Parent.appendChild(this.Container);
//create the container for the hue bar.
this.HueBar = new Element("div");
this.HueBar.setStyle("width", "30px");
this.HueBar.setStyle("cssFloat", "left");
this.HueBar.setStyle("styleFloat", "left");
this.HueBar.setStyle("margin-right", "5px");
this.Container.appendChild(this.HueBar);
//create the container for the Saturation Value Box.
this.SVBox = new Element("div");
this.SVBox.setStyle("cssFloat", "left");
this.SVBox.setStyle("styleFloat", "left");
this.Container.appendChild(this.SVBox);
//create the container for the Color Swatches and Text Boxes.
this.ColorInfo = new Element("div");
this.ColorInfo.setStyle("cssFloat", "left");
this.ColorInfo.setStyle("styleFloat", "left");
this.ColorInfo.setStyle("text-align", "center");
this.ColorInfo.setStyle("margin-left", "3px");
this.Container.appendChild(this.ColorInfo);
//Add an empty div to the end to clear the floats.
this.ClearBreak = new Element("div");
this.ClearBreak.setStyle("clear", "both");
this.Container.appendChild(this.ClearBreak);
//create the color swatches.
this.SelectedColorLable = new Element("text");
this.SelectedColorLable.textContent = "Color:";
this.SelectedColor = new Element("div");
this.SelectedColor.setStyle("width", "50px");
this.SelectedColor.setStyle("height", "50px");
this.SelectedColor.setStyle("margin-left", "auto");
this.SelectedColor.setStyle("margin-right", "auto");
this.ColorInfo.appendChild(this.SelectedColorLable);
this.ColorInfo.appendChild(this.SelectedColor);
this.PreviewColorLable = new Element("text");
this.PreviewColorLable.textContent = "Preview:";
this.PreviewColor = new Element("div");
this.PreviewColor.setStyle("width", "50px");
this.PreviewColor.setStyle("height", "50px");
this.PreviewColor.setStyle("margin-left", "auto");
this.PreviewColor.setStyle("margin-right", "auto");
this.ColorInfo.appendChild(this.PreviewColorLable);
this.ColorInfo.appendChild(this.PreviewColor);
//Create the container for the hsv and rgb text boxes
this.ColorInputsContainer = new Element("div");
this.ColorInputsContainer.setStyle("width", "100%");
this.ColorInputsContainer.setStyle("text-align", "left");
this.ColorInputsContainer.setStyle("font-family", "Arial, Helvetica, sans-serif");
this.ColorInputsContainer.setStyle("margin-left", "5px");
this.ColorInfo.appendChild(this.ColorInputsContainer);
//Create the hsv and rgb text fields.
this.hLabel = new Element("text");
this.hLabel.textContent = "H:";
this.hInput = new Element("input");
this.hInput.size = "3";
this.hInput.name = "h";
this.hInput.type = "text";
this.hInput.addEvent('keyup', this.setHSL.bind(this));
this.ColorInputsContainer.appendChild(new Element("br"));
this.ColorInputsContainer.appendChild(this.hLabel);
this.ColorInputsContainer.appendChild(this.hInput);
this.ColorInputsContainer.appendChild(new Element("br"));
this.sLabel = new Element("text");
this.sLabel.textContent = "S:";
this.sInput = new Element("input");
this.sInput.size = "3";
this.sInput.name = "s";
this.sInput.type = "text";
this.sInput.addEvent('keyup', this.setHSL.bind(this));
this.ColorInputsContainer.appendChild(this.sLabel);
this.ColorInputsContainer.appendChild(this.sInput);
this.ColorInputsContainer.appendChild(new Element("br"));
this.vLabel = new Element("text");
this.vLabel.textContent = "V:";
this.vInput = new Element("input");
this.vInput.size = "3";
this.vInput.name = "v";
this.vInput.type = "text";
this.vInput.addEvent('keyup', this.setHSL.bind(this));
this.ColorInputsContainer.appendChild(this.vLabel);
this.ColorInputsContainer.appendChild(this.vInput);
this.ColorInputsContainer.appendChild(new Element("br"));
this.rLabel = new Element("text");
this.rLabel.textContent = "R:";
this.rInput = new Element("input");
this.rInput.size = "3";
this.rInput.name = "r";
this.rInput.type = "text";
this.rInput.addEvent('keyup', this.setRGB.bind(this));
this.ColorInputsContainer.appendChild(new Element("br"));
this.ColorInputsContainer.appendChild(this.rLabel);
this.ColorInputsContainer.appendChild(this.rInput);
this.ColorInputsContainer.appendChild(new Element("br"));
this.gLabel = new Element("text");
this.gLabel.textContent = "G:";
this.gInput = new Element("input");
this.gInput.size = "3";
this.gInput.name = "g";
this.gInput.type = "text";
this.gInput.addEvent('keyup', this.setRGB.bind(this));
this.ColorInputsContainer.appendChild(this.gLabel);
this.ColorInputsContainer.appendChild(this.gInput);
this.ColorInputsContainer.appendChild(new Element("br"));
this.bLabel = new Element("text");
this.bLabel.textContent = "B:";
this.bInput = new Element("input");
this.bInput.size = "3";
this.bInput.name = "b";
this.bInput.type = "text";
this.bInput.addEvent('keyup', this.setRGB.bind(this));
this.ColorInputsContainer.appendChild(this.bLabel);
this.ColorInputsContainer.appendChild(this.bInput);
this.ColorInputsContainer.appendChild(new Element("br"));
//create the ok button and set its onclick callback
this.okInput = new Element("input");
this.okInput.name = "OK";
this.okInput.value = "OK";
this.okInput.type = "button";
this.okInput.addEvent('click', this.handleOK.bind(this));
this.ColorInputsContainer.appendChild(this.okInput);
this.ColorInputsContainer.appendChild(new Element("br"));
//create the ok button and set its onclick callback
this.cancelInput = new Element("input");
this.cancelInput.name = "Cancel";
this.cancelInput.value = "Cancel";
this.cancelInput.type = "button";
this.cancelInput.addEvent('click', this.handleCancel.bind(this));
this.ColorInputsContainer.appendChild(this.cancelInput);
this.ColorInputsContainer.appendChild(new Element("br"));
//Draw the Hue Bar
this.drawHueBar();
//Draw the SVBox
this.drawSVBox();
},
//Iterates through all 360 hues and creates a 1px by 30px div for each hue.
drawHueBar: function (){
//Create a new color with hue at 0 and S and V at 100%
hsvColor = new Color([0,100,100], 'hsb');
//Create the one Hue element and set it's styles.
fcoDiv = new Element("div");
fcoDiv.setStyle("width","30px");
fcoDiv.setStyle("height","1px");
//Loop through the hues
for(ci = 0; ci < 360; ci++){
//User the changeHue to change the existing color object's hue.
hsvColor.changeHue(ci);
//Clone the Hue element and inject it inside the Hue Bar.
coDiv = fcoDiv.clone().injectInside(this.HueBar);
//Set the huse of the new Hue Element
coDiv.setStyle("background-color", hsvColor);
//Set the onClick callback function for the new Hue element.
coDiv.addEvent('click', this.setCurrentHue.bind(this));
}
},
//Draw a SV box that is as tall as the HUE Bar.
drawSVBox: function(objsvDiv){
//Specify the size of the SV Box svSize is used for both width and height.
svSize = 35;
//Set the size of the "pixels" for the SVBox.
pixelSize = 10;
//Get the multiple required to go from 0 to 100 is svSize steps.
svStep = 100/svSize;
//Create the color we will use to set the color of the SV Pixels
svColor = new Color([this.CurColor[0],this.CurColor[1],this.CurColor[2]]);
//Create a div that will hold 1 row of pixels.
// this is done to prevent to reduce the number of
// appends into the document.
rcDiv = new Element("div");
rcDiv.style.clear = "left";
rcDiv.style.width = (svSize*pixelSize)+"px";
rcDiv.style.height = pixelSize+"px";
//Create the one pixel that we will clone for each pixel.
fcoDiv = new Element("div");
fcoDiv.setStyle("width", pixelSize + "px");
fcoDiv.setStyle("height", pixelSize + "px");
fcoDiv.setStyle("cssFloat", "left");
fcoDiv.setStyle("styleFloat", "left");
//Iterate over each step in the row injecting cloaned divs into it.
for(ei = 0; ei < svSize; ei++){
fcoDiv.clone().injectInside(rcDiv);
}
//Iterate over the height of the SV box setting each rows colors.
for(vi = svSize; vi >= 0; vi -= 1){
//set the brightness for this row.
svColor.changeBrightness(vi*svStep);
//Cloan the row into the SVBox container.
trcDiv = rcDiv.clone().injectInside(this.SVBox);
//Get the children of this row.
arChildren = trcDiv.getChildren();
//Iterate the children of this row.
for(ci = 0; ci < arChildren.length; ci++){
//Change the saturation for each pixe.
svColor.changeSaturation(ci*svStep);
arChildren[ci].setStyle("background-color", svColor);
//Set the events for each pixels for color choice and preview.
arChildren[ci].addEvent('click', this.setSelectedColor.bind(this));
arChildren[ci].addEvent('mouseover', this.setPreviewColor.bind(this));
}
}
},
//Update the pixels in the SVBox when the hue is clicked.
UpdateSVBox: function (){
//Get the child rows in the SVBox
arSVRows = this.SVBox.getChildren();
//set the svSize to the number of rows.
svSize = arSVRows.length;
//Get the multiple required to go from 0 to 100 is svSize steps.
svStep = 100/svSize;
//Create a color for calculating the HSV of each pixel.
svColor = new Color([this.CurColor[0],this.CurColor[1],this.CurColor[2]]);
//Loop over all of the rows.
for(vi = svSize - 1; vi >= 0; vi -= 1){
//set the brightness for this row.
svColor.changeBrightness(vi*svStep);
//Get the children of the row.
siChildren = arSVRows[svSize - vi - 1].getChildren();
//Iterate the children of this row.
for(si = 0; si < siChildren.length; si++){
//Change the saturation for each pixe.
svColor.changeSaturation(si*svStep);
siChildren[si].setStyle("background-color", svColor);
}
}
},
setCurrentHue: function (e){
//IE uses srcElement instead of target to specify the
//element that was clicked.
if(!e.target)
e.target = e.srcElement;
//Create a color object from the background of the target so we can
//get its Hue.
CurHueColor = new Color(e.target.getStyle("background-color"));
//Set the Hue of the current color.
this.CurColor.changeHue(CurHueColor.hsb[0]);
//Tell the SVBox to update.
this.UpdateSVBox();
//Set the selected color to the current color.
this.SelectedColor.setStyle("background-color", this.CurColor);
//Update the hsv and rgb text boxes.
this.hInput.value = this.CurColor.hsb[0];
this.sInput.value = this.CurColor.hsb[1];
this.vInput.value = this.CurColor.hsb[2];
this.rInput.value = this.CurColor[0];
this.gInput.value = this.CurColor[1];
this.bInput.value = this.CurColor[2];
},
setPreviewColor: function (e){
//IE uses srcElement instead of target to specify the
//element that was clicked.
if(!e.target)
e.target = e.srcElement;
nColor = new Color(e.target.getStyle("background-color"));
this.PreviewColor.setStyle("background-color", nColor);
},
setSelectedColor: function (e){
//IE uses srcElement instead of target to specify the
//element that was clicked.
if(!e.target)
e.target = e.srcElement;
nColor = new Color(e.target.getStyle("background-color"));
this.CurColor = nColor;
this.SelectedColor.setStyle("background-color", nColor);
this.hInput.value = nColor.hsb[0];
this.sInput.value = nColor.hsb[1];
this.vInput.value = nColor.hsb[2];
this.rInput.value = nColor[0];
this.gInput.value = nColor[1];
this.bInput.value = nColor[2];
},
setRGB: function (){
nc = new Color([this.rInput.value, this.gInput.value, this.bInput.value]);
this.CurColor = nc;
this.hInput.value = nc.hsb[0];
this.sInput.value = nc.hsb[1];
this.vInput.value = nc.hsb[2];
this.SelectedColor.setStyle("background-color", nc);
this.PreviewColor.setStyle("background-color", nc);
this.UpdateSVBox();
},
setHSL: function (){
nc = new Color([this.hInput.value, this.sInput.value, this.vInput.value], 'hsb');
this.CurColor = nc;
this.rInput.value = nc[0];
this.gInput.value = nc[1];
this.bInput.value = nc[2];
this.SelectedColor.setStyle("background-color", nc);
this.PreviewColor.setStyle("background-color", nc);
this.UpdateSVBox();
},
//When the ok button is clicked call this.OKCallBack();
handleOK: function (){
if(this.OKCallback != null)
this.OKCallback();
},
//When the ok button is clicked call this.CancelCallback();
handleCancel: function (){
if(this.CancelCallback != null)
this.CancelCallback();
}
});