- PVSM.RU - https://www.pvsm.ru -

Как создать свой Color Picker на Javascript?

Я знаю что в сети много подобных скриптов на разный вкус и цвет. Но мне захотелось написать свой с нуля и первое что я сделал полез в Гугл искать алгоритм создания(сolor picker). В итоге я был разочарован так как не нашел нечего кроме готовых скриптов, наверно поэтому после того как я разобрался и написал свой color picker, я решил поделится своим опытом в его написание.

Так как я пишу на чистом js без библиотек (не считая той которую я пишу сам:)) в данном посте будет только хардкор чистый javascript.
Что нужно знать что бы написать cp (сокращенно color picker):

  • Основы Drag'n'Drop [1]
  • Немного разбираться в Canvas (на нем будет рисоваться шкала оттенков Hue)

1.CSS & html

<div class="picker" id="primary_block" >

<div id="line">
<div id="arrows">
<div class="left_arrow"></div>
<div class="right_arrow"></div>
</div>
</div>

<div id="block_picker">

<img src="img/bgGradient.png" class="bk_img"><div id="circle"></div>
</div>

</div>

Думаю комментарии тут не нужны структура простейшая.
Теперь css

.right_arrow {
	
	width:0;
	height:0;
	left:23px;
	position:absolute;
	border-bottom:6px solid transparent;
	border-left:10px solid transparent;
	border-top:6px solid transparent;
	border-right:10px solid black;
}//левая стрелка почти аналогично 

.circle {
	width:8px;
	height:8px;
	border:1px solid black;
	border-radius:50%;
	position:absolute;
	left:0;
	top:0;
	cursor: default;
	-moz-user-select: none;
	-khtml-user-select: none;
	user-select: none; 
	  -webkit-user-select: none;   
	}

Это конечно не весь css код но больше нечего интересного нет (только позиционирование элементов ).

2.Javascript

Ну а теперь приступим к самому интересному, к Javascript.
Для начала нужно закончить структуру (т.е от рисовать шкалу Hue [2]), и делать я буду это на canvas (для уменьшения количества изображений).

gradient: function(canva,w,h){
/*
canva- объект canvas
h - высота шкалы
w- ширина
 */
  var context, gradient, hue;
			 
    context = canva.getContext("2d");
			      
	gradient = context.createLinearGradient(w/2,h,w/2,0);
				   
	 hue = [[255,0,0],[255,255,0],[0,255,0],[0,255,255],[0,0,255],[255,0,255],[255,0,0]];
         //цвета на шкале hue в rgb
				   
	     for (var i=0; i <= 6;i++){
		
	         color = 'rgb('+hue[i][0]+','+hue[i][1]+','+hue[i][2]+')';
	
	             gradient.addColorStop(i*1/6, color);
	
	                 };
				             
			context.fillStyle = gradient;
         	 
			   context.fillRect(0,0, w ,h);	
			 }	 	 

Посмотреть и «потрогать» то что получилось можно здесь [3]. Дальше пойдет тривиальное навешивание событий (поэтому этот код я пропущу).
Теперь разберем какую цветовую модель мы будем использовать, это будет HSV [2]

HSV — цветовая модель, в которой координатами цвета являются:

Hue — цветовой тон, (например, красный, зелёный или сине-голубой). Варьируется в пределах 0—360°, однако иногда приводится к диапазону 0—100 или 0—1.

Saturation — насыщенность. Варьируется в пределах 0—100 или 0—1. Чем больше этот параметр, тем «чище» цвет, поэтому этот параметр иногда называют чистотой цвета. А чем ближе этот параметр к нулю, тем ближе цвет к нейтральному серому.

Value (значение цвета) или Brightness — яркость. Также задаётся в пределах 0—100 и 0—1.

как реализовать это на нашем cp наглядно показано ниже(рис 1)

Как создать свой Color Picker на Javascript?

Шкала Hue у нас есть, нам добавить изменение Saturation и Value (значение цвета).
Так как значение S и V у нас 0-100, может возникнуть вопрос:
что делать если ширина и высота блока больше 100?
-

var px_X = elem.clientWidth / 100;
/*  
в переменной px у нас значение пикселя. Пример:
ширина блока 180
180/100 , при смещение на 1 пиксель наше значение должно увеличиваться на 1,8;
*/
var S = left / px_X;// в переменной left текущие смещение "круга" (div c id = "circle")относительно родителя
Math.round(S);//и не забываем округлять

При смещение «круга» отслеживаем изменения S и V (для визуального эффекта изменения цвета изменяем фон под картинкой(картинка полу прозрачная)).
Но для того что бы изменить фон на нужно конвертировать из HSV в RGB, сильно расписасывать этот этап я не буду так как тут [4] есть формула и если ее сравнить с кодом ниже все будет понятно.

 hsv_rgb: function (H,S,V){
	 var f , p, q , t, lH;
   
	  S /=100;
            V /=100;
     
	       lH = Math.floor(H / 60);
      
	          f = H/60 - lH;
                    
                     p = V * (1 - S); 
                     
                    q = V *(1 - S*f);
	       
                       t = V* (1 - (1-f)* S);
      
    switch (lH){
      
          case 0: R = V; G = t; B = p; break;
          case 1: R = q; G = V; B = p; break;
          case 2: R = p; G = V; B = t; break;
          case 3: R = p; G = q; B = V; break;
          case 4: R = t; G = p; B = V; break;
          case 5: R = V; G = p; B = q; break;
}
     
	 return [parseInt(R*255), parseInt(G*255), parseInt(B*255)];
	 }

писал сам так как то что находил в сети работало не корректно.
Надеюсь основные знания для создания cp я в этом посте дал, поэтому на этом я закончу потому что увеличивать функционал можно долго добавляю конвертацию в разные цветовые форматы…

3. Подведем Итоги

Вот что у меня получилось демо [5].
В этом посте старался объяснить как создать cp, не углубляясь сильно в код так как не видел в этом смысла в Drag`n`Drop нечего сложного нет!
Спасибо за внимание с вами был CyBer_UA и это мой первый пост о javascript (надеюсь не последний).
П.с код в итоговом примере кривоват (писался давно), просто только сейчас дошли руки написать этот пост.

Автор: cyber_ua


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/10717

Ссылки в тексте:

[1] Основы Drag'n'Drop: http://learn.javascript.ru/drag-and-drop

[2] Hue: http://ru.wikipedia.org/wiki/HSV_(%D1%86%D0%B2%D0%B5%D1%82%D0%BE%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C)

[3] здесь: http://learn.javascript.ru/play/zGDwd

[4] тут: http://ru.wikipedia.org/wiki/HSV_(%D1%86%D0%B2%D0%B5%D1%82%D0%BE%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C)#.D0.9F.D1.80.D0.B5.D0.BE.D0.B1.D1.80.D0.B0.D0.B7.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D1.8F_.D1.86.D0.B2.D0.B5.D1.82.D0.BE.D0.B2.D1.8B.D1.85_.D0.BA.D0.BE.D0.BC.D0.BF.D0.BE.D0.BD.D0.B5.D0.BD.D1.82.D0.BE.D0.B2_.D0.BC.D0.B5.D0.B6.D0.B4.D1.83_.D0.BC.D0.BE.D0.B4.D0.B5.D0.BB.D1.8F.D0.BC.D0.B8

[5] демо: http://learn.javascript.ru/play/7SuIfc