Version 1.7Slider Demo: Colour Picker
API Quick Reference
JavaScript is required to use the quick reference
Example
Code
HTML
<form action="#" id="colourPickerForm">
<div id="colourPicker">
<div id="finalColour"></div>
<div id="rSelect">
<label for="rInput">Red:</label>
<div id="rContainer"></div>
<input type="text" name="rInput" id="rInput" />
</div>
<div id="gSelect">
<label for="gInput">Green:</label>
<div id="gContainer"></div>
<input type="text" name="gInput" id="gInput" />
</div>
<div id="bSelect">
<label for="bInput">Blue:</label>
<div id="bContainer"></div>
<input type="text" name="bInput" id="bInput" />
</div>
</div>
<p id="colourValue">
<label for="hexColour">Colour:</label>
<input type="text" name="hexColour" id="hexColour" />
</p>
</form>
Initialisation
var glow,
// shortcut to glow.dom.get
$,
// element to show the final colour in
finalColour,
// object containing 3 sliders (r, g, b)
sliders = {},
// object containing 3 gradients for those sliders
gradients = {},
// element to show hex value in
hexColour;
function init() {
// handy shortcut
$ = glow.dom.get;
// get element to show the final colour in
finalColour = $("#finalColour");
// get element to show hex value in
hexColour = $("#hexColour");
var colours = ["r", "g", "b"],
i = 0,
len = colours.length;
// for r, g & b, make a slider and gradient
for (; i < len; i++) {
// create a slider
sliders[ colours[i] ] = new glow.widgets.Slider("#" + colours[i] + "Container", {
bindTo: "#" + colours[i] + "Input",
id: colours[i],
min: 0,
max: 255,
changeOnDrag: true,
buttons: false,
onChange: colourChange
})
// create a gradient
gradients[ colours[i] ] = new Gradient("#" + colours[i] + "Select", 284, 11);
}
// listen for the user manually changing the hex value
glow.events.addListener(hexColour, "keyup", hexInputChange);
// initialise the gradients and final colour
colourChange();
}
In the above, init is called when Glow has loaded and the DOM is ready.
Handling changes to the hex value
The following is called when the user enters characters into the "Colour" input.
function hexInputChange() {
// get the new value
var val = hexColour.val(),
parsedColour;
// test to see if it's a full 6 char hex value
if (/#[0-9a-fA-F]{6}/.test( val )) {
// break the hex down into r, g, b integers
parsedColour = glow.dom.parseCssColor(val);
// set all the sliders to reflect the new value
sliders.r.val( parsedColour.r );
sliders.g.val( parsedColour.g );
sliders.b.val( parsedColour.b );
// update the gradients and final colour
colourChange();
}
}
Handling changes to the selected colour
Whenever the user interacts with the sliders or changes the value in the "Colour" input to a valid hex colour value, we need to update the selected colour, the gradients, and the hex value.
function colourChange() {
// get the value of each slider
var r = sliders.r.val(),
g = sliders.g.val(),
b = sliders.b.val();
// set the background of the finalColour div to the selected colour.
// This is done by setting the background css property
// to something in the format rgb(255, 255, 255)
finalColour.css("background", "rgb(" + r + ", " + g + ", " + b + ")");
// set the new colours for the start and end of each gradient
gradients.r.setColours("rgb(0, " + g + ", " + b + ")", "rgb(255, " + g + ", " + b + ")");
gradients.g.setColours("rgb(" + r + ", 0, " + b + ")", "rgb(" + r + ", 255, " + b + ")");
gradients.b.setColours("rgb(" + r + ", " + g + ", 0)", "rgb(" + r + ", " + g + ", 255)");
// convert the values into hex strings
var rHex = r.toString(16),
gHex = g.toString(16),
bHex = b.toString(16);
// pad the values with a zero if needed
if (rHex.length == 1) rHex = "0" + rHex;
if (gHex.length == 1) gHex = "0" + gHex;
if (bHex.length == 1) bHex = "0" + bHex;
// assign the hex value to the input
hexColour.val(
"#" + rHex + gHex + bHex
);
}
The Gradients
The gradients are done using canvas or VML, depending on the browser.
I created a simple class to abstract creating the gradients and changing their colour.
I've gone a bit over the top with comments here...
/**
@name Gradient
@class
@description Create a canvas / VML horizontal linear gradient
@param {Element | Selector} container Where to insert the gradient
@param {Number} width
@param {Number} height
*/
function Gradient(container, width, height) {
// IE supports VML, other browsers support canvas
if (glow.env.ie) {
var stylesheet,
rect,
fill;
// VML requires initial setup, the following is only required on the
// creation of the first gradient
if ( !Gradient.ranInitialSetup ) {
// add the v: namespace
document.namespaces.add("v");
// add some microsoft nonsense to enable vml
stylesheet = document.createStyleSheet();
stylesheet.addRule('v\\:*', "behavior: url(/glow/docs/1.7/furtherinfo/widgets/slider/);");
}
// create a rectangle with a fill
this._fill = glow.dom.create('<v:rect><v:fill></v:fill></v:rect>')
// apply the dimentions
.css("width", width)
.css("height", height)
// disable borders
.attr("stroked", "false")
// add it to the page
.appendTo(container)
// grab the fill element
.children()
// set up the gradient
.attr({
type: "gradient",
angle: "270",
// setting the method to none makes the gradient change linearly,
// else it doesn't match the selected value
method: "none"
})[0];
} else {
// create a canvas
this._canvas = glow.dom.create('<canvas></canvas>')
// apply the dimentions
.attr({
width: width,
height: height
})
// add it to the page
.appendTo(container)[0];
}
Gradient.ranInitialSetup = true;
}
// this static variable lets us detect when we're creating the first
// instance of Gradient.
Gradient.ranInitialSetup = false;
Gradient.prototype = {
/**
@name Gradient#setColours
@function
@description Set the colours of the gradient
@param {String} startColour Start colour of the gradient (CSS value)
@param {String} endColour End colour of the gradient (CSS value)
*/
setColours: function(startColour, endColour) {
// once again, the process is completely different for VML and Canvas
if (glow.env.ie) {
// set the colours as properties of the fill
this._fill.color = startColour;
this._fill.color2 = endColour;
} else {
// return if the browser doesn't support canvas
if ( !this._canvas.getContext ) return;
// get a drawing context
var context = this._canvas.getContext('2d'),
// create a gradient (startX, startY, endX, endY)
gradient = context.createLinearGradient(0, 0, this._canvas.width, 0);
// add colours to the gradient (position, colour)
gradient.addColorStop(0, startColour);
gradient.addColorStop(1, endColour);
// assign the fill style to the canvas
context.fillStyle = gradient;
// create a fill (startX, startY, endX, endY)
context.fillRect(0, 0, this._canvas.width, this._canvas.height);
}
}
}
Loading Glow
Trigger the running of our application by loading Glow
gloader.load(["glow", "1", "glow.dom", "glow.events", "glow.widgets.Slider"], {
async: true,
onLoad: function(glowInstance) {
// send glow to the previous scope
glow = glowInstance;
// run init when dom is ready
glow.ready(init);
}
});
All of the above code is contained within a closure to keep it out of global scope. See the source of this page for all of the code in one chunk. It can be found towards the end of the page, with the CSS in the head of the page.