Sixtest Wiki:API5/Color

$API("Project:API5/Color", function (color) {	"use strict";	color.extend({ options: { /* PLANNED LIST OF OPTIONS */ theme_name: "", theme_color_model: "hsv", color_base: [], contrast_ratio: "", brightness_factor: "", font_size: "", // element_list: [ "a", "abbre",  "acronym",  "address",  "applet",  "area",  "b",  "base",  "bdo",  "big",  "blockquote",  "body",  "br",  "button",  "caption",  "center",  "cite",  "code",  "col",  "colgroup",  "dd",  "del",  "dfn",  "dir",  "div",  "dl",  "dt",  "em",  "fieldset",  "form",  "frame",  "frameset",  h1,  h2,  h3,  h4,  h5,  h6,  "head",  "hr",  "html",  "i",  "iframe",  "img",  "input",  "ins",  "kbd",  "label",  "legend",  "li",  "link",  "map",  "meta",  "noframes",  "noscript",  "object",  "ol",  "optgroup",  "option",  "p",  "param",  "pre",  "q",  "s",  "samp",  "script",  "select",  "small",  "span",  "strong",  "style",  "sub",  "sup",  "table",  "tbody",  "td",  "textarea",  "tfoot",  "th",  "thead",  "title",  "tr",  "tt",  "ul",  "var" ], /* Supported options*/ use: "hsv", },		// TODO: work on completing color model conversions rgb: [ 0, 0, 0 ], //hsv: [ 0, 0, 0 ], hsv: [ 160, 50, 50 ], hsl: [ 0, 0, 0 ], yuv: [ 0, 0, 0 ], lab: [ 0, 0, 0 ], convert: { rgb: { rgb: function (rgb) { return rgb; }, hsv: function (rgb) { var rgb_min, rgb_max, r, g, b, h, s, v;					r = rgb[0]; g = rgb[1]; b = rgb[2]; rgb_min = color.util.min(r, g, b); rgb_max = color.util.max(r, g, b); v = rgb_max / 255; if (v === 0) { h = s = 0; return [ h, s, v ]; }					r = r / (v * 255); g = g / (v * 255); b = b / (v * 255); rgb_min = color.util.min(r, g, b); rgb_max = color.util.max(r, g, b); s = rgb_max - rgb_min; if (s === 0) { h = 0; return [ h, s, v ]; }					r = (r - rgb_min) / s;					g = (g - rgb_min) / s;					b = (b - rgb_min) / s;					rgb_min = color.util.min(r, g, b); rgb_max = color.util.max(r, g, b); h = (360 + (rgb_max === r ? 60 * (g - b) : (rgb_max === g ? 120 + 60 * (b - r) : (240 + 60 * (r - g))))) % 360; return [ h, s, v ]; },				yiq: function (rgb) { var r = rgb[0], g = rgb[1], b = rgb[2], y, i, q;					y = 0.299 * r + 0.587 * g + 0.114 * b;					i = 0.595716 * r + -0.274453 * g + -0.321263 * b;					q = 0.211456 * r + -0.522591 * g + 0.311135 * b;					return [ y, i, q ]; },				yuv: function (rgb) { var r = rgb[0], g = rgb[1], b = rgb[2]; return [ color.util.clip(Math.round(0.299 * r + 0.587 * g + 0.114 * b), 0, 255), color.util.clip(Math.round(-0.14713 * r + -0.28886 * g + 0.436 * b), 0, 255), color.util.clip(Math.round(0.615 * r + -0.51499 * g + -0.10001 * b), 0, 255) ];				}			},			hsv: { rgb: function (hsv) { var h, s, v, chroma, mH, mI, rgb, vmc; h = Math.abs(hsv[0]) % 360; s = (hsv[1] < 0 ? Math.abs(hsv[1]) % 1 : (hsv[1] > 1 ? hsv[1] % 1 : hsv[1])); v = (hsv[2] < 0 ? Math.abs(hsv[2]) % 1 : (hsv[2] > 1 ? hsv[2] % 1 : hsv[2])); chroma = v * s;					mH = h / 60; mI = chroma * (1 - (Math.abs((mH % 2) - 1))); vmc = v - chroma; if (0 <= mH) { if (mH < 1) { rgb = [ chroma, mI, 0 ]; } else if (mH < 2) { rgb = [ mI, chroma, 0 ]; } else if (mH < 3) { rgb = [ 0, chroma, mI ]; } else if (mH < 4) { rgb = [ 0, mI, chroma ]; } else if (mH < 5) { rgb = [ mI, 0, chroma ]; } else if (mH < 6) { rgb = [ chroma, 0, mI ]; }					}					return [ Math.round((rgb[0] + vmc)*255), Math.round((rgb[1] + vmc)*255), Math.round((rgb[2] + vmc)*255) ];				},				hsv: function (hsv) { return hsv; }, hsl: null, yuv: null, lab: null },			hsl: { rgb: null, hsv: null, hsl: function (hsl) { return hsl; }, yuv: null, lab: null },			yuv: { rgb: function (yuv) { var y, u, v, r, g, b, rgb; y = yuv[0]; u = yuv[1]; v = yuv[2]; r = color.util.clip(Math.round(y + 1.13983 * v), 0, 255); g = color.util.clip(Math.round(y + -0.39465 * u + -0.58060 * v), 0, 255); b = color.util.clip(Math.round(y + 2.03211 * u), 0, 255); rgb = [ r, g, b ]; return rgb; },				hsv: null, hsl: null, yuv: function (yuv) { return yuv; }, lab: null },			lab: { rgb: null, hsv: null, hsl: null, yuv: null, lab: function (lab) { return lab; } }		},		util: { clip: function (val, min, max) { return (val < min ? min : (val > max ? max : val)); },			min: function { var i = 0, len = arguments.length, min; for (i; i < len; i += 1) { if (min === undefined || arguments[i] < min) { min = arguments[i]; }				}				return min; },			max: function { var i = 0, len = arguments.length, max; for (i; i < len; i += 1) { if (max === undefined || arguments[i] > max) { max = arguments[i]; }				}				return max; },			inverse: function (rgb, max) { var r = rgb[0], g = rgb[1], b = rgb[2]; max = max || 255; return [ max - r,					max - g,					max - b				]; },			round: function (arr) { var i = 0, len = arr.length, out = []; if (typeof arr === 'object') { for (i; i < len; i += 1) { out[i] = color.util.round(arr[i]); }					return out; }				return Math.round(arr); },			slider: function (setting) { var sliders = [], hue = document.createElement('div'), saturation = document.createElement('div'), value = document.createElement('div'), colorBox = document.createElement('div'), // [min, max, current] hue_val = [0, 359, 0, "Hue"], saturation_val = [0, 100, 0, "Saturation"], value_val = [0, 100, 0, "Value"], settings, i = 0, len; setting = setting || {}; settings = { parent: setting.parent || document.getElementById("API-Interface"), container: setting.container || document.createElement('div'), callback: setting.callback || null, slidebar_width: setting.slidebar_width !== undefined? setting.slidebar_width : 275, model: setting.model || "HSV", sliders: setting.sliders || [ { header: "Hue", value_min: 0, value_max: 359, value_curr: 180, factor: 1 }, { header: "Saturation", value_min: 0, value_max: 100, value_curr: 50, factor: 0.01 }, { header: "Value", value_min: 0, value_max: 100, value_curr: 50, factor: 0.01 } ]				};				/* OK */ settings.container.className = 'colorpicker'; colorBox.className = 'color'; settings.container.appendChild(colorBox); settings.parent.appendChild(settings.container); function colorUpdate { var sliders = settings.sliders, i = 0, len = sliders.length, hsv = [], res, rgb = []; if (settings.model === "HSV") { for (i; i < len; i += 1) { hsv[i] = sliders[i].value_curr * (sliders[i].factor || 1); }						rgb = color.convert.hsv.rgb(hsv); rgb[0] = Math.round(rgb[0]); rgb[1] = Math.round(rgb[1]); rgb[2] = Math.round(rgb[2]); colorBox.style.backgroundColor = "rgb(" + rgb.join(",") + ")"; return rgb; }				}				/* /OK */ function slider(cslider) { var ele = document.createElement('div'), ele_header = document.createElement('div'), ele_slidebar = document.createElement('div'), ele_slider = document.createElement('div'), ele_number = document.createElement('div'), max_pos = settings.slidebar_width, max_value = cslider.value_max || null, min_value = cslider.value_min || null; ele_header.className = 'header'; ele_header.appendChild(document.createTextNode( cslider.text !== undefined ? cslider.text : cslider.header.charAt(0) )); ele_slidebar.draggable = "true"; ele_slidebar.className = 'slidebar'; ele_slidebar.style.width = max_pos + "px"; ele_slidebar.appendChild(ele_slider); ele_slider.className = 'slider'; ele_number.className = 'number'; // append slider to slidebar // append elements to ele ele.appendChild(ele_header); ele.appendChild(ele_slidebar); ele.appendChild(ele_number); // and ele to main interface settings.container.appendChild(ele); function getOffset(element) { var x = 0, y = 0; while (element && !isNaN(element.offsetTop) && !isNaN(element.offsetLeft)) { x += element.offsetLeft - element.scrollLeft; y += element.offsetTop - element.scrollTop; element = element.offsetParent; }						return [ x, y ]; }					function sliderDisplayNumber(perc) { while (ele_number.firstChild) { ele_number.removeChild(ele_number.firstChild); }						ele_number.appendChild(document.createTextNode( Math.round(perc * 100) / 100 )); }					function sliderMouseMove(e, pos) { var offset, width; offset = getOffset(ele_slidebar); width = ele_slidebar.offsetWidth; if (pos === undefined) { if (!e || e.clientX === undefined) { throw new Error("Position cannot be determined."); }							pos = (e.clientX - offset[0]) / width * max_value; }						if (pos > max_value) { pos = max_value; }						if (pos < min_value) { pos = min_value; }						ele_slider.style.left = pos / max_value * width - Math.round(ele_slider.offsetWidth / 2) + "px"; sliderDisplayNumber(pos); cslider.value_curr = pos; if (settings.callback) { settings.callback(colorUpdate); } else { colorUpdate; }					}					function sliderMouseUp { window.removeEventListener("mousemove", sliderMouseMove); }					function sliderMouseDown(e) { sliderMouseMove(e); window.addEventListener("mousemove", sliderMouseMove); window.addEventListener("mouseup", sliderMouseUp); }					sliderMouseMove(undefined, cslider.value_curr || 0); ele_slidebar.onmousedown = sliderMouseDown; ele_slidebar.draggable = "true"; }				for (i, len = settings.sliders.length; i < len; i += 1) { slider(settings.sliders[i]); }			}		},		style: function (element, depth) { var rgb_light_base, rgb_light_base_text, rgb_light_base_text2, ccolor = this[this.options.theme_color_model], color; color = [ ccolor[0], ccolor[1], ccolor[2] ]; color[1] = color[1] - depth * this.options.brightness_factor; color[1] = color[1] > 1 ? 1 : color[1] < 0 ? 0 : color[1]; // TODO: color, border element.style.backgroundColor = "rgb(" + this.util.round(this.convert.hsv.rgb(color)).join(",") + ")"; },		colorIt: function (settings) { var func, element = document.getElementById("API-Interface"); this.hsv = this.convert[this.options.theme_color_model].hsv(this[this.options.theme_color_model]); this.options.theme_color_model = "hsv"; function colorElement(element, depth) { var i = 0, len = element.children.length; color.style(element, +depth); if (len) { for (i; i < len; i += 1) { colorElement(element.children[i], depth + 1); }				}			}			colorElement(element, 0); }	}); });