colpick.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. colpick Color Picker
  3. Copyright 2013 Jose Vargas. Licensed under GPL license. Based on Stefan Petre's Color Picker www.eyecon.ro, dual licensed under the MIT and GPL licenses
  4. For usage and examples: colpick.com/plugin
  5. */
  6. (function($) {
  7. var colpick = function() {
  8. var
  9. tpl = '<div class="colpick"><div class="colpick_color"><div class="colpick_color_overlay1"><div class="colpick_color_overlay2"><div class="colpick_selector_outer"><div class="colpick_selector_inner"></div></div></div></div></div><div class="colpick_hue"><div class="colpick_hue_arrs"><div class="colpick_hue_larr"></div><div class="colpick_hue_rarr"></div></div></div><div class="colpick_new_color"></div><div class="colpick_current_color"></div><div class="colpick_hex_field"><div class="colpick_field_letter">#</div><input type="text" maxlength="6" size="6" /></div><div class="colpick_rgb_r colpick_field"><div class="colpick_field_letter">R</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_rgb_g colpick_field"><div class="colpick_field_letter">G</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_rgb_b colpick_field"><div class="colpick_field_letter">B</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsx_h colpick_field"><div class="colpick_field_letter">H</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsx_s colpick_field"><div class="colpick_field_letter">S</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_hsx_x colpick_field"><div class="colpick_field_letter">B</div><input type="text" maxlength="3" size="3" /><div class="colpick_field_arrs"><div class="colpick_field_uarr"></div><div class="colpick_field_darr"></div></div></div><div class="colpick_submit"></div></div>',
  10. defaults = {
  11. showEvent: 'click',
  12. onShow: function() {
  13. },
  14. onBeforeShow: function() {
  15. },
  16. onHide: function() {
  17. },
  18. onChange: function() {
  19. },
  20. onSubmit: function() {
  21. },
  22. colorScheme: 'light',
  23. color: '3289c7',
  24. livePreview: true,
  25. flat: false,
  26. layout: 'full',
  27. submit: 1,
  28. submitText: 'OK',
  29. height: 156,
  30. hsl: false
  31. },
  32. //Fill the inputs of the plugin
  33. fillRGBFields = function(hsx, cal) {
  34. var rgb = $(cal).data('colpick').hsl ? hslToRgb(hsx) : hsbToRgb(hsx);
  35. $(cal).data('colpick').fields
  36. .eq(1).val(rgb.r).end()
  37. .eq(2).val(rgb.g).end()
  38. .eq(3).val(rgb.b).end();
  39. },
  40. fillHSXFields = function(hsx, cal) {
  41. $(cal).data('colpick').fields
  42. .eq(4).val(Math.round(hsx.h)).end()
  43. .eq(5).val(Math.round(hsx.s)).end()
  44. .eq(6).val(Math.round(hsx.x)).end();
  45. },
  46. fillHexFields = function(hsx, cal) {
  47. $(cal).data('colpick').fields.eq(0).val($(cal).data('colpick').hsl ? hslToHex(hsx) : hsbToHex(hsx));
  48. },
  49. //Set the round selector position
  50. setSelector = function(hsx, cal) {
  51. $(cal).data('colpick').selector.css('backgroundColor', '#' + ($(cal).data('colpick').hsl ? hslToHex({h: hsx.h, s: 100, x: 50}) : hsbToHex({h: hsx.h, s: 100, x: 100})));
  52. $(cal).data('colpick').selectorIndic.css({
  53. left: parseInt($(cal).data('colpick').height * hsx.s / 100, 10),
  54. top: parseInt($(cal).data('colpick').height * (100 - hsx.x) / 100, 10)
  55. });
  56. },
  57. //Set the hue selector position
  58. setHue = function(hsx, cal) {
  59. $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsx.h / 360, 10));
  60. },
  61. //Set current and new colors
  62. setCurrentColor = function(hsx, cal) {
  63. $(cal).data('colpick').currentColor.css('backgroundColor', '#' + ($(cal).data('colpick').hsl ? hslToHex(hsx) : hsbToHex(hsx)));
  64. },
  65. setNewColor = function(hsx, cal) {
  66. $(cal).data('colpick').newColor.css('backgroundColor', '#' + ($(cal).data('colpick').hsl ? hslToHex(hsx) : hsbToHex(hsx)));
  67. },
  68. //Called when the new color is changed
  69. change = function(ev) {
  70. var cal = $(this).parent().parent(), col;
  71. if (this.parentNode.className.indexOf('_hex') > 0) {
  72. cal.data('colpick').color = col = cal.data('colpick').hsl ? hexToHsl(fixHex(this.value)) : hexToHsb(fixHex(this.value));
  73. fillRGBFields(col, cal.get(0));
  74. fillHSXFields(col, cal.get(0));
  75. } else if (this.parentNode.className.indexOf('_hsx') > 0) {
  76. cal.data('colpick').color = col = fixHsx({
  77. h: parseInt(cal.data('colpick').fields.eq(4).val(), 10),
  78. s: parseInt(cal.data('colpick').fields.eq(5).val(), 10),
  79. x: parseInt(cal.data('colpick').fields.eq(6).val(), 10)
  80. });
  81. fillRGBFields(col, cal.get(0));
  82. fillHexFields(col, cal.get(0));
  83. } else {
  84. var rgb = {
  85. r: parseInt(cal.data('colpick').fields.eq(1).val(), 10),
  86. g: parseInt(cal.data('colpick').fields.eq(2).val(), 10),
  87. b: parseInt(cal.data('colpick').fields.eq(3).val(), 10)
  88. };
  89. cal.data('colpick').color = col = cal.data('colpick').hsl ? rgbToHsl(fixRgb(rgb)) : rgbToHsb(fixRgb(rgb));
  90. fillHexFields(col, cal.get(0));
  91. fillHSXFields(col, cal.get(0));
  92. }
  93. setSelector(col, cal.get(0));
  94. setHue(col, cal.get(0));
  95. setNewColor(col, cal.get(0));
  96. cal.data('colpick').onChange.apply(cal.parent(), [col, cal.data('colpick').hsl ? hslToHex(col) : hslToHex(col), cal.data('colpick').hsl ? hslToRgb(col) : hsbToRgb(col), cal.data('colpick').el, 0]);
  97. },
  98. //Change style on blur and on focus of inputs
  99. blur = function(ev) {
  100. $(this).parent().removeClass('colpick_focus');
  101. },
  102. focus = function() {
  103. $(this).parent().parent().data('colpick').fields.parent().removeClass('colpick_focus');
  104. $(this).parent().addClass('colpick_focus');
  105. },
  106. //Increment/decrement arrows functions
  107. downIncrement = function(ev) {
  108. ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
  109. var field = $(this).parent().find('input').focus();
  110. var current = {
  111. el: $(this).parent().addClass('colpick_slider'),
  112. max: this.parentNode.className.indexOf('_hsx_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsx') > 0 ? 100 : 255),
  113. y: ev.pageY,
  114. field: field,
  115. val: parseInt(field.val(), 10),
  116. preview: $(this).parent().parent().data('colpick').livePreview
  117. };
  118. $(document).mouseup(current, upIncrement);
  119. $(document).mousemove(current, moveIncrement);
  120. },
  121. moveIncrement = function(ev) {
  122. ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val - ev.pageY + ev.data.y, 10))));
  123. if (ev.data.preview) {
  124. change.apply(ev.data.field.get(0), [true]);
  125. }
  126. return false;
  127. },
  128. upIncrement = function(ev) {
  129. change.apply(ev.data.field.get(0), [true]);
  130. ev.data.el.removeClass('colpick_slider').find('input').focus();
  131. $(document).off('mouseup', upIncrement);
  132. $(document).off('mousemove', moveIncrement);
  133. return false;
  134. },
  135. //Hue slider functions
  136. downHue = function(ev) {
  137. ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
  138. var current = {
  139. cal: $(this).parent(),
  140. y: $(this).offset().top
  141. };
  142. $(document).on('mouseup touchend', current, upHue);
  143. $(document).on('mousemove touchmove', current, moveHue);
  144. var pageY = ((ev.type == 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY);
  145. change.apply(
  146. current.cal.data('colpick')
  147. .fields.eq(4).val(parseInt(360 * (current.cal.data('colpick').height - (pageY - current.y)) / current.cal.data('colpick').height, 10))
  148. .get(0),
  149. [current.cal.data('colpick').livePreview]
  150. );
  151. return false;
  152. },
  153. moveHue = function(ev) {
  154. var pageY = ((ev.type == 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY);
  155. change.apply(
  156. ev.data.cal.data('colpick')
  157. .fields.eq(4).val(parseInt(360 * (ev.data.cal.data('colpick').height - Math.max(0, Math.min(ev.data.cal.data('colpick').height, (pageY - ev.data.y)))) / ev.data.cal.data('colpick').height, 10))
  158. .get(0),
  159. [ev.data.preview]
  160. );
  161. return false;
  162. },
  163. upHue = function(ev) {
  164. //fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
  165. //fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
  166. $(document).off('mouseup touchend', upHue);
  167. $(document).off('mousemove touchmove', moveHue);
  168. return false;
  169. },
  170. //Color selector functions
  171. downSelector = function(ev) {
  172. ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
  173. var current = {
  174. cal: $(this).parent(),
  175. pos: $(this).offset()
  176. };
  177. current.preview = current.cal.data('colpick').livePreview;
  178. $(document).on('mouseup touchend', current, upSelector);
  179. $(document).on('mousemove touchmove', current, moveSelector);
  180. var payeX, pageY;
  181. if (ev.type == 'touchstart') {
  182. pageX = ev.originalEvent.changedTouches[0].pageX,
  183. pageY = ev.originalEvent.changedTouches[0].pageY;
  184. } else {
  185. pageX = ev.pageX;
  186. pageY = ev.pageY;
  187. }
  188. change.apply(
  189. current.cal.data('colpick').fields
  190. .eq(6).val(parseInt(100 * (current.cal.data('colpick').height - (pageY - current.pos.top)) / current.cal.data('colpick').height, 10)).end()
  191. .eq(5).val(parseInt(100 * (pageX - current.pos.left) / current.cal.data('colpick').height, 10))
  192. .get(0),
  193. [current.preview]
  194. );
  195. return false;
  196. },
  197. moveSelector = function(ev) {
  198. var payeX, pageY;
  199. if (ev.type == 'touchmove') {
  200. pageX = ev.originalEvent.changedTouches[0].pageX,
  201. pageY = ev.originalEvent.changedTouches[0].pageY;
  202. } else {
  203. pageX = ev.pageX;
  204. pageY = ev.pageY;
  205. }
  206. change.apply(
  207. ev.data.cal.data('colpick').fields
  208. .eq(6).val(parseInt(100 * (ev.data.cal.data('colpick').height - Math.max(0, Math.min(ev.data.cal.data('colpick').height, (pageY - ev.data.pos.top)))) / ev.data.cal.data('colpick').height, 10)).end()
  209. .eq(5).val(parseInt(100 * (Math.max(0, Math.min(ev.data.cal.data('colpick').height, (pageX - ev.data.pos.left)))) / ev.data.cal.data('colpick').height, 10))
  210. .get(0),
  211. [ev.data.preview]
  212. );
  213. return false;
  214. },
  215. upSelector = function(ev) {
  216. //fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
  217. //fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0));
  218. $(document).off('mouseup touchend', upSelector);
  219. $(document).off('mousemove touchmove', moveSelector);
  220. return false;
  221. },
  222. //Submit button
  223. clickSubmit = function(ev) {
  224. var cal = $(this).parent();
  225. var col = cal.data('colpick').color;
  226. cal.data('colpick').origColor = col;
  227. setCurrentColor(col, cal.get(0));
  228. cal.data('colpick').onSubmit(col, cal.data('colpick').hsl ? hslToHex(col) : hslToHex(col), cal.data('colpick').hsl ? hslToRgb(col) : hsbToRgb(col), cal.data('colpick').el);
  229. },
  230. //Show/hide the color picker
  231. show = function(ev) {
  232. // Prevent the trigger of any direct parent
  233. ev.stopPropagation();
  234. var cal = $('#' + $(this).data('colpickId'));
  235. cal.data('colpick').onBeforeShow.apply(this, [cal.get(0)]);
  236. var pos = $(this).offset();
  237. var top = pos.top + this.offsetHeight;
  238. var left = pos.left;
  239. var viewPort = getViewport();
  240. var calW = cal.width();
  241. if (left + calW > viewPort.l + viewPort.w) {
  242. left -= calW;
  243. }
  244. cal.css({left: left + 'px', top: top + 'px'});
  245. if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) != false) {
  246. cal.show();
  247. }
  248. //Hide when user clicks outside
  249. $('html').mousedown({cal: cal}, hide);
  250. cal.mousedown(function(ev) {
  251. ev.stopPropagation();
  252. })
  253. },
  254. hide = function(ev) {
  255. if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
  256. ev.data.cal.hide();
  257. }
  258. $('html').off('mousedown', hide);
  259. },
  260. getViewport = function() {
  261. var m = document.compatMode == 'CSS1Compat';
  262. return {
  263. l: window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
  264. w: window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth)
  265. };
  266. },
  267. //Fix the values if the user enters a negative or high value
  268. fixHsx = function(hsx) {
  269. return {
  270. h: Math.min(360, Math.max(0, hsx.h)),
  271. s: Math.min(100, Math.max(0, hsx.s)),
  272. x: Math.min(100, Math.max(0, hsx.x))
  273. };
  274. },
  275. fixRgb = function(rgb) {
  276. return {
  277. r: Math.min(255, Math.max(0, rgb.r)),
  278. g: Math.min(255, Math.max(0, rgb.g)),
  279. b: Math.min(255, Math.max(0, rgb.b))
  280. };
  281. },
  282. fixHex = function(hex) {
  283. var len = 6 - hex.length;
  284. if (len > 0) {
  285. var o = [];
  286. for (var i = 0; i < len; i++) {
  287. o.push('0');
  288. }
  289. o.push(hex);
  290. hex = o.join('');
  291. }
  292. return hex;
  293. },
  294. restoreOriginal = function() {
  295. var cal = $(this).parent();
  296. var col = cal.data('colpick').origColor;
  297. cal.data('colpick').color = col;
  298. fillRGBFields(col, cal.get(0));
  299. fillHexFields(col, cal.get(0));
  300. fillHSXFields(col, cal.get(0));
  301. setSelector(col, cal.get(0));
  302. setHue(col, cal.get(0));
  303. setNewColor(col, cal.get(0));
  304. };
  305. return {
  306. init: function(opt) {
  307. opt = $.extend({}, defaults, opt || {});
  308. //Set color
  309. if (typeof opt.color == 'string') {
  310. opt.color = opt.hsl ? hexToHsl(opt.color) : hexToHsb(opt.color);
  311. } else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) {
  312. opt.color = opt.hsl ? rgbToHsl(opt.color) : rgbToHsb(opt.color);
  313. } else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) {
  314. opt.color = opt.hsl ? fixHsl(opt.color) : fixHsb(opt.color);
  315. } else {
  316. return this;
  317. }
  318. //For each selected DOM element
  319. return this.each(function() {
  320. //If the element does not have an ID
  321. if (!$(this).data('colpickId')) {
  322. var options = $.extend({}, opt);
  323. options.origColor = opt.color;
  324. //Generate and assign a random ID
  325. var id = 'collorpicker_' + parseInt(Math.random() * 1000);
  326. $(this).data('colpickId', id);
  327. //Set the tpl's ID and get the HTML
  328. var cal = $(tpl).attr('id', id);
  329. //Add class according to layout
  330. cal.addClass('colpick_' + options.layout + (options.submit ? '' : ' colpick_' + options.layout + '_ns'));
  331. //Add class if the color scheme is not default
  332. if (options.colorScheme != 'light')
  333. cal.addClass('colpick_' + options.colorScheme);
  334. //Add class if HSL is enabled
  335. if (options.hsl)
  336. cal.addClass('colpick_hsl');
  337. //Setup submit button
  338. cal.find('div.colpick_submit').html(options.submitText).click(clickSubmit);
  339. //Setup input fields
  340. options.fields = cal.find('input').change(change).blur(blur).focus(focus);
  341. cal.find('div.colpick_field_arrs').mousedown(downIncrement).end().find('div.colpick_current_color').click(restoreOriginal);
  342. //Setup hue selector
  343. options.selector = cal.find('div.colpick_color').on('mousedown touchstart', downSelector);
  344. options.selectorIndic = options.selector.find('div.colpick_selector_outer');
  345. //Store parts of the plugin
  346. options.el = this;
  347. options.hue = cal.find('div.colpick_hue_arrs');
  348. huebar = options.hue.parent();
  349. //Paint the hue bar
  350. var UA = navigator.userAgent.toLowerCase();
  351. var isIE = navigator.appName === 'Microsoft Internet Explorer';
  352. var IEver = isIE ? parseFloat(UA.match(/msie ([0-9]{1,}[\.0-9]{0,})/)[1]) : 0;
  353. var ngIE = (isIE && IEver < 10);
  354. var stops = ['#ff0000', '#ff0080', '#ff00ff', '#8000ff', '#0000ff', '#0080ff', '#00ffff', '#00ff80', '#00ff00', '#80ff00', '#ffff00', '#ff8000', '#ff0000'];
  355. if (ngIE) {
  356. var i, div;
  357. for (i = 0; i <= 11; i++) {
  358. div = $('<div></div>').attr('style', 'height:8.333333%; filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=' + stops[i] + ', endColorstr=' + stops[i + 1] + '); -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=' + stops[i] + ', endColorstr=' + stops[i + 1] + ')";');
  359. huebar.append(div);
  360. }
  361. } else {
  362. stopList = stops.join(',');
  363. huebar.attr('style', 'background:-webkit-linear-gradient(top center,' + stopList + '); background:-moz-linear-gradient(top center,' + stopList + '); background:linear-gradient(to bottom,' + stopList + '); ');
  364. }
  365. cal.find('div.colpick_hue').on('mousedown touchstart', downHue);
  366. options.newColor = cal.find('div.colpick_new_color');
  367. options.currentColor = cal.find('div.colpick_current_color');
  368. //Store options and fill with default color
  369. cal.data('colpick', options);
  370. fillRGBFields(options.color, cal.get(0));
  371. fillHSXFields(options.color, cal.get(0));
  372. fillHexFields(options.color, cal.get(0));
  373. setHue(options.color, cal.get(0));
  374. setSelector(options.color, cal.get(0));
  375. setCurrentColor(options.color, cal.get(0));
  376. setNewColor(options.color, cal.get(0));
  377. //Append to body if flat=false, else show in place
  378. if (options.flat) {
  379. cal.appendTo(this).show();
  380. cal.css({
  381. position: 'relative',
  382. display: 'block'
  383. });
  384. } else {
  385. cal.appendTo(document.body);
  386. $(this).on(options.showEvent, show);
  387. cal.css({
  388. position: 'absolute'
  389. });
  390. }
  391. }
  392. });
  393. },
  394. //Shows the picker
  395. showPicker: function() {
  396. return this.each(function() {
  397. if ($(this).data('colpickId')) {
  398. show.apply(this);
  399. }
  400. });
  401. },
  402. //Hides the picker
  403. hidePicker: function() {
  404. return this.each(function() {
  405. if ($(this).data('colpickId')) {
  406. $('#' + $(this).data('colpickId')).hide();
  407. }
  408. });
  409. },
  410. //Sets a color as new and current (default)
  411. setColor: function(col, setCurrent) {
  412. setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent;
  413. if (typeof col == 'string') {
  414. col = hexToHsb(col);
  415. } else if (col.r != undefined && col.g != undefined && col.b != undefined) {
  416. col = rgbToHsb(col);
  417. } else if (col.h != undefined && col.s != undefined && col.b != undefined) {
  418. col = fixHsb(col);
  419. } else {
  420. return this;
  421. }
  422. return this.each(function() {
  423. if ($(this).data('colpickId')) {
  424. var cal = $('#' + $(this).data('colpickId'));
  425. cal.data('colpick').color = col;
  426. cal.data('colpick').origColor = col;
  427. fillRGBFields(col, cal.get(0));
  428. fillHSXFields(col, cal.get(0));
  429. fillHexFields(col, cal.get(0));
  430. setHue(col, cal.get(0));
  431. setSelector(col, cal.get(0));
  432. setNewColor(col, cal.get(0));
  433. cal.data('colpick').onChange.apply(cal.parent(), [
  434. col,
  435. cal.data('colpick').hsl ? hslToHex(col) : hsbToHex(col),
  436. cal.data('colpick').hsl ? hslToRgb(col) : hsbToRgb(col),
  437. cal.data('colpick').el,
  438. 1
  439. ]);
  440. if (setCurrent) {
  441. setCurrentColor(col, cal.get(0));
  442. }
  443. }
  444. });
  445. }
  446. };
  447. }();
  448. //Color space convertions
  449. var hexToRgb = function(hex) {
  450. var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
  451. return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
  452. };
  453. var hexToHsb = function(hex) {
  454. return rgbToHsb(hexToRgb(hex));
  455. };
  456. var hexToHsl = function(hex) {
  457. return rgbToHsl(hexToRgb(hex));
  458. };
  459. var rgbToHsb = function(rgb) {
  460. var hsb = {h: 0, s: 0, x: 0};
  461. var min = Math.min(rgb.r, rgb.g, rgb.b);
  462. var max = Math.max(rgb.r, rgb.g, rgb.b);
  463. var delta = max - min;
  464. hsb.x = max;
  465. hsb.s = max != 0 ? 255 * delta / max : 0;
  466. if (hsb.s != 0) {
  467. if (rgb.r == max)
  468. hsb.h = (rgb.g - rgb.b) / delta;
  469. else if (rgb.g == max)
  470. hsb.h = 2 + (rgb.b - rgb.r) / delta;
  471. else
  472. hsb.h = 4 + (rgb.r - rgb.g) / delta;
  473. } else
  474. hsb.h = -1;
  475. hsb.h *= 60;
  476. if (hsb.h < 0)
  477. hsb.h += 360;
  478. hsb.s *= 100 / 255;
  479. hsb.x *= 100 / 255;
  480. return hsb;
  481. };
  482. var rgbToHsl = function(rgb) {
  483. return hsbToHsl(rgbToHsb(rgb));
  484. };
  485. var hsbToHsl = function(hsb) {
  486. var hsl = {h: 0, s: 0, x: 0};
  487. hsl.h = hsb.h;
  488. hsl.x = hsb.x * (200 - hsb.s) / 200;
  489. hsl.s = hsb.x * hsb.s / (100 - Math.abs(2 * hsl.x - 100));
  490. return hsl;
  491. };
  492. var hslToHsb = function(hsl) {
  493. var hsb = {h: 0, s: 0, x: 0};
  494. hsb.h = hsl.h;
  495. hsb.x = (200 * hsl.x + hsl.s * (100 - Math.abs(2 * hsl.x - 100))) / 200
  496. hsb.s = 200 * (hsb.x - hsl.x) / hsb.x;
  497. return hsb;
  498. };
  499. var hsbToRgb = function(hsb) {
  500. var rgb = {};
  501. var h = hsb.h;
  502. var s = hsb.s * 255 / 100;
  503. var v = hsb.x * 255 / 100;
  504. if (s == 0) {
  505. rgb.r = rgb.g = rgb.b = v;
  506. } else {
  507. var t1 = v;
  508. var t2 = (255 - s) * v / 255;
  509. var t3 = (t1 - t2) * (h % 60) / 60;
  510. if (h == 360)
  511. h = 0;
  512. if (h < 60) {
  513. rgb.r = t1;
  514. rgb.b = t2;
  515. rgb.g = t2 + t3
  516. }
  517. else if (h < 120) {
  518. rgb.g = t1;
  519. rgb.b = t2;
  520. rgb.r = t1 - t3
  521. }
  522. else if (h < 180) {
  523. rgb.g = t1;
  524. rgb.r = t2;
  525. rgb.b = t2 + t3
  526. }
  527. else if (h < 240) {
  528. rgb.b = t1;
  529. rgb.r = t2;
  530. rgb.g = t1 - t3
  531. }
  532. else if (h < 300) {
  533. rgb.b = t1;
  534. rgb.g = t2;
  535. rgb.r = t2 + t3
  536. }
  537. else if (h < 360) {
  538. rgb.r = t1;
  539. rgb.g = t2;
  540. rgb.b = t1 - t3
  541. }
  542. else {
  543. rgb.r = 0;
  544. rgb.g = 0;
  545. rgb.b = 0
  546. }
  547. }
  548. return {r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b)};
  549. };
  550. var hslToRgb = function(hsl) {
  551. return hsbToRgb(hslToHsb(hsl));
  552. };
  553. var rgbToHex = function(rgb) {
  554. var hex = [
  555. rgb.r.toString(16),
  556. rgb.g.toString(16),
  557. rgb.b.toString(16)
  558. ];
  559. $.each(hex, function(nr, val) {
  560. if (val.length == 1) {
  561. hex[nr] = '0' + val;
  562. }
  563. });
  564. return hex.join('');
  565. };
  566. var hsbToHex = function(hsb) {
  567. return rgbToHex(hsbToRgb(hsb));
  568. };
  569. var hslToHex = function(hsl) {
  570. return hsbToHex(hslToHsb(hsl));
  571. };
  572. $.fn.extend({
  573. colpick: colpick.init,
  574. colpickHide: colpick.hidePicker,
  575. colpickShow: colpick.showPicker,
  576. colpickSetColor: colpick.setColor
  577. });
  578. $.extend({
  579. colpick: {
  580. rgbToHex: rgbToHex,
  581. rgbToHsb: rgbToHsb,
  582. rgbToHsl: rgbToHsl,
  583. hsbToHex: hsbToHex,
  584. hsbToRgb: hsbToRgb,
  585. hsbToHsl: hsbToHsl,
  586. hexToHsb: hexToHsb,
  587. hexToHsl: hexToHsl,
  588. hexToRgb: hexToRgb,
  589. hslToHsb: hslToHsb,
  590. hslToRgb: hslToRgb,
  591. hslToHex: hslToHex
  592. }
  593. });
  594. })(jQuery);