/* colorPicker for script.aculo.us, version 0.9 REQUIRES prototype.js, yahoo.color.js and script.aculo.us written by Matthias Platzer AT knallgrau.at for a detailled documentation go to http://www.knallgrau.at/code/colorpicker */ if(!Control) var Control = {}; Control.colorPickers = []; Control.ColorPicker = Class.create(); Control.ColorPicker.activeColorPicker; Control.ColorPicker.CONTROL; /** * ColorPicker Control allows you to open a little inline popUp HSV color chooser. * This control is bound to an input field, that holds a hex value. */ Control.ColorPicker.prototype = { initialize : function(field, options) { var colorPicker = this; Control.colorPickers.push(colorPicker); this.field = $(field); this.fieldName = this.field.name || this.field.id; this.options = Object.extend({ IMAGE_BASE : "img/" }, options || {}); this.swatch = $(this.options.swatch) || this.field; this.rgb = {}; this.hsv = {}; this.isOpen = false; // create control (popUp) if not already existing // all colorPickers on a page share the same control (popUp) if (!Control.ColorPicker.CONTROL) { Control.ColorPicker.CONTROL = {}; if (!$("colorpicker")) { var control = Builder.node('div', {id: 'colorpicker'}); control.innerHTML = '
' + ( // apply png fix for ie 5.5 and 6.0 (/MSIE ((6)|(5\.5))/gi.test(navigator.userAgent) && /windows/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) ? '' : '' ) + '
' + '
' + '
' + '' document.body.appendChild(control); } Control.ColorPicker.CONTROL = { popUp : $("colorpicker"), pickerArea : $('colorpicker-div'), selector : $('colorpicker-selector'), okButton : $("colorpicker-okbutton"), value : $("colorpicker-value"), input : $("colorpicker-value-input"), picker : new Draggable($('colorpicker-selector'), { snap: function(x, y) { return [ Math.min(Math.max(x, 0), Control.ColorPicker.activeColorPicker.control.pickerArea.offsetWidth), Math.min(Math.max(y, 0), Control.ColorPicker.activeColorPicker.control.pickerArea.offsetHeight) ]; }, zindex: 1009, change: function(draggable) { var pos = draggable.currentDelta(); Control.ColorPicker.activeColorPicker.update(pos[0], pos[1]); } }), hueSlider: new Control.Slider('colorpicker-hue-thumb', 'colorpicker-hue-slider', { axis: 'vertical', onChange: function(v) { Control.ColorPicker.activeColorPicker.updateHue(v); } }) }; Element.hide($("colorpicker")); } this.control = Control.ColorPicker.CONTROL; // bind event listener to properties, so we can use them savely with Event[observe|stopObserving] this.toggleOnClickListener = this.toggle.bindAsEventListener(this); this.updateOnChangeListener = this.updateFromFieldValue.bindAsEventListener(this); this.closeOnClickOkListener = this.close.bindAsEventListener(this); this.updateOnClickPickerListener = this.updateSelector.bindAsEventListener(this); Event.observe(this.swatch, "click", this.toggleOnClickListener); Event.observe(this.field, "change", this.updateOnChangeListener); Event.observe(this.control.input, "change", this.updateOnChangeListener); this.updateSwatch(); }, toggle : function(event) { this[(this.isOpen) ? "close" : "open"](event); Event.stop(event); }, open : function(event) { Control.colorPickers.each(function(colorPicker) { colorPicker.close(); }); Control.ColorPicker.activeColorPicker = this; this.isOpen = true; Element.show(this.control.popUp); if (this.options.getPopUpPosition) { var pos = this.options.getPopUpPosition.bind(this)(event); } else { var pos = Position.cumulativeOffset(this.swatch || this.field); pos[0] = (pos[0] + (this.swatch || this.field).offsetWidth + 10); } this.control.popUp.style.left = (pos[0]) + "px"; this.control.popUp.style.top = (pos[1]) + "px"; this.updateFromFieldValue(); Event.observe(this.control.okButton, "click", this.closeOnClickOkListener); Event.observe(this.control.pickerArea, "mousedown", this.updateOnClickPickerListener); if (this.options.onOpen) this.options.onOpen.bind(this)(event); }, close : function(event) { if (Control.ColorPicker.activeColorPicker == this) Control.ColorPicker.activeColorPicker = null; this.isOpen = false; Element.hide(this.control.popUp); Event.stopObserving(this.control.okButton, "click", this.closeOnClickOkListener); Event.stopObserving(this.control.pickerArea, "mousedown", this.updateOnClickPickerListener); if (this.options.onClose) this.options.onClose.bind(this)(); }, updateHue : function(v) { var h = (this.control.pickerArea.offsetHeight - v * 100) / this.control.pickerArea.offsetHeight; if (h == 1) h = 0; var rgb = YAHOO.util.Color.hsv2rgb( h, 1, 1 ); if (!YAHOO.util.Color.isValidRGB(rgb)) return; this.control.pickerArea.style.backgroundColor = "rgb(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ")"; this.update(); }, updateFromFieldValue : function(event) { if (!this.isOpen) return; var field = (event && Event.findElement(event, "input")) || this.field; var rgb = YAHOO.util.Color.hex2rgb( field.value ); if (!YAHOO.util.Color.isValidRGB(rgb)) return; var hsv = YAHOO.util.Color.rgb2hsv( rgb[0], rgb[1], rgb[2] ); this.control.selector.style.left = Math.round(hsv[1] * this.control.pickerArea.offsetWidth) + "px"; this.control.selector.style.top = Math.round((1 - hsv[2]) * this.control.pickerArea.offsetWidth) + "px"; this.control.hueSlider.setValue((1 - hsv[0])); }, updateSelector : function(event) { var xPos = Event.pointerX(event); var yPos = Event.pointerY(event); var pos = Position.cumulativeOffset($("colorpicker-bg")); this.control.selector.style.left = (xPos - pos[0] - 6) + "px"; this.control.selector.style.top = (yPos - pos[1] - 6) + "px"; this.update((xPos - pos[0]), (yPos - pos[1])); this.control.picker.initDrag(event); }, updateSwatch : function() { var rgb = YAHOO.util.Color.hex2rgb( this.field.value ); if (!YAHOO.util.Color.isValidRGB(rgb)) return; this.swatch.style.backgroundColor = "rgb(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ")"; var hsv = YAHOO.util.Color.rgb2hsv( rgb[0], rgb[1], rgb[2] ); this.swatch.style.color = (hsv[2] > 0.65) ? "#000000" : "#FFFFFF"; }, update : function(x, y) { if (!x) x = this.control.picker.currentDelta()[0]; if (!y) y = this.control.picker.currentDelta()[1]; var h = (this.control.pickerArea.offsetHeight - this.control.hueSlider.value * 100) / this.control.pickerArea.offsetHeight; if (h == 1) { h = 0; }; this.hsv = { hue: 1 - this.control.hueSlider.value, saturation: x / this.control.pickerArea.offsetWidth, brightness: (this.control.pickerArea.offsetHeight - y) / this.control.pickerArea.offsetHeight }; var rgb = YAHOO.util.Color.hsv2rgb( this.hsv.hue, this.hsv.saturation, this.hsv.brightness ); this.rgb = { red: rgb[0], green: rgb[1], blue: rgb[2] }; this.field.value = YAHOO.util.Color.rgb2hex(rgb[0], rgb[1], rgb[2]); this.control.input.value = this.field.value; this.updateSwatch(); if (this.options.onUpdate) this.options.onUpdate.bind(this)(this.field.value); } }