(function () { var util = { css: function (elem, obj) { for (var i in obj) { elem.style[i] = obj[i]; } }, hasClass: function (elem, classN) { var className = elem.getAttribute("class"); return className.indexOf(classN) != -1; } }; function Colorpicker(opt) { if (this === window) throw `Colorpicker: Can't call a function directly`; this.init(opt); }; Colorpicker.prototype = { init(opt) { let { el, initColor = "rgb(255,0,0)", allMode = ['hex', 'rgb'], color = '' } = opt; var elem = document.getElementById(el); if (!(elem && elem.nodeType && elem.nodeType === 1)) { throw `Colorpicker: not found ID:${el} HTMLElement,not ${{}.toString.call(el)}`; } this.Opt = { ...opt, el, initColor, allMode, color } this.bindElem = elem; // 缁戝畾鐨勫厓绱� this.elem_wrap = null; // 鏈€澶栧眰瀹瑰櫒 this.fixedBg = null; // 鎷捐壊鍣ㄥ悗闈㈠浐瀹氬畾浣嶇殑閫忔槑div 鐢ㄤ簬鐐瑰嚮闅愯棌鎷捐壊鍣� this.elem_colorPancel = null; // 鑹插僵闈㈡澘 this.elem_picker = null; // 鎷捐壊鍣ㄨ壊鍧楁寜閽� this.elem_barPicker1 = null; // 棰滆壊鏉� this.elem_hexInput = null; // 鏄剧ずhex鐨勮〃鍗� this.elem_showColor = null; // 鏄剧ず褰撳墠棰滆壊 this.elem_showModeBtn = null; // 鍒囨崲杈撳叆妗嗘ā寮忔寜閽� this.elem_inputWrap = null; // 杈撳叆妗嗗灞傚鍣� this.pancelLeft = 0; this.pancelTop = 0; this.downX = 0; this.downY = 0; this.moveX = 0; this.moveY = 0; this.pointLeft = 0; this.pointTop = 0; this.current_mode = 'hex'; // input妗嗗綋鍓嶇殑妯″紡 this.rgba = { r: 0, g: 0, b: 0, a: 1 }; this.hsb = { h: 0, s: 100, b: 100 }; var _this = this, rgb = initColor.slice(4, -1).split(","); this.rgba.r = parseInt(rgb[0]); this.rgba.g = parseInt(rgb[1]); this.rgba.b = parseInt(rgb[2]); var body = document.getElementsByTagName("body")[0], div = document.createElement("div"); div.innerHTML = this.render(); body.appendChild(div); this.elem_wrap = div; this.fixedBg = div.children[0]; this.elem_colorPancel = div.getElementsByClassName("color-pancel")[0]; this.pancel_width = this.elem_colorPancel.offsetWidth; this.pancel_height = this.elem_colorPancel.offsetHeight; this.elem_picker = div.getElementsByClassName("pickerBtn")[0]; this.elem_colorPalette = div.getElementsByClassName("color-palette")[0]; this.elem_showColor = div.getElementsByClassName("colorpicker-showColor")[0]; this.elem_barPicker1 = div.getElementsByClassName("colorBar-color-picker")[0]; /* this.elem_barPicker2 = div.getElementsByClassName("colorBar-opacity-picker")[0]; */ this.elem_hexInput = div.getElementsByClassName("colorpicker-hexInput")[0]; this.elem_showModeBtn = div.getElementsByClassName("colorpicker-showModeBtn")[0]; this.elem_inputWrap = div.getElementsByClassName("colorpicker-inputWrap")[0]; /* this.elem_opacityPancel = this.elem_barPicker2.parentNode.parentNode.children[1]; */ // var rect = this.bindElem.getBoundingClientRect(); var elem = this.bindElem; var top = elem.offsetTop; var left = elem.offsetLeft; while (elem.offsetParent) { top += elem.offsetParent.offsetTop; left += elem.offsetParent.offsetLeft; elem = elem.offsetParent; } this.pancelLeft = left + this.elem_colorPalette.clientWidth; this.pancelTop = top + this.bindElem.offsetHeight; util.css(div, { "position": "absolute", "z-index": 999999999999999, "display": 'none', "left": left + "px", "top": top + this.bindElem.offsetHeight + "px" }); this.bindMove(this.elem_colorPancel, this.setPosition, true); this.bindMove(this.elem_barPicker1.parentNode, this.setBar, false); /* this.bindMove(this.elem_barPicker2.parentNode,this.setBar,false); */ this.bindElem.addEventListener("click", function () { _this.show(); }, false); this.fixedBg.addEventListener("click", function (e) { _this.hide(); }, false) this.elem_showModeBtn.addEventListener("click", function () { _this.switch_current_mode(); }, false) this.elem_wrap.addEventListener("input", function (e) { var target = e.target, value = target.value; _this.setColorByInput(value); }, false); this.elem_colorPalette.addEventListener("click", function (e) { if (e.target.tagName.toLocaleLowerCase() == "p") { let colorStr = e.target.style.background; let rgb = colorStr.slice(4, -1).split(","); let rgba = { r: parseInt(rgb[0]), g: parseInt(rgb[1]), b: parseInt(rgb[2]) } switch (_this.current_mode) { case "hex": _this.setColorByInput("#" + _this.rgbToHex(rgba)) break; case 'rgb': let inputs = _this.elem_wrap.getElementsByTagName("input") inputs[0].value = rgba.r; inputs[1].value = rgba.g; inputs[2].value = rgba.b; _this.setColorByInput(colorStr) /* _this.hsb = _this.rgbToHsb(rgba); */ break; } } }, false); (color != '' && this.setColorByInput(color)); }, render: function () { var tpl = `
${this.getPaletteColorsItem()}
${this.getInputTpl()}
`; return tpl; }, getInputTpl: function () { var current_mode_html = ""; switch (this.current_mode) { case 'hex': var hex = "#" + this.rgbToHex(this.HSBToRGB(this.hsb)); current_mode_html += `
hex
`; break; case 'rgb': for (var i = 0; i < 3; i++) { current_mode_html += `
${'rgb'[i]}
`; } default: } return current_mode_html; }, getPaletteColorsItem: function () { let str = ''; let palette = ["rgb(0, 0, 0)", "rgb(67, 67, 67)", "rgb(102, 102, 102)", "rgb(204, 204, 204)", "rgb(217, 217, 217)", "rgb(255, 255, 255)", "rgb(152, 0, 0)", "rgb(255, 0, 0)", "rgb(255, 153, 0)", "rgb(255, 255, 0)", "rgb(0, 255, 0)", "rgb(0, 255, 255)", "rgb(74, 134, 232)", "rgb(0, 0, 255)", "rgb(153, 0, 255)", "rgb(255, 0, 255)", "rgb(230, 184, 175)", "rgb(244, 204, 204)", "rgb(252, 229, 205)", "rgb(255, 242, 204)", "rgb(217, 234, 211)", "rgb(208, 224, 227)", "rgb(201, 218, 248)", "rgb(207, 226, 243)", "rgb(217, 210, 233)", "rgb(234, 209, 220)", "rgb(221, 126, 107)", "rgb(234, 153, 153)", "rgb(249, 203, 156)", "rgb(255, 229, 153)", "rgb(182, 215, 168)", "rgb(162, 196, 201)", "rgb(164, 194, 244)", "rgb(159, 197, 232)", "rgb(180, 167, 214)"] palette.forEach(item => str += `

`) return str; }, setPosition(x, y) { var LEFT = parseInt(x - this.pancelLeft), TOP = parseInt(y - this.pancelTop); this.pointLeft = Math.max(0, Math.min(LEFT, this.pancel_width)); this.pointTop = Math.max(0, Math.min(TOP, this.pancel_height)); util.css(this.elem_picker, { left: this.pointLeft + "px", top: this.pointTop + "px" }) this.hsb.s = parseInt(100 * this.pointLeft / this.pancel_width); this.hsb.b = parseInt(100 * (this.pancel_height - this.pointTop) / this.pancel_height); this.setShowColor(); this.setValue(this.rgba); }, setBar: function (elem, x) { var elem_bar = elem.getElementsByTagName("div")[0], rect = elem.getBoundingClientRect(), elem_width = elem.offsetWidth, X = Math.max(0, Math.min(x - rect.x, elem_width)); if (elem_bar === this.elem_barPicker1) { util.css(elem_bar, { left: X + "px" }); this.hsb.h = parseInt(360 * X / elem_width); } else { util.css(elem_bar, { left: X + "px" }); this.rgba.a = X / elem_width; } this.setPancelColor(this.hsb.h); this.setShowColor(); this.setValue(this.rgba); }, setPancelColor: function (h) { var rgb = this.HSBToRGB({ h: h, s: 100, b: 100 }); util.css(this.elem_colorPancel, { background: 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + this.rgba.a + ')' }); }, setShowColor: function () { var rgb = this.HSBToRGB(this.hsb); this.rgba.r = rgb.r; this.rgba.g = rgb.g; this.rgba.b = rgb.b; util.css(this.elem_showColor, { background: 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + this.rgba.a + ')' }); }, setValue: function (rgb) { var hex = "#" + this.rgbToHex(rgb); this.elem_inputWrap.innerHTML = this.getInputTpl(); console.log("1") this.Opt.change(this.bindElem, hex); }, setColorByInput: function (value) { var _this = this; switch (this.current_mode) { case "hex": value = value.slice(1); if (value.length == 3) { value = '#' + value[0] + value[0] + value[1] + value[1] + value[2] + value[2]; this.hsb = this.hexToHsb(value); } else if (value.length == 6) { this.hsb = this.hexToHsb(value); } break; case 'rgb': var inputs = this.elem_wrap.getElementsByTagName("input"), rgb = { r: inputs[0].value ? parseInt(inputs[0].value) : 0, g: inputs[1].value ? parseInt(inputs[1].value) : 0, b: inputs[2].value ? parseInt(inputs[2].value) : 0 }; this.hsb = this.rgbToHsb(rgb); } this.changeViewByHsb(); }, changeViewByHsb: function () { this.pointLeft = parseInt(this.hsb.s * this.pancel_width / 100); this.pointTop = parseInt((100 - this.hsb.b) * this.pancel_height / 100); util.css(this.elem_picker, { left: this.pointLeft + "px", top: this.pointTop + "px" }); this.setPancelColor(this.hsb.h); this.setShowColor(); util.css(this.elem_barPicker1, { left: this.hsb.h / 360 * (this.elem_barPicker1.parentNode.offsetWidth) + "px" }); var hex = '#' + this.rgbToHex(this.HSBToRGB(this.hsb)); console.log("2") this.Opt.change(this.bindElem, hex); }, switch_current_mode: function () { this.current_mode = this.current_mode == 'hex' ? 'rgb' : 'hex'; this.elem_inputWrap.innerHTML = this.getInputTpl(); }, bindMove: function (elem, fn, bool) { var _this = this; elem.addEventListener("mousedown", function (e) { _this.downX = e.pageX; _this.downY = e.pageY; bool ? fn.call(_this, _this.downX, _this.downY) : fn.call(_this, elem, _this.downX, _this.downY); document.addEventListener("mousemove", mousemove, false); function mousemove(e) { _this.moveX = e.pageX; _this.moveY = e.pageY; bool ? fn.call(_this, _this.moveX, _this.moveY) : fn.call(_this, elem, _this.moveX, _this.moveY); e.preventDefault(); } document.addEventListener("mouseup", mouseup, false); function mouseup(e) { document.removeEventListener("mousemove", mousemove, false) document.removeEventListener("mouseup", mouseup, false) } }, false); }, show: function () { util.css(this.elem_wrap, { "display": "block" }) }, hide: function () { util.css(this.elem_wrap, { "display": "none" }) }, HSBToRGB: function (hsb) { var rgb = {}; var h = Math.round(hsb.h); var s = Math.round(hsb.s * 255 / 100); var v = Math.round(hsb.b * 255 / 100); if (s == 0) { rgb.r = rgb.g = rgb.b = v; } else { var t1 = v; var t2 = (255 - s) * v / 255; var t3 = (t1 - t2) * (h % 60) / 60; if (h == 360) h = 0; if (h < 60) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3 } else if (h < 120) { rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3 } else if (h < 180) { rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3 } else if (h < 240) { rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3 } else if (h < 300) { rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3 } else if (h < 360) { rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3 } else { rgb.r = 0; rgb.g = 0; rgb.b = 0 } } return { r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b) }; }, rgbToHex: function (rgb) { var hex = [ rgb.r.toString(16), rgb.g.toString(16), rgb.b.toString(16) ]; hex.map(function (str, i) { if (str.length == 1) { hex[i] = '0' + str; } }); return hex.join(''); }, hexToRgb: function (hex) { var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); return { r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF) }; }, hexToHsb: function (hex) { return this.rgbToHsb(this.hexToRgb(hex)); }, rgbToHsb: function (rgb) { var hsb = { h: 0, s: 0, b: 0 }; var min = Math.min(rgb.r, rgb.g, rgb.b); var max = Math.max(rgb.r, rgb.g, rgb.b); var delta = max - min; hsb.b = max; hsb.s = max != 0 ? 255 * delta / max : 0; if (hsb.s != 0) { if (rgb.r == max) hsb.h = (rgb.g - rgb.b) / delta; else if (rgb.g == max) hsb.h = 2 + (rgb.b - rgb.r) / delta; else hsb.h = 4 + (rgb.r - rgb.g) / delta; } else hsb.h = -1; hsb.h *= 60; if (hsb.h < 0) hsb.h += 360; hsb.s *= 100 / 255; hsb.b *= 100 / 255; return hsb; } } Colorpicker.create = function (opt) { return new Colorpicker(opt) } window.Colorpicker = Colorpicker; })()