Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 12.04.2010, 20:55
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Ещё один Color Picker
Вот хочу поделиться с вами небольшим плагином для 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);


Ваши предложения и комментарии.
Вложения:
Тип файла: zip colorpicker.zip (37.9 Кб, 20 просмотров)

Последний раз редактировалось B~Vladi, 12.04.2010 в 21:21.
Ответить с цитированием
  #2 (permalink)  
Старый 12.04.2010, 21:30
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

А если CSS-градиенты попробовать использовать?
В Fx как-то так:
<div style="width: 200px; height: 40px; background: -moz-linear-gradient(left, red, yellow, cyan, blue, magenta);"></div>
Изображения:
Тип файла: jpg Снимок.jpg (14.4 Кб, 20 просмотров)

Последний раз редактировалось Octane, 12.04.2010 в 21:32.
Ответить с цитированием
  #3 (permalink)  
Старый 12.04.2010, 21:37
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Octane
А если CSS-градиенты попробовать использовать?
Ну про градиенты в FF я не слышал раньше... Только для IE. Они у себя на старом сайте майкрософт это использовали.

Т.е. ты предлагаешь в обработчиках события вычислять цвет по формуле? Тут важно написать правильную формулу Да и не факт что для IE эта формула подойдет...
А для других браузеров есть что-то подобное?

Зелёный забыл
Ответить с цитированием
  #4 (permalink)  
Старый 12.04.2010, 21:40
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

А, кста нельзя будет задавать ширину цвета... По-моему не плохой эффект получается
Ответить с цитированием
  #5 (permalink)  
Старый 12.04.2010, 22:10
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от B~Vladi
Ну про градиенты в FF я не слышал раньше...
Они в 3.6 появились вроде.

Сообщение от B~Vladi
Т.е. ты предлагаешь в обработчиках события вычислять цвет по формуле? Тут важно написать правильную формулу
Если в Photoshop водить ползунок вдоль такой же полоски, то меняется только H-составляющая цвета.

Сообщение от B~Vladi
Да и не факт что для IE эта формула подойдет...
Сообщение от B~Vladi
А, кста нельзя будет задавать ширину цвета...
Я еще не разбирался, как там что работает, но параметров много всяких можно указать, особенно в webkit.

Сообщение от B~Vladi
А для других браузеров есть что-то подобное?
CSS Gradients For All Web Browsers, Without Using Images


А еще градиент можно нарисовать на Canvas или при помощи SVG/VML
Gradients
Ответить с цитированием
  #6 (permalink)  
Старый 12.04.2010, 22:50
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,584

В данном случае это будет просто излишний кроссбраузерный онанизм.
Подобный градиент в пнг ничего не весит вообще.)
Ответить с цитированием
  #7 (permalink)  
Старый 12.04.2010, 22:55
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Octane
А еще градиент можно нарисовать на Canvas или при помощи SVG/VML
Я вкурсе про SVG & VML но нужна же ещё обёртка, потом нужно ещё генерировать цвета в обработчиках... В общем думается мне что кода будет больше...
Сообщение от Octane
Если в Photoshop водить ползунок вдоль такой же полоски, то меняется только H-составляющая цвета.
Ок, как перевести в RGB?
Ответить с цитированием
  #8 (permalink)  
Старый 12.04.2010, 22:55
Аватар для B~Vladi
Модератор Всея Форума
Отправить личное сообщение для B~Vladi Посмотреть профиль Найти все сообщения от B~Vladi
 
Регистрация: 14.05.2009
Сообщений: 4,021

Сообщение от Aetae
Подобный градиент в пнг ничего не весит вообще.
Да не нужен тут PNG... Кода получилось совсем не много...
Ответить с цитированием
  #9 (permalink)  
Старый 12.04.2010, 23:00
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Сообщение от Aetae
В данном случае это будет просто излишний кроссбраузерный онанизм.
Просто ради интереса))

Сообщение от B~Vladi
Ок, как перевести в RGB?
http://fastcoder.org/articles/?aid=154
Ответить с цитированием
  #10 (permalink)  
Старый 12.04.2010, 23:01
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,584

svg,vml,canvas,-gradient - это всё нифига не кроссбраузерно.
Рисовать дивами - в данном конкретном случае можно, но более детально - во-первых тормоза, а во вторых куча мусорного кода.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выделить группу чекбоксов. В группе может быть только один чекбокс. JooZ Элементы интерфейса 2 23.12.2009 19:28
глюк форума Gvozd Сайт Javascript.ru 11 18.03.2009 14:37
Еще один вопрос по setTimeout setInterval Хранитель Света Общие вопросы Javascript 5 12.03.2009 22:37
Еще один вариант плавно раскрывающегося дива (экспандер, спойлер) Alekson Ваши сайты и скрипты 0 23.12.2008 03:01
не получается вложить один эффект в другой svip Библиотеки/Тулкиты/Фреймворки 1 30.03.2008 11:07