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

в 11:58, , рубрики: color picker, javascript, метки:

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

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

  • Основы Drag'n'Drop
  • Немного разбираться в 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), и делать я буду это на 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);	
			 }	 	 

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

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, сильно расписасывать этот этап я не буду так как тут есть формула и если ее сравнить с кодом ниже все будет понятно.

 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. Подведем Итоги

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

Автор: cyber_ua

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js