/* colpick Color Picker 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 For usage and examples: colpick.com/plugin */ /* global console, document, Element, EventBridge, jQuery, navigator, window, _ $ */ (function ($) { var colpick = function () { var tpl = '
' + '
' + '
' + '
' + '
' + '
#
' + '
' + '
R
' + '
' + '
' + '
G
' + '
' + '
B
' + '
' + '
' + '
H
' + '
' + '
' + '
S
' + '
' + '
' + '
B
' + '
' + '
' + '
', defaults = { showEvent: 'click', onShow: function () {}, onBeforeShow: function(){}, onHide: function () {}, onChange: function () {}, onSubmit: function () {}, colorScheme: 'light', color: '3289c7', livePreview: true, flat: false, layout: 'full', submit: 1, submitText: 'OK', height: 156 }, // Fill the inputs of the plugin fillRGBFields = function (hsb, cal) { var rgb = hsbToRgb(hsb); $(cal).data('colpick').fields .eq(1).val(rgb.r).end() .eq(2).val(rgb.g).end() .eq(3).val(rgb.b).end(); }, fillHSBFields = function (hsb, cal) { $(cal).data('colpick').fields .eq(4).val(Math.round(hsb.h)).end() .eq(5).val(Math.round(hsb.s)).end() .eq(6).val(Math.round(hsb.b)).end(); }, fillHexFields = function (hsb, cal) { $(cal).data('colpick').fields.eq(0).val(hsbToHex(hsb)); }, // Set the round selector position setSelector = function (hsb, cal) { $(cal).data('colpick').selector.css('backgroundColor', '#' + hsbToHex({h: hsb.h, s: 100, b: 100})); $(cal).data('colpick').selectorIndic.css({ left: parseInt($(cal).data('colpick').height * hsb.s/100, 10), top: parseInt($(cal).data('colpick').height * (100-hsb.b)/100, 10) }); }, // Set the hue selector position setHue = function (hsb, cal) { $(cal).data('colpick').hue.css('top', parseInt($(cal).data('colpick').height - $(cal).data('colpick').height * hsb.h / 360, 10)); }, // Set current and new colors setCurrentColor = function (hsb, cal) { $(cal).data('colpick').currentColor.css('backgroundColor', '#' + hsbToHex(hsb)); }, setNewColor = function (hsb, cal) { $(cal).data('colpick').newColor.css('backgroundColor', '#' + hsbToHex(hsb)); }, // Called when the new color is changed change = function (ev) { var cal = $(this).parent().parent(), col; if (this.parentNode.className.indexOf('_hex') > 0) { cal.data('colpick').color = col = hexToHsb(fixHex(this.value)); fillRGBFields(col, cal.get(0)); fillHSBFields(col, cal.get(0)); fillHexFields(col, cal.get(0)); } else if (this.parentNode.className.indexOf('_hsb') > 0) { cal.data('colpick').color = col = fixHSB({ h: parseInt(cal.data('colpick').fields.eq(4).val(), 10), s: parseInt(cal.data('colpick').fields.eq(5).val(), 10), b: parseInt(cal.data('colpick').fields.eq(6).val(), 10) }); fillRGBFields(col, cal.get(0)); fillHexFields(col, cal.get(0)); fillHSBFields(col, cal.get(0)); } else { cal.data('colpick').color = col = rgbToHsb(fixRGB({ r: parseInt(cal.data('colpick').fields.eq(1).val(), 10), g: parseInt(cal.data('colpick').fields.eq(2).val(), 10), b: parseInt(cal.data('colpick').fields.eq(3).val(), 10) })); fillHexFields(col, cal.get(0)); fillHSBFields(col, cal.get(0)); fillRGBFields(col, cal.get(0)); } setSelector(col, cal.get(0)); setHue(col, cal.get(0)); setNewColor(col, cal.get(0)); cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 0]); }, // Change style on blur and on focus of inputs blur = function (ev) { $(this).parent().removeClass('colpick_focus'); }, focus = function () { $(this).parent().parent().data('colpick').fields.parent().removeClass('colpick_focus'); $(this).parent().addClass('colpick_focus'); }, // Increment/decrement arrows functions downIncrement = function (ev) { ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; var field = $(this).parent().find('input').focus(); var current = { el: $(this).parent().addClass('colpick_slider'), max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255), y: ev.pageY, field: field, val: parseInt(field.val(), 10), preview: $(this).parent().parent().data('colpick').livePreview }; $(document).mouseup(current, upIncrement); $(document).mousemove(current, moveIncrement); }, moveIncrement = function (ev) { ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val - ev.pageY + ev.data.y, 10)))); if (ev.data.preview) { change.apply(ev.data.field.get(0), [true]); } return false; }, upIncrement = function (ev) { change.apply(ev.data.field.get(0), [true]); ev.data.el.removeClass('colpick_slider').find('input').focus(); $(document).off('mouseup', upIncrement); $(document).off('mousemove', moveIncrement); return false; }, // Hue slider functions downHue = function (ev) { ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; var current = { cal: $(this).parent(), y: $(this).offset().top }; $(document).on('mouseup touchend',current,upHue); $(document).on('mousemove touchmove',current,moveHue); var pageY = ((ev.type === 'touchstart') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( current.cal.data('colpick') .fields.eq(4).val(parseInt(360 * (current.cal.data('colpick').height - (pageY - current.y)) / current.cal.data('colpick').height, 10)) .get(0), [current.cal.data('colpick').livePreview] ); return false; }, moveHue = function (ev) { var pageY = ((ev.type === 'touchmove') ? ev.originalEvent.changedTouches[0].pageY : ev.pageY ); change.apply( ev.data.cal.data('colpick') .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)) .get(0), [ev.data.preview] ); return false; }, upHue = function (ev) { fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); $(document).off('mouseup touchend',upHue); $(document).off('mousemove touchmove',moveHue); return false; }, // Color selector functions downSelector = function (ev) { ev.preventDefault ? ev.preventDefault() : ev.returnValue = false; var current = { cal: $(this).parent(), pos: $(this).offset() }; current.preview = current.cal.data('colpick').livePreview; $(document).on('mouseup touchend',current,upSelector); $(document).on('mousemove touchmove',current,moveSelector); var pageX,pageY; if (ev.type === 'touchstart') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; } else { pageX = ev.pageX; pageY = ev.pageY; } change.apply( current.cal.data('colpick').fields .eq(6).val(parseInt(100 * (current.cal.data('colpick').height - (pageY - current.pos.top)) / current.cal.data('colpick').height, 10)).end() .eq(5).val(parseInt(100*(pageX - current.pos.left)/current.cal.data('colpick').height, 10)) .get(0), [current.preview] ); return false; }, moveSelector = function (ev) { var pageX,pageY; if (ev.type === 'touchmove') { pageX = ev.originalEvent.changedTouches[0].pageX, pageY = ev.originalEvent.changedTouches[0].pageY; } else { pageX = ev.pageX; pageY = ev.pageY; } change.apply( ev.data.cal.data('colpick').fields .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() .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)) .get(0), [ev.data.preview] ); return false; }, upSelector = function (ev) { fillRGBFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); fillHexFields(ev.data.cal.data('colpick').color, ev.data.cal.get(0)); $(document).off('mouseup touchend',upSelector); $(document).off('mousemove touchmove',moveSelector); return false; }, // Submit button clickSubmit = function (ev) { var cal = $(this).parent(); var col = cal.data('colpick').color; cal.data('colpick').origColor = col; setCurrentColor(col, cal.get(0)); cal.data('colpick').onSubmit(col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el); }, // Show/hide the color picker show = function (ev) { if ($(this).attr('disabled')) { return; } // Prevent the trigger of any direct parent ev.stopPropagation(); var cal = $('#' + $(this).data('colpickId')); cal.data('colpick').onBeforeShow.apply(this, [cal.get(0)]); var pos = $(this).offset(); var top = pos.top + this.offsetHeight; var left = pos.left; var viewPort = getViewport(); var calW = cal.width(); if (left + calW > viewPort.l + viewPort.w) { left -= calW; } cal.css({left: left + 'px', top: top + 'px'}); if (cal.data('colpick').onShow.apply(this, [cal.get(0)]) !== false) { cal.show(); } // Hide when user clicks outside $('html').mousedown({cal:cal}, hide); cal.mousedown(function(ev){ ev.stopPropagation(); }); }, hide = function (ev) { if (ev.data.cal.data('colpick').onHide.apply(this, [ev.data.cal.get(0)]) !== false) { ev.data.cal.hide(); } $('html').off('mousedown', hide); }, getViewport = function () { var m = document.compatMode === 'CSS1Compat'; return { l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft), w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth) }; }, // Fix the values if the user enters a negative or high value fixHSB = function (hsb) { return { h: Math.min(360, Math.max(0, hsb.h)), s: Math.min(100, Math.max(0, hsb.s)), b: Math.min(100, Math.max(0, hsb.b)) }; }, fixRGB = function (rgb) { return { r: Math.min(255, Math.max(0, rgb.r)), g: Math.min(255, Math.max(0, rgb.g)), b: Math.min(255, Math.max(0, rgb.b)) }; }, fixHex = function (hex) { var len = 6 - hex.length; if (len > 0) { var o = []; for (var i=0; i').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] + ')";'); huebar.append(div); } } else { var stopList = stops.join(','); huebar.attr('style', 'background:-webkit-linear-gradient(top,' + stopList + '); background: -o-linear-gradient(top,' + stopList + '); background: -ms-linear-gradient(top,' + stopList + '); background:-moz-linear-gradient(top,' + stopList + '); -webkit-linear-gradient(top,' + stopList + '); background:linear-gradient(to bottom,' + stopList + '); '); } cal.find('div.colpick_hue').on('mousedown touchstart',downHue); options.newColor = cal.find('div.colpick_new_color'); options.currentColor = cal.find('div.colpick_current_color'); // Store options and fill with default color cal.data('colpick', options); fillRGBFields(options.color, cal.get(0)); fillHSBFields(options.color, cal.get(0)); fillHexFields(options.color, cal.get(0)); setHue(options.color, cal.get(0)); setSelector(options.color, cal.get(0)); setCurrentColor(options.color, cal.get(0)); setNewColor(options.color, cal.get(0)); // Append to body if flat=false, else show in place if (options.flat) { cal.appendTo(this).show(); cal.css({ position: 'relative', display: 'block' }); } else { cal.appendTo(document.body); $(this).on(options.showEvent, show); cal.css({ position:'absolute' }); } } }); }, // Shows the picker showPicker: function() { return this.each( function () { if ($(this).data('colpickId')) { show.apply(this); } }); }, // Hides the picker hidePicker: function() { return this.each( function () { if ($(this).data('colpickId')) { $('#' + $(this).data('colpickId')).hide(); } }); }, // Sets a color as new and current (default) setColor: function(col, setCurrent) { setCurrent = (typeof setCurrent === "undefined") ? 1 : setCurrent; if (typeof col === 'string') { col = hexToHsb(col); } else if (col.r !== undefined && col.g !== undefined && col.b !== undefined) { col = rgbToHsb(col); } else if (col.h !== undefined && col.s !== undefined && col.b !== undefined) { col = fixHSB(col); } else { return this; } return this.each(function(){ if ($(this).data('colpickId')) { var cal = $('#' + $(this).data('colpickId')); cal.data('colpick').color = col; cal.data('colpick').origColor = col; fillRGBFields(col, cal.get(0)); fillHSBFields(col, cal.get(0)); fillHexFields(col, cal.get(0)); setHue(col, cal.get(0)); setSelector(col, cal.get(0)); setNewColor(col, cal.get(0)); cal.data('colpick').onChange.apply(cal.parent(), [col, hsbToHex(col), hsbToRgb(col), cal.data('colpick').el, 1]); if (setCurrent) { setCurrentColor(col, cal.get(0)); } } }); } }; }(); // Color space convertions var hexToRgb = function (hexString) { if (typeof hexString !== "string") { print("Error - ColPick.js::hexToRgb expects string object."); return; } var hexNumber = parseInt(((hexString.indexOf('#') > -1) ? hexString.substring(1) : hexString), 16); return { r: hexNumber >> 16, g: (hexNumber & 0x00FF00) >> 8, b: (hexNumber & 0x0000FF)}; }; var hexToHsb = function (hexString) { if (typeof hexString !== "string") { print("Error - ColPick.js::hexToHsb expects string object."); return; } return rgbToHsb(hexToRgb(hexString)); }; var 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; // eslint-disable-line eqeqeq if (hsb.s != 0) { // eslint-disable-line eqeqeq if (rgb.r == max) { // eslint-disable-line eqeqeq hsb.h = (rgb.g - rgb.b) / delta; } else if (rgb.g == max) { // eslint-disable-line eqeqeq 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; }; var hsbToRgb = function (hsb) { var rgb = {}; var h = hsb.h; var s = hsb.s*255/100; var v = hsb.b*255/100; if (s == 0) { // eslint-disable-line eqeqeq 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) { // eslint-disable-line eqeqeq 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)}; }; var rgbToHex = function (rgb) { var hex = [ rgb.r.toString(16), rgb.g.toString(16), rgb.b.toString(16) ]; $.each(hex, function (nr, val) { if (val.length == 1) { // eslint-disable-line eqeqeq hex[nr] = '0' + val; } }); return hex.join(''); }; var hsbToHex = function (hsb) { return rgbToHex(hsbToRgb(hsb)); }; $.fn.extend({ colpick: colpick.init, colpickHide: colpick.hidePicker, colpickShow: colpick.showPicker, colpickSetColor: colpick.setColor }); $.extend({ colpick:{ rgbToHex: rgbToHex, rgbToHsb: rgbToHsb, hsbToHex: hsbToHex, hsbToRgb: hsbToRgb, hexToHsb: hexToHsb, hexToRgb: hexToRgb } }); })(jQuery);