colorpicker.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /**
  2. @Title: layui.colorpicker 颜色选择器
  3. @Author: star1029
  4. @License:MIT
  5. */
  6. layui.define('jquery', function(exports){
  7. "use strict";
  8. var $ = layui.jquery
  9. //外部接口
  10. ,colorpicker = {
  11. config: {}
  12. ,index: layui.colorpicker ? (layui.colorpicker.index + 10000) : 0
  13. //设置全局项
  14. ,set: function(options){
  15. var that = this;
  16. that.config = $.extend({}, that.config, options);
  17. return that;
  18. }
  19. //事件监听
  20. ,on: function(events, callback){
  21. return layui.onevent.call(this, 'colorpicker', events, callback);
  22. }
  23. }
  24. //操作当前实例
  25. ,thisColorPicker = function(){
  26. var that = this
  27. ,options = that.config;
  28. return {
  29. config: options
  30. }
  31. }
  32. //字符常量
  33. ,MOD_NAME = 'colorpicker', SHOW = 'layui-show', THIS = 'layui-this', ELEM = 'layui-colorpicker'
  34. ,ELEM_MAIN = '.layui-colorpicker-main', ICON_PICKER_DOWN = 'layui-icon-down', ICON_PICKER_CLOSE = 'layui-icon-close'
  35. ,PICKER_TRIG_SPAN = 'layui-colorpicker-trigger-span', PICKER_TRIG_I = 'layui-colorpicker-trigger-i', PICKER_SIDE = 'layui-colorpicker-side', PICKER_SIDE_SLIDER = 'layui-colorpicker-side-slider'
  36. ,PICKER_BASIS = 'layui-colorpicker-basis', PICKER_ALPHA_BG = 'layui-colorpicker-alpha-bgcolor', PICKER_ALPHA_SLIDER = 'layui-colorpicker-alpha-slider', PICKER_BASIS_CUR = 'layui-colorpicker-basis-cursor', PICKER_INPUT = 'layui-colorpicker-main-input'
  37. //RGB转HSB
  38. ,RGBToHSB = function(rgb){
  39. var hsb = {h:0, s:0, b:0};
  40. var min = Math.min(rgb.r, rgb.g, rgb.b);
  41. var max = Math.max(rgb.r, rgb.g, rgb.b);
  42. var delta = max - min;
  43. hsb.b = max;
  44. hsb.s = max != 0 ? 255*delta/max : 0;
  45. if(hsb.s != 0){
  46. if(rgb.r == max){
  47. hsb.h = (rgb.g - rgb.b) / delta;
  48. }else if(rgb.g == max){
  49. hsb.h = 2 + (rgb.b - rgb.r) / delta;
  50. }else{
  51. hsb.h = 4 + (rgb.r - rgb.g) / delta;
  52. }
  53. }else{
  54. hsb.h = -1;
  55. };
  56. if(max == min){
  57. hsb.h = 0;
  58. };
  59. hsb.h *= 60;
  60. if(hsb.h < 0) {
  61. hsb.h += 360;
  62. };
  63. hsb.s *= 100/255;
  64. hsb.b *= 100/255;
  65. return hsb;
  66. }
  67. //HEX转HSB
  68. ,HEXToHSB = function(hex){
  69. var hex = hex.indexOf('#') > -1 ? hex.substring(1) : hex;
  70. if(hex.length == 3){
  71. var num = hex.split("");
  72. hex = num[0]+num[0]+num[1]+num[1]+num[2]+num[2]
  73. };
  74. hex = parseInt(hex, 16);
  75. var rgb = {r:hex >> 16, g:(hex & 0x00FF00) >> 8, b:(hex & 0x0000FF)};
  76. return RGBToHSB(rgb);
  77. }
  78. //HSB转RGB
  79. ,HSBToRGB = function(hsb){
  80. var rgb = {};
  81. var h = hsb.h;
  82. var s = hsb.s*255/100;
  83. var b = hsb.b*255/100;
  84. if(s == 0){
  85. rgb.r = rgb.g = rgb.b = b;
  86. }else{
  87. var t1 = b;
  88. var t2 = (255 - s) * b /255;
  89. var t3 = (t1 - t2) * (h % 60) /60;
  90. if(h == 360) h = 0;
  91. if(h < 60) {rgb.r=t1; rgb.b=t2; rgb.g=t2+t3}
  92. else if(h < 120) {rgb.g=t1; rgb.b=t2; rgb.r=t1-t3}
  93. else if(h < 180) {rgb.g=t1; rgb.r=t2; rgb.b=t2+t3}
  94. else if(h < 240) {rgb.b=t1; rgb.r=t2; rgb.g=t1-t3}
  95. else if(h < 300) {rgb.b=t1; rgb.g=t2; rgb.r=t2+t3}
  96. else if(h < 360) {rgb.r=t1; rgb.g=t2; rgb.b=t1-t3}
  97. else {rgb.r=0; rgb.g=0; rgb.b=0}
  98. }
  99. return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)};
  100. }
  101. //HSB转HEX
  102. ,HSBToHEX = function(hsb){
  103. var rgb = HSBToRGB(hsb);
  104. var hex = [
  105. rgb.r.toString(16)
  106. ,rgb.g.toString(16)
  107. ,rgb.b.toString(16)
  108. ];
  109. $.each(hex, function(nr, val){
  110. if(val.length == 1){
  111. hex[nr] = '0' + val;
  112. }
  113. });
  114. return hex.join('');
  115. }
  116. //转化成所需rgb格式
  117. ,RGBSTo = function(rgbs){
  118. var regexp = /[0-9]{1,3}/g;
  119. var re = rgbs.match(regexp) || [];
  120. return {r:re[0], g:re[1], b:re[2]};
  121. }
  122. ,$win = $(window)
  123. ,$doc = $(document)
  124. //构造器
  125. ,Class = function(options){
  126. var that = this;
  127. that.index = ++colorpicker.index;
  128. that.config = $.extend({}, that.config, colorpicker.config, options);
  129. that.render();
  130. };
  131. //默认配置
  132. Class.prototype.config = {
  133. color: '' //默认颜色,默认没有
  134. ,size: null //选择器大小
  135. ,alpha: false //是否开启透明度
  136. ,format: 'hex' //颜色显示/输入格式,可选 rgb,hex
  137. ,predefine: false //预定义颜色是否开启
  138. ,colors: [ //默认预定义颜色列表
  139. '#009688', '#5FB878', '#1E9FFF', '#FF5722', '#FFB800', '#01AAED', '#999', '#c00', '#ff8c00','#ffd700'
  140. ,'#90ee90', '#00ced1', '#1e90ff', '#c71585', 'rgb(0, 186, 189)', 'rgb(255, 120, 0)', 'rgb(250, 212, 0)', '#393D49', 'rgba(0,0,0,.5)', 'rgba(255, 69, 0, 0.68)', 'rgba(144, 240, 144, 0.5)', 'rgba(31, 147, 255, 0.73)'
  141. ]
  142. };
  143. //初始颜色选择框
  144. Class.prototype.render = function(){
  145. var that = this
  146. ,options = that.config
  147. //颜色选择框对象
  148. ,elemColorBox = $(['<div class="layui-unselect layui-colorpicker">'
  149. ,'<span '+ (options.format == 'rgb' && options.alpha
  150. ? 'class="layui-colorpicker-trigger-bgcolor"'
  151. : '') +'>'
  152. ,'<span class="layui-colorpicker-trigger-span" '
  153. ,'lay-type="'+ (options.format == 'rgb' ? (options.alpha ? 'rgba' : 'torgb') : '') +'" '
  154. ,'style="'+ function(){
  155. var bgstr = '';
  156. if(options.color){
  157. bgstr = options.color;
  158. if((options.color.match(/[0-9]{1,3}/g) || []).length > 3){ //需要优化
  159. if(!(options.alpha && options.format == 'rgb')){
  160. bgstr = '#' + HSBToHEX(RGBToHSB(RGBSTo(options.color)))
  161. }
  162. }
  163. return 'background: '+ bgstr;
  164. }
  165. return bgstr;
  166. }() +'">'
  167. ,'<i class="layui-icon layui-colorpicker-trigger-i '+ (options.color
  168. ? ICON_PICKER_DOWN
  169. : ICON_PICKER_CLOSE) +'"></i>'
  170. ,'</span>'
  171. ,'</span>'
  172. ,'</div>'].join(''))
  173. //初始化颜色选择框
  174. var othis = $(options.elem);
  175. options.size && elemColorBox.addClass('layui-colorpicker-'+ options.size); //初始化颜色选择框尺寸
  176. //插入颜色选择框
  177. othis.addClass('layui-inline').html(
  178. that.elemColorBox = elemColorBox
  179. );
  180. //获取背景色值
  181. that.color = that.elemColorBox.find('.'+ PICKER_TRIG_SPAN)[0].style.background;
  182. //相关事件
  183. that.events();
  184. };
  185. //渲染颜色选择器
  186. Class.prototype.renderPicker = function(){
  187. var that = this
  188. ,options = that.config
  189. ,elemColorBox = that.elemColorBox[0]
  190. //颜色选择器对象
  191. ,elemPicker = that.elemPicker = $(['<div id="layui-colorpicker'+ that.index +'" data-index="'+ that.index +'" class="layui-anim layui-anim-upbit layui-colorpicker-main">'
  192. //颜色面板
  193. ,'<div class="layui-colorpicker-main-wrapper">'
  194. ,'<div class="layui-colorpicker-basis">'
  195. ,'<div class="layui-colorpicker-basis-white"></div>'
  196. ,'<div class="layui-colorpicker-basis-black"></div>'
  197. ,'<div class="layui-colorpicker-basis-cursor"></div>'
  198. ,'</div>'
  199. ,'<div class="layui-colorpicker-side">'
  200. ,'<div class="layui-colorpicker-side-slider"></div>'
  201. ,'</div>'
  202. ,'</div>'
  203. //透明度条块
  204. ,'<div class="layui-colorpicker-main-alpha '+ (options.alpha ? SHOW : '') +'">'
  205. ,'<div class="layui-colorpicker-alpha-bgcolor">'
  206. ,'<div class="layui-colorpicker-alpha-slider"></div>'
  207. ,'</div>'
  208. ,'</div>'
  209. //预设颜色列表
  210. ,function(){
  211. if(options.predefine){
  212. var list = ['<div class="layui-colorpicker-main-pre">'];
  213. layui.each(options.colors, function(i, v){
  214. list.push(['<div class="layui-colorpicker-pre'+ ((v.match(/[0-9]{1,3}/g) || []).length > 3
  215. ? ' layui-colorpicker-pre-isalpha'
  216. : '') +'">'
  217. ,'<div style="background:'+ v +'"></div>'
  218. ,'</div>'].join(''));
  219. });
  220. list.push('</div>');
  221. return list.join('');
  222. } else {
  223. return '';
  224. }
  225. }()
  226. //底部表单元素区域
  227. ,'<div class="layui-colorpicker-main-input">'
  228. ,'<div class="layui-inline">'
  229. ,'<input type="text" class="layui-input">'
  230. ,'</div>'
  231. ,'<div class="layui-btn-container">'
  232. ,'<button class="layui-btn layui-btn-primary layui-btn-sm" colorpicker-events="clear">清空</button>'
  233. ,'<button class="layui-btn layui-btn-sm" colorpicker-events="confirm">确定</button>'
  234. ,'</div'
  235. ,'</div>'
  236. ,'</div>'].join(''))
  237. ,elemColorBoxSpan = that.elemColorBox.find('.' + PICKER_TRIG_SPAN)[0];
  238. //如果当前点击的颜色盒子已经存在选择器,则关闭
  239. if($(ELEM_MAIN)[0] && $(ELEM_MAIN).data('index') == that.index){
  240. that.removePicker(Class.thisElemInd);
  241. } else { //插入颜色选择器
  242. that.removePicker(Class.thisElemInd);
  243. $('body').append(elemPicker);
  244. }
  245. Class.thisElemInd = that.index; //记录最新打开的选择器索引
  246. Class.thisColor = elemColorBox.style.background //记录最新打开的选择器颜色选中值
  247. that.position();
  248. that.pickerEvents();
  249. };
  250. //颜色选择器移除
  251. Class.prototype.removePicker = function(index){
  252. var that = this
  253. ,options = that.config;
  254. $('#layui-colorpicker'+ (index || that.index)).remove();
  255. return that;
  256. };
  257. //定位算法
  258. Class.prototype.position = function(){
  259. var that = this
  260. ,options = that.config
  261. ,elem = that.bindElem || that.elemColorBox[0]
  262. ,elemPicker = that.elemPicker[0]
  263. ,rect = elem.getBoundingClientRect() //绑定元素的坐标
  264. ,elemWidth = elemPicker.offsetWidth //控件的宽度
  265. ,elemHeight = elemPicker.offsetHeight //控件的高度
  266. //滚动条高度
  267. ,scrollArea = function(type){
  268. type = type ? 'scrollLeft' : 'scrollTop';
  269. return document.body[type] | document.documentElement[type];
  270. }
  271. ,winArea = function(type){
  272. return document.documentElement[type ? 'clientWidth' : 'clientHeight']
  273. }, margin = 5, left = rect.left, top = rect.bottom;
  274. left = left - (elemWidth - elem.offsetWidth)/2;
  275. top = top + margin
  276. //如果右侧超出边界
  277. if(left + elemWidth + margin > winArea('width')){
  278. left = winArea('width') - elemWidth - margin;
  279. } else if(left < margin){ //如果左侧超出边界
  280. left = margin;
  281. }
  282. //如果底部超出边界
  283. if(top + elemHeight + margin > winArea()){
  284. top = rect.top > elemHeight //顶部是否有足够区域显示完全
  285. ? rect.top - elemHeight
  286. : winArea() - elemHeight;
  287. top = top - margin*2;
  288. }
  289. if(options.position){
  290. elemPicker.style.position = options.position;
  291. }
  292. elemPicker.style.left = left + (options.position === 'fixed' ? 0 : scrollArea(1)) + 'px';
  293. elemPicker.style.top = top + (options.position === 'fixed' ? 0 : scrollArea()) + 'px';
  294. };
  295. //颜色选择器赋值
  296. Class.prototype.val = function(){
  297. var that = this
  298. ,options = that.config
  299. ,elemColorBox = that.elemColorBox.find('.' + PICKER_TRIG_SPAN)
  300. ,elemPickerInput = that.elemPicker.find('.' + PICKER_INPUT)
  301. ,e = elemColorBox[0]
  302. ,bgcolor = e.style.backgroundColor;
  303. //判断是否有背景颜色
  304. if(bgcolor){
  305. //转化成hsb格式
  306. var hsb = RGBToHSB(RGBSTo(bgcolor))
  307. ,type = elemColorBox.attr('lay-type');
  308. //同步滑块的位置及颜色选择器的选择
  309. that.select(hsb.h, hsb.s, hsb.b);
  310. //如果格式要求为rgb
  311. if(type === 'torgb'){
  312. elemPickerInput.find('input').val(bgcolor);
  313. };
  314. //如果格式要求为rgba
  315. if(type === 'rgba'){
  316. var rgb = RGBSTo(bgcolor);
  317. //如果开启透明度而没有设置,则给默认值
  318. if((bgcolor.match(/[0-9]{1,3}/g) || []).length == 3){
  319. elemPickerInput.find('input').val('rgba('+ rgb.r +', '+ rgb.g +', '+ rgb.b +', 1)');
  320. that.elemPicker.find('.'+ PICKER_ALPHA_SLIDER).css("left", 280);
  321. } else {
  322. elemPickerInput.find('input').val(bgcolor);
  323. var left = bgcolor.slice(bgcolor.lastIndexOf(",") + 1, bgcolor.length - 1) * 280;
  324. that.elemPicker.find('.'+ PICKER_ALPHA_SLIDER).css("left", left);
  325. };
  326. //设置span背景色
  327. that.elemPicker.find('.'+ PICKER_ALPHA_BG)[0].style.background = 'linear-gradient(to right, rgba('+ rgb.r +', '+ rgb.g +', '+ rgb.b +', 0), rgb('+ rgb.r +', '+ rgb.g +', '+ rgb.b +'))';
  328. };
  329. }else{
  330. //如果没有背景颜色则默认到最初始的状态
  331. that.select(0,100,100);
  332. elemPickerInput.find('input').val("");
  333. that.elemPicker.find('.'+ PICKER_ALPHA_BG)[0].style.background = '';
  334. that.elemPicker.find('.'+ PICKER_ALPHA_SLIDER).css("left", 280);
  335. }
  336. };
  337. //颜色选择器滑动 / 点击
  338. Class.prototype.side = function(){
  339. var that = this
  340. ,options = that.config
  341. ,span = that.elemColorBox.find('.' + PICKER_TRIG_SPAN)
  342. ,type = span.attr('lay-type')
  343. ,side = that.elemPicker.find('.' + PICKER_SIDE)
  344. ,slider = that.elemPicker.find('.' + PICKER_SIDE_SLIDER)
  345. ,basis = that.elemPicker.find('.' + PICKER_BASIS)
  346. ,choose = that.elemPicker.find('.' + PICKER_BASIS_CUR)
  347. ,alphacolor = that.elemPicker.find('.' + PICKER_ALPHA_BG)
  348. ,alphaslider = that.elemPicker.find('.' + PICKER_ALPHA_SLIDER)
  349. ,_h = slider[0].offsetTop/180*360
  350. ,_b = 100 - (choose[0].offsetTop + 3)/180*100
  351. ,_s = (choose[0].offsetLeft + 3)/260*100
  352. ,_a = Math.round(alphaslider[0].offsetLeft/280*100)/100
  353. ,i = that.elemColorBox.find('.' + PICKER_TRIG_I)
  354. ,pre = that.elemPicker.find('.layui-colorpicker-pre').children('div')
  355. ,change = function(x,y,z,a){
  356. that.select(x, y, z);
  357. var rgb = HSBToRGB({h:x, s:y, b:z});
  358. i.addClass(ICON_PICKER_DOWN).removeClass(ICON_PICKER_CLOSE);
  359. span[0].style.background = 'rgb('+ rgb.r +', '+ rgb.g +', '+ rgb.b +')';
  360. if(type === 'torgb'){
  361. that.elemPicker.find('.' + PICKER_INPUT).find('input').val('rgb('+ rgb.r +', '+ rgb.g +', '+ rgb.b +')');
  362. };
  363. if(type === 'rgba'){
  364. var left = 0;
  365. left = a * 280;
  366. alphaslider.css("left", left);
  367. that.elemPicker.find('.' + PICKER_INPUT).find('input').val('rgba('+ rgb.r +', '+ rgb.g +', '+ rgb.b +', '+ a +')');
  368. span[0].style.background = 'rgba('+ rgb.r +', '+ rgb.g +', '+ rgb.b +', '+ a +')';
  369. alphacolor[0].style.background = 'linear-gradient(to right, rgba('+ rgb.r +', '+ rgb.g +', '+ rgb.b +', 0), rgb('+ rgb.r +', '+ rgb.g +', '+ rgb.b +'))'
  370. };
  371. //回调更改的颜色
  372. options.change && options.change(that.elemPicker.find('.' + PICKER_INPUT).find('input').val());
  373. }
  374. //拖拽元素
  375. ,elemMove = $(['<div class="layui-auxiliar-moving" id="LAY-colorpicker-moving"></div'].join(''))
  376. ,createMoveElem = function(call){
  377. $('#LAY-colorpicker-moving')[0] || $('body').append(elemMove);
  378. elemMove.on('mousemove', call);
  379. elemMove.on('mouseup', function(){
  380. elemMove.remove();
  381. }).on('mouseleave', function(){
  382. elemMove.remove();
  383. });
  384. };
  385. //右侧主色选择
  386. slider.on('mousedown', function(e){
  387. var oldtop = this.offsetTop
  388. ,oldy = e.clientY;
  389. var move = function(e){
  390. var top = oldtop + (e.clientY - oldy)
  391. ,maxh = side[0].offsetHeight;
  392. if(top < 0)top = 0;
  393. if(top > maxh)top = maxh;
  394. var h = top/180*360;
  395. _h = h;
  396. change(h, _s, _b, _a);
  397. e.preventDefault();
  398. };
  399. createMoveElem(move);
  400. e.preventDefault();
  401. });
  402. side.on('click', function(e){
  403. var top = e.clientY - $(this).offset().top;
  404. if(top < 0)top = 0;
  405. if(top > this.offsetHeight)top = this.offsetHeight;
  406. var h = top/180*360;
  407. _h = h;
  408. change(h, _s, _b, _a);
  409. e.preventDefault();
  410. });
  411. //中间小圆点颜色选择
  412. choose.on('mousedown', function(e){
  413. var oldtop = this.offsetTop
  414. ,oldleft = this.offsetLeft
  415. ,oldy = e.clientY
  416. ,oldx = e.clientX;
  417. var move = function(e){
  418. var top = oldtop + (e.clientY - oldy)
  419. ,left = oldleft + (e.clientX - oldx)
  420. ,maxh = basis[0].offsetHeight - 3
  421. ,maxw = basis[0].offsetWidth - 3;
  422. if(top < -3)top = -3;
  423. if(top > maxh)top = maxh;
  424. if(left < -3)left = -3;
  425. if(left > maxw)left = maxw;
  426. var s = (left + 3)/260*100
  427. ,b = 100 - (top + 3)/180*100;
  428. _b = b;
  429. _s = s;
  430. change(_h, s, b, _a);
  431. e.preventDefault();
  432. };
  433. layui.stope(e);
  434. createMoveElem(move);
  435. e.preventDefault();
  436. });
  437. basis.on('mousedown', function(e){
  438. var top = e.clientY - $(this).offset().top - 3 + $win.scrollTop()
  439. ,left = e.clientX - $(this).offset().left - 3 + $win.scrollLeft()
  440. if(top < -3)top = -3;
  441. if(top > this.offsetHeight - 3)top = this.offsetHeight - 3;
  442. if(left < -3)left = -3;
  443. if(left > this.offsetWidth - 3)left = this.offsetWidth - 3;
  444. var s = (left + 3)/260*100
  445. ,b = 100 - (top + 3)/180*100;
  446. _b = b;
  447. _s = s;
  448. change(_h, s, b, _a);
  449. e.preventDefault();
  450. choose.trigger(e, 'mousedown');
  451. });
  452. //底部透明度选择
  453. alphaslider.on('mousedown', function(e){
  454. var oldleft = this.offsetLeft
  455. ,oldx = e.clientX;
  456. var move = function(e){
  457. var left = oldleft + (e.clientX - oldx)
  458. ,maxw = alphacolor[0].offsetWidth;
  459. if(left < 0)left = 0;
  460. if(left > maxw)left = maxw;
  461. var a = Math.round(left /280*100) /100;
  462. _a = a;
  463. change(_h, _s, _b, a);
  464. e.preventDefault();
  465. };
  466. createMoveElem(move);
  467. e.preventDefault();
  468. });
  469. alphacolor.on('click', function(e){
  470. var left = e.clientX - $(this).offset().left
  471. if(left < 0)left = 0;
  472. if(left > this.offsetWidth)left = this.offsetWidth;
  473. var a = Math.round(left /280*100) /100;
  474. _a = a;
  475. change(_h, _s, _b, a);
  476. e.preventDefault();
  477. });
  478. //预定义颜色选择
  479. pre.each(function(){
  480. $(this).on('click', function(){
  481. $(this).parent('.layui-colorpicker-pre').addClass('selected').siblings().removeClass('selected');
  482. var color = this.style.backgroundColor
  483. ,hsb = RGBToHSB(RGBSTo(color))
  484. ,a = color.slice(color.lastIndexOf(",") + 1, color.length - 1),left;
  485. _h = hsb.h;
  486. _s = hsb.s;
  487. _b = hsb.b;
  488. if((color.match(/[0-9]{1,3}/g) || []).length == 3) a = 1;
  489. _a = a;
  490. left = a * 280;
  491. change(hsb.h, hsb.s, hsb.b, a);
  492. })
  493. });
  494. };
  495. //颜色选择器hsb转换
  496. Class.prototype.select = function(h, s, b, type){
  497. var that = this
  498. ,options = that.config
  499. ,hex = HSBToHEX({h:h, s:100, b:100})
  500. ,color = HSBToHEX({h:h, s:s, b:b})
  501. ,sidetop = h/360*180
  502. ,top = 180 - b/100*180 - 3
  503. ,left = s/100*260 - 3;
  504. that.elemPicker.find('.' + PICKER_SIDE_SLIDER).css("top", sidetop); //滑块的top
  505. that.elemPicker.find('.' + PICKER_BASIS)[0].style.background = '#' + hex; //颜色选择器的背景
  506. //选择器的top left
  507. that.elemPicker.find('.' + PICKER_BASIS_CUR).css({
  508. "top": top
  509. ,"left": left
  510. });
  511. if(type === 'change') return;
  512. //选中的颜色
  513. that.elemPicker.find('.' + PICKER_INPUT).find('input').val('#' + color);
  514. };
  515. Class.prototype.pickerEvents = function(){
  516. var that = this
  517. ,options = that.config
  518. ,elemColorBoxSpan = that.elemColorBox.find('.' + PICKER_TRIG_SPAN) //颜色盒子
  519. ,elemPickerInput = that.elemPicker.find('.' + PICKER_INPUT + ' input') //颜色选择器表单
  520. ,pickerEvents = {
  521. //清空
  522. clear: function(othis){
  523. elemColorBoxSpan[0].style.background ='';
  524. that.elemColorBox.find('.' + PICKER_TRIG_I).removeClass(ICON_PICKER_DOWN).addClass(ICON_PICKER_CLOSE);
  525. that.color = '';
  526. options.done && options.done('');
  527. that.removePicker();
  528. }
  529. //确认
  530. ,confirm: function(othis, change){
  531. var value = elemPickerInput.val()
  532. ,colorValue = value
  533. ,hsb = {};
  534. if(value.indexOf(',') > -1){
  535. hsb = RGBToHSB(RGBSTo(value));
  536. that.select(hsb.h, hsb.s, hsb.b);
  537. elemColorBoxSpan[0].style.background = (colorValue = '#' + HSBToHEX(hsb));
  538. if((value.match(/[0-9]{1,3}/g) || []).length > 3 && elemColorBoxSpan.attr('lay-type') === 'rgba'){
  539. var left = value.slice(value.lastIndexOf(",") + 1, value.length - 1) * 280;
  540. that.elemPicker.find('.' + PICKER_ALPHA_SLIDER).css("left", left);
  541. elemColorBoxSpan[0].style.background = value;
  542. colorValue = value;
  543. };
  544. } else {
  545. hsb = HEXToHSB(value);
  546. elemColorBoxSpan[0].style.background = (colorValue = '#' + HSBToHEX(hsb));
  547. that.elemColorBox.find('.' + PICKER_TRIG_I).removeClass(ICON_PICKER_CLOSE).addClass(ICON_PICKER_DOWN);
  548. };
  549. if(change === 'change'){
  550. that.select(hsb.h, hsb.s, hsb.b, change);
  551. options.change && options.change(colorValue);
  552. return;
  553. }
  554. that.color = value;
  555. options.done && options.done(value);
  556. that.removePicker();
  557. }
  558. };
  559. //选择器面板点击事件
  560. that.elemPicker.on('click', '*[colorpicker-events]', function(){
  561. var othis = $(this)
  562. ,attrEvent = othis.attr('colorpicker-events');
  563. pickerEvents[attrEvent] && pickerEvents[attrEvent].call(this, othis);
  564. });
  565. //输入框事件
  566. elemPickerInput.on('keyup', function(e){
  567. var othis = $(this)
  568. pickerEvents.confirm.call(this, othis, e.keyCode === 13 ? null : 'change');
  569. });
  570. }
  571. //颜色选择器输入
  572. Class.prototype.events = function(){
  573. var that = this
  574. ,options = that.config
  575. ,elemColorBoxSpan = that.elemColorBox.find('.' + PICKER_TRIG_SPAN)
  576. //弹出颜色选择器
  577. that.elemColorBox.on('click' , function(){
  578. that.renderPicker();
  579. if($(ELEM_MAIN)[0]){
  580. that.val();
  581. that.side();
  582. };
  583. });
  584. if(!options.elem[0] || that.elemColorBox[0].eventHandler) return;
  585. //绑定关闭控件事件
  586. $doc.on('click', function(e){
  587. //如果点击的元素是颜色框
  588. if($(e.target).hasClass(ELEM)
  589. || $(e.target).parents('.'+ELEM)[0]
  590. ) return;
  591. //如果点击的元素是选择器
  592. if($(e.target).hasClass(ELEM_MAIN.replace(/\./g, ''))
  593. || $(e.target).parents(ELEM_MAIN)[0]
  594. ) return;
  595. if(!that.elemPicker) return;
  596. if(that.color){
  597. var hsb = RGBToHSB(RGBSTo(that.color));
  598. that.select(hsb.h, hsb.s, hsb.b);
  599. } else {
  600. that.elemColorBox.find('.' + PICKER_TRIG_I).removeClass(ICON_PICKER_DOWN).addClass(ICON_PICKER_CLOSE);
  601. }
  602. elemColorBoxSpan[0].style.background = that.color || '';
  603. that.removePicker();
  604. });
  605. //自适应定位
  606. $win.on('resize', function(){
  607. if(!that.elemPicker || !$(ELEM_MAIN)[0]){
  608. return false;
  609. }
  610. that.position();
  611. });
  612. that.elemColorBox[0].eventHandler = true;
  613. };
  614. //核心入口
  615. colorpicker.render = function(options){
  616. var inst = new Class(options);
  617. return thisColorPicker.call(inst);
  618. };
  619. exports(MOD_NAME, colorpicker);
  620. });