Я знаю что в сети много подобных скриптов на разный вкус и цвет. Но мне захотелось написать свой с нуля и первое что я сделал полез в Гугл искать алгоритм создания(сolor picker). В итоге я был разочарован так как не нашел нечего кроме готовых скриптов, наверно поэтому после того как я разобрался и написал свой color picker, я решил поделится своим опытом в его написание.
Так как я пишу на чистом js без библиотек (не считая той которую я пишу сам:)) в данном посте будет толькохардкор чистый javascript.
Что нужно знать что бы написать cp (сокращенно color picker):
Думаю комментарии тут не нужны структура простейшая.
Теперь css
Это конечно не весь css код но больше нечего интересного нет (только позиционирование элементов ).
Ну а теперь приступим к самому интересному, к Javascript.
Для начала нужно закончить структуру (т.е от рисовать шкалу Hue), и делать я буду это на canvas (для уменьшения количества изображений).
Посмотреть и «потрогать» то что получилось можно здесь. Дальше пойдет тривиальное навешивание событий (поэтому этот код я пропущу).
Теперь разберем какую цветовую модель мы будем использовать, это будет HSV

Шкала Hue у нас есть, нам добавить изменение Saturation и Value (значение цвета).
Так как значение S и V у нас 0-100, может возникнуть вопрос:
что делать если ширина и высота блока больше 100?
-
При смещение «круга» отслеживаем изменения S и V (для визуального эффекта изменения цвета изменяем фон под картинкой(картинка полу прозрачная)).
Но для того что бы изменить фон на нужно конвертировать из HSV в RGB, сильно расписасывать этот этап я не буду так как тут есть формула и если ее сравнить с кодом ниже все будет понятно.
писал сам так как то что находил в сети работало не корректно.
Надеюсь основные знания для создания cp я в этом посте дал, поэтому на этом я закончу потому что увеличивать функционал можно долго добавляю конвертацию в разные цветовые форматы…
Вот что у меня получилось демо.
В этом посте старался объяснить как создать cp, не углубляясь сильно в код так как не видел в этом смысла в Drag`n`Drop нечего сложного нет!
Спасибо за внимание с вами был CyBer_UA и это мой первый пост о javascript (надеюсь не последний).
П.с код в итоговом примере кривоват (писался давно), просто только сейчас дошли руки написать этот пост.
Так как я пишу на чистом js без библиотек (не считая той которую я пишу сам:)) в данном посте будет только
Что нужно знать что бы написать 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)

Шкала 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 (надеюсь не последний).
П.с код в итоговом примере кривоват (писался давно), просто только сейчас дошли руки написать этот пост.