Вот хочу поделиться с вами небольшим плагином для jQuery. Т.к. не нашел ничего подобного из аналогов, написал сам. Может кому и пригодиться.
Отличия от остальных в том, что не используется графика и цвет можно выбирать только из спектра (т.е. без смешивания каналов). Если кому не нужна полная палитра - очень пригодиться. Демка лежит во вложении, так же выложу код сюда, чтобы можно было не качать.
(function($){
var settings = { // Настройки по умолчанию
// Свойства, передаваемые плагину (не обязательные):
width:100, // Ширина линии спектра
height:20, // Высота линии спектра
colorSize:1, // Ширина одного цвета
setColor: null, // Установка начального цвета для спектра
marker: null, // Селектор или DOM-элемент маркера
onMouseDown: null, // Обработчик события при mousedown
onMouseMove: null, // Обработчик события при mousemove
onMouseUp: null, // Обработчик события при mouseup
// Свойства, доступные в обработчиках события через this
colors: [], // Массив всех сгенерированных цветов.
dom: null // DOM-элемент линии спектра
};
var handlers = (function(){ // Обработчики событий линии спектра
var opt; // Опции спектра
function getColor(evt){ // Получение цвета
if(evt.pageX < opt.dom.offsetLeft){
return opt.colors[0];
} else {
return opt.colors[Math.floor((evt.pageX - opt.dom.offsetLeft) / opt.colorSize) * opt.colorSize - opt.colorSize] || opt.colors[opt.colors.length - 1];
}
}
function setMarkerPosition(evt){ // Установка позиции маркера
if(opt.marker){
var mWidth = opt.marker.offsetWidth / 2,
oLeft = opt.dom.offsetLeft,
oRight = opt.dom.offsetWidth + oLeft - mWidth,
newPosition = evt.pageX - mWidth;
if(newPosition < oLeft - mWidth){
opt.marker.style.left = oLeft - mWidth + 'px';
} else if(newPosition > oRight){
opt.marker.style.left = oRight + 'px';
} else {
opt.marker.style.left = newPosition + 'px';
}
}
}
return {
onMouseDown: function(evt, data){ // Нажатие на спектр
evt = data || evt;
opt = evt.data;
if(!evt.pageX){
evt.pageX = evt.target.offsetLeft + opt.dom.offsetLeft + evt.target.offsetWidth;
}
setMarkerPosition(evt);
if($.isFunction(opt.onMouseDown)){
opt.onMouseDown(getColor(evt));
}
$(document).bind('mousemove', handlers.onMouseMove).bind('mouseup', handlers.onMouseUp);
return false;
},
onMouseMove: function(evt){ // Драг маркера
setMarkerPosition(evt);
if(opt.onMouseMove){
opt.onMouseMove(getColor(evt));
}
return false;
},
onMouseUp: function(evt){ // Остановка драга маркера
setMarkerPosition(evt);
if(opt.onMouseUp && evt.pageX){
opt.onMouseUp(getColor(evt));
}
$(document).unbind('mousemove', handlers.onMouseMove).unbind('mouseup', handlers.onMouseUp);
return false;
}
}
})();
function markerEvent(evt){ // Обработчик события маркера
$(evt.data.dom).trigger('mousedown', evt);
return false;
}
$.fn.extend({
colorPicker: function(opt){ // colorPicker - имя плагина
var dom = this[0]; // this[0] = линия спектра
// Применение настроек
var domWidth = dom.offsetWidth;
var domHeight = dom.offsetHeight;
if(typeof opt.width != 'number' && domWidth > 0){
opt.width = domWidth;
}
if(typeof opt.height != 'number' && domHeight > 0){
opt.height = domHeight;
}
opt = $.extend(settings, opt);
opt.dom = dom;
opt.marker = $(opt.marker)[0];
// Необходимые стили для спектра
dom.style.cssText = 'display: block; ' +
'lihe-height: ' + opt.height + 'px; ' +
'width: ' + opt.width + 'px; ' +
'height: ' + opt.height + 'px; ' +
'position: relative;' +
'overflow: hidden';
// Инициализация маркера
if(opt.marker){
opt.marker.style.position = 'absolute';
opt.marker.style.display = 'block';
opt.marker.style.top = dom.offsetTop + (opt.height / 2) - (opt.marker.offsetHeight / 2) + 'px';
$(opt.marker).bind('mousedown', opt, markerEvent);
}
// Установка обработчика линии спектра
this.bind('mousedown', opt, handlers.onMouseDown);
// Генерация цветов спектра
var colors = [];
var colorLength = opt.width / 6;
for(var i = 0, l = Math.ceil(colorLength / opt.colorSize); i < l; i++){
var tmpColor = Math.ceil((i * opt.colorSize) * 255 / colorLength).toString(16);
colors.push((i == l-1) ? 'ff' : (tmpColor.length == 1) ? '0' + tmpColor : tmpColor);
}
var rgb = {
r: colors.slice(0).reverse(),
g: colors.slice(0),
b: colors.slice(0)
},
colorsIndex = {
r : 0,
g : 0,
b : 0
},
channels = ['g', 'r', 'b'],
channelIndex = 0,
fragment = document.createDocumentFragment(),
setColor;
for(i = 0, l = opt.width / opt.colorSize; i < l; i++){
var chanel = channels[channelIndex];
if(colorsIndex[chanel] == colors.length-1){
rgb[chanel].reverse();
colorsIndex[chanel] = 0;
channelIndex++;
if(channelIndex == channels.length){
channelIndex = 0;
}
} else {
colorsIndex[chanel]++;
}
var newDiv = document.createElement('div'),
newColor = '#' + rgb.r[colorsIndex.r] + rgb.g[colorsIndex.g] + rgb.b[colorsIndex.b];
opt.colors[i * opt.colorSize] = newColor;
newDiv.style.cssText = 'background-color: ' + newColor + '; ' +
'float: left; ' +
'width: '+ opt.colorSize +'px; ' +
'height: '+ opt.height +'px; ';
newDiv.appendChild(document.createTextNode(' '));
fragment.appendChild(newDiv);
if(newColor == opt.setColor){
setColor = newDiv;
}
}
dom.appendChild(fragment);
// Установка начального положения маркера
$(setColor || dom.firstChild).trigger('mousedown').trigger('mouseup');
}
});
})(jQuery);
Ваши предложения и комментарии.