// A nutty little DHTML Color Picker // By Martin Atkins aka Mart var colpic_imgprefix = '/img'; // spawnPicker - create a picker window function spawnPicker(dataobject, displayobject, des) { var p = window.open("","colorpick_"+dataobject.name,"width=560,height=450"); var d = p.document; // declare the data storage object in the picker's scope d.write(''); var dat = p.picker; dat.dataobject = dataobject; dat.displayobject = displayobject; dat.current = ''+dataobject.value; dat.r = 0; dat.g = 0; dat.b = 0; dat.h = 0; dat.s = 0; dat.v = 0; // Copy some functions into the picker's scope so events can hit them p._HSVtoRGB = _HSVtoRGB; p._varstoform = _varstoform; p.setBGColor = setBGColor; p.findel = findel; d.write(""+des+""); _createInterface(p); d.close(); findel('spectrum',d).onclick=function(evt) { if (! evt) { evt = p.event; } var x, y; if (evt.offsetX != null) { x = evt.offsetX; y = evt.offsetY; } else if (evt.pageX != null) { x = evt.pageX - 6; y = evt.pageY - 6; } else if (evt.clientX != null) { x = evt.clientX - 6; y = evt.clientY - 6; } else { p.alert('Your mouseclick could not be handled. Sorry.'); } // var x = evt.offsetX || (evt.pageX ? evt.pageX - 6 : false) || (evt.clientX - 6); // var y = evt.offsetY || (evt.pageY ? evt.pageX - 6 : false) || (evt.clientY - 6); p.picker.h = Math.abs(p.Math.floor(x / 2) % 256); p.picker.s = Math.abs(y % 255); p._HSVtoRGB(p); p._varstoform(p); }; findel('brightness',d).onclick=function(evt) { if (! evt) { evt = p.event; } p.picker.v = Math.abs((evt.offsetY || (evt.pageY - 6)) % 255); p._HSVtoRGB(p); p._varstoform(p); }; findel('btnCancel',d).onclick=function() { p.close(); }; findel('btnOK',d).onclick=function() { dataobject.value=p.picker.current; p.setBGColor(displayobject,p.picker.current); p.close(); }; // The crosshair prevents clicks under it, so fake events for it findel('crosshair',d).onclick=function(evt) { if (! evt) { evt = p.event; } var fakeevt = new Object; fakeevt.pageX = evt.pageX; fakeevt.pageY = evt.pageY; fakeevt.clientX = evt.clientX; fakeevt.clientY = evt.clientY; findel('spectrum',p.document).onclick(fakeevt); }; findel('fr',d).onchange= findel('fg',d).onchange= findel('fb',d).onchange=function() { dat.r = Math.abs(findel('fr',d).value % 256); dat.g = Math.abs(findel('fg',d).value % 256); dat.b = Math.abs(findel('fb',d).value % 256); _RGBtoHSV(p); _varstoform(p); } findel('fh',d).onchange= findel('fs',d).onchange= findel('fv',d).onchange=function() { dat.h = Math.abs(findel('fh',d).value % 255); dat.s = Math.abs(findel('fs',d).value % 256); dat.v = Math.abs(findel('fv',d).value % 256); _HSVtoRGB(p); _varstoform(p); } _setcolor(p,dat.current); return false; } function setBGColor(displayobject, colorstring) { displayobject.style.backgroundColor = colorstring; } function findel(id,doc) { if (! doc) { doc = document; } return doc.getElementById(id); } function _varstoform(p) { var d = p.document; var dat = p.picker; findel("fr",d).value=dat.r; findel("fg",d).value=dat.g; findel("fb",d).value=dat.b; findel("fh",d).value=dat.h; findel("fs",d).value=dat.s; findel("fv",d).value=dat.v; dat.current = "#"+_hex(dat.r)+ _hex(dat.g)+ _hex(dat.b); setBGColor(findel('preview',p.document),dat.current); _updatebrightnessgrad(p); _placeindicators(p); } function _updatebrightnessgrad(p) { var grad = findel("brightness",p.document); var fbc = new Object; fbc.h=p.picker.h; fbc.s=p.picker.s; fbc.v=255; _HSVtoRGB(p,fbc); gradclr = _hex(fbc.r)+ _hex(fbc.g)+ _hex(fbc.b); var newgradurl = "/palimg/colorpicker/longgrad.gif/pg00000000ff"+gradclr.toLowerCase(); var oldgradurl = grad.src; if (oldgradurl != newgradurl) { grad.src = newgradurl; } } function _placeindicators(p) { var d = p.document; var pointer = findel('pointer',d); var crosshair = findel('crosshair',d); pointer.style.top = (p.picker.v + 3)+"px"; crosshair.style.top = (p.picker.s - 1)+"px"; crosshair.style.left = ((p.picker.h * 2) - 1)+"px"; pointer.style.display = ''; crosshair.style.display = ''; } function _setcolor(p,htmlcolor) { p.picker.current = htmlcolor; var clrparts = _colorfromstring(htmlcolor); p.picker.r = clrparts[1]; p.picker.g = clrparts[2]; p.picker.b = clrparts[3]; _RGBtoHSV(p); _varstoform(p); } function _RGBtoHSV(p,dat) { if (! dat) { dat = p.picker; } var r = dat.r; var g = dat.g; var b = dat.b; r = (r % 256) / 255; g = (g % 256) / 255; b = (b % 256) / 255; var min = 255, max = 0, h, s, v, hi, diff; var rgb = new Array(0,r,g,b); for (var i = 1; i <= 3; i++) { if (rgb[i] > max) { max = rgb[i]; hi = 1; } if (rgb[i] < min) { min = rgb[i]; } } diff = max - min; v = max; if (max == 0) { s = 0; } else { s = diff / max; } if (s == 0) { h = 0; } else { switch (hi) { case 1: h = (g - b) / diff; break; case 2: h = 2 + (b - r) / diff; break; case 3: h = 4 + (r - g) / diff; break; } h = h / 6; if (h < 0) { h = h + 1; } } dat.h = Math.floor(h * 255); dat.s = Math.floor(s * 255); dat.v = Math.floor(v * 255); } function _HSVtoRGB(p,dat) { if (! dat) { dat = p.picker; } var h = dat.h; var s = dat.s; var v = dat.v; // If value is zero, return black. if (v == 0) { dat.r = dat.g = dat.b = 0; return; } // If there's no saturation, return a grey. if (s == 0) { dat.r = dat.g = dat.b = v; return; } h = (h % 255) / 255; s = (s % 256) / 255; v = (v % 256) / 255; var t, aa, bb, cc, r, g, b; t = p.Math.floor(h * 6); // Find which color's range we're in. f = (h * 6) - t; aa = v * (1 - s); bb = v * (1 - s * f); cc = v * (1 - (s * (1 - f))); switch (t) { case 0: r=v; g=cc; b=aa; break; case 1: r=bb; g=v; b=aa; break; case 2: r=aa; g=v; b=cc; break; case 3: r=aa; g=bb; b=v; break; case 4: r=cc; g=aa; b=v; break; default: r=v; g=aa; b=bb; break; } dat.r = p.Math.floor(r * 255) % 256; dat.g = p.Math.floor(g * 255) % 256; dat.b = p.Math.floor(b * 255) % 256; return; } // Fun with Regular Expressions function _colorfromstring(strcolor) { var clrparts; strcolor = strcolor.toLowerCase(); if ((clrparts = strcolor.match( /^#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/ )) != null) { for (var i=1; i<=3; i++) { clrparts[i] = parseInt(clrparts[i],16); } return clrparts; } else if ((clrparts = strcolor.match( /^rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/ )) != null) { for (var i=1; i<=3; i++) { if (clrparts[i]<0 || clrparts[i]>255) { return [0,0,0,0]; } return clrparts; } } return [0,255,255,255]; } function _hex(i) { var r = ''; var h = new Array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); for (var x = 0; x < 32; x++) { if (Math.pow( 16, x + 1 ) > i) break; } for ( var y = x; y >= 0; y-- ) { var z = Math.pow( 16, y ); r += h[ Math.floor ( i / z ) ]; i = i % z; } r = ( r.length == 0 ) ? '0' : r; while ( r.length < 2 ) { r = '0' + r; } return r } function _createInterface(p) { var curclr = p.picker.current; var d = p.document; d.write(''); d.write('\n'); d.write('\n'); d.write('
\n'); d.write('
\n'); d.write('
\n'); d.write('\n'); _writeControlRow(d,'Hue','fh'); _writeControlRow(d,'Red','fr'); d.write('\n'); _writeControlRow(d,'Saturation','fs'); _writeControlRow(d,'Green','fg'); d.write('\n'); _writeControlRow(d,'Lightness','fv'); _writeControlRow(d,'Blue','fb'); d.write('
 
\n'); d.write('
'+ ' '+ '
'); d.write('
\n'); d.write('\n'); d.write('\n'); } function _writeControlRow(doc,caption,name) { doc.write('\n'); } function colPic_set_imgprefix(prefix) { colpic_imgprefix = prefix; }