At the moment the purpose of this page is just to show the three files which are in use to make this work. That's index.html, colour.js and colour.css. When I find/make time to augment it a little, this page will be further prettified with syntax highlighting and some pre-amble about each file. I'll also put a few links in, such as one to take you back to the tool. I will also provide links to validate both the HTML and the CSS, although it may all be a bit dicey given that a lot of content is generated by the javascript, and I'm not sure if the validator can take account of that.
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-gb" lang="en">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=iso-8859-1" />
<title>JavaScript Colour Picker - evilstreak</title>
<link rel="stylesheet" type="text/css" href="colour.css" />
<script type="text/javascript" src="colour.js" />
</head>
<body onload="javascript:resetPalette();">
<div id="menu">
<ul>
<li><a href="javascript:showInstructions();" title="Find out how to use the colour picker.">Instructions</a></li>
<li><a href="source.php" title="View the PHP and JavaScript that make the colour picker work.">View Source</a></li>
</ul>
<ul>
<li><a href="javascript:resetPalette();" title="Reset the colour picker to its original state, wiping all your stored colours.">Reset All</a></li>
<li><a href="javascript:refreshPalette(0,0,0);" title="Reset the palette to the 216 web-safe palette, but keep all your stored colours.">Web-safe</a></li>
</ul>
<ul>
<li class="inline">
<a id="sm" href="javascript:setStepSize(0x08);" title="Set the step size to small. This will make the palette colours correlate strongly.">S</a>
<a id="md" href="javascript:setStepSize(0x11);" title="Set the step size to medium. This will make the palette colours correlate weakly.">M</a>
<a id="lg" href="javascript:setStepSize(0x33);" title="Set the step size to large. This will display the web-safe palette.">L</a>
</li>
<li style="clear:both"><a href="javascript:storeColour();" title="Add the current colour to your "paintbox" to compare against other colours.">Store Colour</a></li>
<li><a id="link" href="" title="Get a link to this page with your stored colours so you can share it with friends.">Create Link</a></li>
</ul>
<ul>
<li id="current">#000000</li>
</ul>
</div><!-- end of #menu -->
<div id="links">
<ul>
<li><a href="javascript:void(0);" title="Copyright © 2005 Dominic Baggott">Copyright</a></li>
<li><a href="archive/" title="Take look at previous versions of this tool, some a lot less efficient than this one!">Old Versions</a></li>
<li><a href="http://dbwebdesign.net/" title="Visit the author's site.">DB Web Design</a></li>
</ul>
</div><!-- end of #links -->
<div id="palette"></div>
<div id="paintbox"></div>
</body>
</html>
/* private void refreshTextColour ()
*
* this function refreshes the text colour used on the screen
* picking either white or black for optimum legibility
*/
function refreshTextColour()
{
// this looks for the rgb values in "rgb(x, x, x)"
var re = /^rgb\((\d{1,3}),\s(\d{1,3}),\s(\d{1,3})\)/;
var colours = re.exec(document.body.style.background);
// this decides whether black or white is more visible
// see [http://www.w3.org/TR/AERT#color-contrast]
r = colours[1] * 299;
g = colours[2] * 587;
b = colours[3] * 114;
rgb = ((r + g + b) / 1000) > 127 ? '000' : 'fff';
// set the text color
document.body.style.color = '#' + rgb;
}
/* private string makeHex (int r, int g, int b)
*
* this function glues together three rgb values into
* a single string, making sure each part is 2 digits
*/
function makeHex(r,g,b)
{
r = parseInt(r,10).toString(16);
if (r.length != 2) r = '0' + r;
g = parseInt(g,10).toString(16);
if (g.length != 2) g = '0' + g;
b = parseInt(b,10).toString(16);
if (b.length != 2) b = '0' + b;
return (r + g + b);
}
/* public void refreshPalette (int r, int g, int b)
*
* this function refreshes the main colour palette, by
* taking the given set of rgb values, and building up
* from 2 steps below to 3 steps above. this results
* in 216 colours (6**3) being sent to the screen.
*/
function refreshPalette(r,g,b)
{
var r0,g0,b0;
if (r < stepSize * 2) r0 = 0;
else if (r > 255 - stepSize * 5) r0 = 255 - stepSize * 5;
else r0 = r - stepSize * 2;
if (g < stepSize * 2) g0 = 0;
else if (g > 255 - stepSize * 5) g0 = 255 - stepSize * 5;
else g0 = g - stepSize * 2;
if (b < stepSize * 2) b0 = 0;
else if (b > 255 - stepSize * 5) b0 = 255 - stepSize * 5;
else b0 = b - stepSize * 2;
// temporary variable to hold data
var newPalette = '';
// build new palette
for (var i = 0, r = r0; i < 6; i++, r += stepSize)
{
// this div and the ones nested in it simply
// allow the block wrapping to work
newPalette += '<div>';
for (var j = 0, g = g0; j < 6; j++, g += stepSize)
{
newPalette += '<div>';
for (var k = 0, b = b0; k < 6; k++, b += stepSize)
{
var rgb = makeHex(r,g,b);
// this is the link which holds the css styling
// to make it a block
newPalette += '<a ' +
'href="javascript:setColour('+r+','+g+','+b+');" ' +
'title="#' + rgb + '" ' +
'style="background:#' + rgb + '">' +
'</a>';
}
newPalette += '</div>';
}
newPalette += '</div>';
}
// send to the screen
document.getElementById('palette').innerHTML = newPalette;
}
/* public void resetPalette ()
*
* this function resets the colour picker back to its
* original state, wiping all stored colours.
*/
function resetPalette()
{
// remove all paintbox patches
paintbox = document.getElementById('paintbox');
while (paintbox.childNodes.length > 0)
paintbox.removeChild(paintbox.childNodes[0]);
// set palette to display web-safe colours
setStepSize(0x33);
setColour(0,0,0);
// set step size to medium
setStepSize(0x11);
}
/* public void showInstructions ()
*
* this function resets the colour picker back to its
* original state, wiping all stored colours.
*/
function showInstructions ()
{
document.getElementById('palette').innerHTML =
'<ul>' +
'<li>guidance</li>' +
'<ul>' +
'<li>click any square to focus the colour patches in the palette around that colour. the step size affects how tightly the colours will correlate.</li>' +
'</ul>' +
'</li>' +
'<li>menu</li>' +
'<ul>' +
'<li><strong>instructions</strong> will bring these instructions up, but then i guess you know that now!</li>' +
'<li><strong>view source</strong> will display the source code from the 3 files to make this tool, along with comments.</li>' +
'<li><strong>reset all</strong> will fully reset the state of the colour picker. all of the colours in your "paintbox" will be lost, along with the current selections.</li>' +
'<li><strong>web-safe</strong> will put the colours of the palette back to the web-safe colours. it will leave your selected colour and step size the same.</li>' +
'<li><strong>step size</strong> options allow you to control how close the colours in the palette are to each other.</li>' +
'<ul>' +
'<li><strong>small</strong> step size will make the colours correlate highly.</li>' +
'<li><strong>medium</strong> step size will make the colours correlate weakly.</li>' +
'<li><strong>large</strong> step size will not make the colours correlate at all, in fact it will give you the web-safe palette.</li>' +
'</ul>' +
'</ul>' +
'</li>' +
'</ul>';
}
/* public void setStepSize (int size)
*
* this function sets the stepSize in use to the
* value of the parameter passed. 0x33, 0x11 and
* 0x08 are the three values currently used.
*/
function setStepSize (size)
{
// store parameter so other functions can access it
stepSize = size;
// refreshTextColour();
// reset all links to default appearance
document.getElementById('sm').style.fontWeight = 'normal';
document.getElementById('md').style.fontWeight = 'normal';
document.getElementById('lg').style.fontWeight = 'normal';
// determine highlighted link(s)
switch (stepSize)
{
case 0x08:
var id = 'sm';
break;
case 0x11:
var id = 'md';
break;
case 0x33:
var id = 'lg';
break;
}
document.getElementById(id).style.fontWeight = 'bold';
}
/* public void setColour (int r, int g, int b)
*
* this function sets the background colour to the
* value of the parameters passed, and refreshed
* the palette to focus around that colour.
*/
function setColour (r,g,b)
{
document.body.style.background = '#' + makeHex(r,g,b);
document.getElementById('current').innerHTML = '#' + makeHex(r,g,b);
refreshTextColour();
refreshPalette(r,g,b);
}
function storeColour ()
{
// this looks for the rgb values in "rgb(x, x, x)"
var re = /^rgb\((\d{1,3}),\s(\d{1,3}),\s(\d{1,3})\)/;
var colours = re.exec(document.body.style.background);
// this decides whether black or white is more visible
// see [http://www.w3.org/TR/AERT#color-contrast]
var r = colours[1] * 299;
var g = colours[2] * 587;
var b = colours[3] * 114;
var x_colour = ((r + g + b) / 1000) > 127 ? 'light' : 'dark';
var r = colours[1];
var g = colours[2];
var b = colours[3];
pb_entry = document.createElement('div');
pb_patch = document.createElement('a');
pb_delete = document.createElement('a');
pb_entry.style.top = '430px';
pb_patch.setAttribute('class','pb_patch');
pb_patch.setAttribute('href','javascript:setColour('+r+','+g+','+b+');');
pb_patch.setAttribute('title','#' + makeHex(r,g,b));
pb_patch.style.background = '#' + makeHex(r,g,b);
pb_delete.setAttribute('class','pb_delete_' + x_colour);
pb_delete.setAttribute('href','#');
pb_delete.setAttribute('title','Delete this colour from your "paintbox".');
pb_delete.appendChild(document.createTextNode('x'));
pb_delete.onclick = function () { javascript:this.parentNode.parentNode.removeChild(this.parentNode); return false; };
pb_entry.appendChild(pb_patch);
pb_entry.appendChild(pb_delete);
document.getElementById('paintbox').appendChild(pb_entry);
}
body
{
background: #000;
color: #fff;
font-family: Verdana, Tahoma, Sans-serif;
font-size: 10px;
}
/* menu & links on RHS of screen */
div#menu, div#links
{
position: absolute;
right: 0px;
width: 100px;
}
div#menu { top: 0; }
div#links { bottom: 0; }
div#menu ul,
div#links ul
{
margin: 0;
padding: 0;
line-height: 2.5em;
text-align: center;
}
div#menu ul { margin-bottom: 20px; }
div#links ul { margin-top: 20px; }
div#menu li,
div#links li
{
list-style: none;
border-left: 1px dashed #fff;
}
div#menu li
{
border-bottom: 1px dashed #fff;
}
div#links li
{
border-top: 1px dashed #fff;
}
div#menu ul li:first-child
{
border-top: 1px dashed #fff;
}
div#menu ul:first-child li
{
border-top: 0;
}
div#menu li.inline
{
height: 2.5em;
}
div#menu a#sm,
div#menu a#md,
div#menu a#lg
{
display: block;
line-height: 2.5em;
float: left;
width: 33px;
}
div#menu a, div#links a
{
display: block;
padding: 0;
line-height: 2.5em;
color: #f93;
}
div#menu a:hover,
div#links a:hover
{
background: #fff;
color: #900;
}
/* main colour palette */
div#palette
{
width: 540px;
position: absolute;
top: 50%;
left: 50%;
margin: -180px 0 0 -270px;
}
div#palette div
{
float: left;
}
div#palette a
{
display: block;
width: 30px;
height: 30px;
}
/* paintbox */
div#paintbox
{
position: absolute;
left: 30px;
}
div#paintbox div
{
padding-top: 30px;
text-align: right;
}
div#paintbox a.pb_patch
{
display: block;
height: 50px;
width: 50px;
}
div#paintbox a.pb_delete_dark,
div#paintbox a.pb_delete_light
{
position: relative;
top: -15px;
padding: 1px 4px 3px;
text-decoration: none;
}
div#paintbox a.pb_delete_dark
{
color: #fff;
}
div#paintbox a.pb_delete_dark:hover
{
background: #ccc;
color: #900;
}
div#paintbox a.pb_delete_light
{
color: #000;
}
div#paintbox a.pb_delete_light:hover
{
background: #333;
color: #f99;
}