/* * Bootstrap Color Picker Sliders - v3.0.1 * * Bootstrap 3 optimized responsive color selector with HSV, HSL, RGB and CIE-Lch (which supports human perceived lightness) selectors and color swatches. * http://www.virtuosoft.eu/code/bootstrap-colorpickersliders/ * * Made by István Ujj-Mészáros * Under Apache License v2.0 License * * Requirements: * * TinyColor: https://github.com/bgrins/TinyColor/ * * Using color math algorithms from EasyRGB Web site:/ * http://www.easyrgb.com/index.php?X=MATH */ (function($) { 'use strict'; $.fn.ColorPickerSliders = function(options) { return this.each(function() { var alreadyinitialized = false, settings, triggerelement = $(this), triggerelementisinput = triggerelement.is('input'), container, popover_container, elements, connectedinput = false, swatches, groupingname = '', rendermode = false, visible = false, MAXLIGHT = 101, // 101 needed for bright colors (maybe due to rounding errors) dragTarget = false, lastUpdateTime = 0, _moveThrottleTimer = null, _throttleDelay = 70, _inMoveHandler = false, _lastMoveHandlerRun = 0, color = { tiny: null, hsla: null, rgba: null, hsv: null, cielch: null }, MAXVALIDCHROMA = 144; // maximum valid chroma value found convertible to rgb (blue) init(); function _initSettings() { if (typeof options === 'undefined') { options = {}; } settings = $.extend({ color: 'hsl(342, 52%, 70%)', size: 'default', // sm | default | lg placement: 'auto', trigger: 'focus', // focus | manual preventtouchkeyboardonshow: true, // makes the input readonly and needs a second click to be editable title: '', hsvpanel: false, sliders: true, grouping: true, swatches: ['FFFFFF', 'C0C0C0', '808080', '000000', 'FF0000', '800000', 'FFFF00', '808000', '00FF00', '008000', '00FFFF', '008080', '0000FF', '000080', 'FF00FF', '800080'], // array or false to disable swatches customswatches: 'colorpickkersliders', // false or a grop name connectedinput: false, // can be a jquery object or a selector flat: false, updateinterval: 30, // update interval of the sliders while in drag (ms) previewontriggerelement: true, previewcontrasttreshold: 15, previewformat: 'rgb', // rgb | hsl | hex erroneousciecolormarkers: true, invalidcolorsopacity: 1, // everything below 1 causes slightly slower responses finercierangeedges: true, // can be disabled for faster responses titleswatchesadd: 'Add color to swatches', titleswatchesremove: 'Remove color from swatches', titleswatchesreset: 'Reset to default swatches', order: {}, labels: {}, onchange: function() { } }, options); if (options.hasOwnProperty('order')) { settings.order = $.extend({ opacity: false, hsl: false, rgb: false, cie: false, preview: false }, options.order); } else { settings.order = { opacity: 0, hsl: 1, rgb: 2, cie: 3, // cie sliders can increase response time of all sliders! preview: 4 }; } if (!options.hasOwnProperty('labels')) { options.labels = {}; } settings.labels = $.extend({ hslhue: 'HSL-Hue', hslsaturation: 'HSL-Saturation', hsllightness: 'HSL-Lightness', rgbred: 'RGB-Red', rgbgreen: 'RGB-Green', rgbblue: 'RGB-Blue', cielightness: 'CIE-Lightness', ciechroma: 'CIE-Chroma', ciehue: 'CIE-hue', opacity: 'Opacity', preview: 'Preview' }, options.labels); } function init() { if (alreadyinitialized) { return; } alreadyinitialized = true; rendermode = $.fn.ColorPickerSliders.detectWhichGradientIsSupported(); if (rendermode === 'filter') { rendermode = false; } if (!rendermode && $.fn.ColorPickerSliders.svgSupported()) { rendermode = 'svg'; } _initSettings(); // force preview when browser doesn't support css gradients if ((!settings.order.hasOwnProperty('preview') || settings.order.preview === false) && !rendermode) { settings.order.preview = 10; } _initConnectedElements(); _initColor(); _initConnectedinput(); _updateTriggerelementColor(); _updateConnectedInput(); if (settings.flat) { showFlat(); } _bindEvents(); } function _buildComponent() { _initElements(); _renderSwatches(); _updateAllElements(); _bindControllerEvents(); } function _initColor() { if (triggerelementisinput) { color.tiny = tinycolor(triggerelement.val()); if (!color.tiny.isValid()) { color.tiny = tinycolor(settings.color); } } else { color.tiny = tinycolor(settings.color); } color.hsla = color.tiny.toHsl(); color.rgba = color.tiny.toRgb(); color.hsv = color.tiny.toHsv(); color.cielch = $.fn.ColorPickerSliders.rgb2lch(color.rgba); } function _initConnectedinput() { if (settings.connectedinput) { if (settings.connectedinput instanceof jQuery) { connectedinput = settings.connectedinput; } else { connectedinput = $(settings.connectedinput); } } } function updateColor(newcolor, disableinputupdate) { var updatedcolor = tinycolor(newcolor); if (updatedcolor.isValid()) { color.tiny = updatedcolor; color.hsla = updatedcolor.toHsl(); color.rgba = updatedcolor.toRgb(); color.hsv = updatedcolor.toHsv(); color.cielch = $.fn.ColorPickerSliders.rgb2lch(color.rgba); if (settings.flat || visible) { container.removeClass('cp-unconvertible-cie-color'); _updateAllElements(disableinputupdate); } else { if (!disableinputupdate) { _updateConnectedInput(); } _updateTriggerelementColor(); } return true; } else { return false; } } function show(disableLastlyUsedGroupUpdate) { if (settings.flat) { return; } if (visible) { // repositions the popover triggerelement.popover('hide'); triggerelement.popover('show'); _bindControllerEvents(); return; } showPopover(disableLastlyUsedGroupUpdate); visible = true; } function hide() { visible = false; hidePopover(); } function showPopover(disableLastlyUsedGroupUpdate) { if (popover_container instanceof jQuery) { return; } if (typeof disableLastlyUsedGroupUpdate === 'undefined') { disableLastlyUsedGroupUpdate = false; } popover_container = $('
').appendTo( triggerelement.parents('.twoj_block')); container = $('
').appendTo(popover_container); // console.log( triggerelement.data('callback')+'ffff' ); //container.data('callback', triggerelement.data('callback') ); container.html(_getControllerHtml()); switch (settings.size) { case 'sm': container.addClass('cp-container-sm'); break; case 'lg': container.addClass('cp-container-lg'); break; } _buildComponent(); if (!disableLastlyUsedGroupUpdate) { activateLastlyUsedGroup(); } triggerelement.popover({ html: true, animation: false, trigger: 'manual', title: settings.title, placement: settings.placement, container: popover_container, content: function() { return container; } }); triggerelement.popover('show'); } function hidePopover() { popover_container.remove(); popover_container = null; triggerelement.popover('destroy'); } function _getControllerHtml() { var sliders = [], color_picker_html = ''; if (settings.sliders) { if (settings.order.opacity !== false) { sliders[settings.order.opacity] = '
' + settings.labels.opacity + '
'; } if (settings.order.hsl !== false) { sliders[settings.order.hsl] = '
' + settings.labels.hslhue + '
' + settings.labels.hslsaturation + '
' + settings.labels.hsllightness + '
'; } if (settings.order.rgb !== false) { sliders[settings.order.rgb] = '
' + settings.labels.rgbred + '
' + settings.labels.rgbgreen + '
' + settings.labels.rgbblue + '
'; } if (settings.order.cie !== false) { sliders[settings.order.cie] = '
' + settings.labels.cielightness + '
' + settings.labels.ciechroma + '
' + settings.labels.ciehue + '
'; } if (settings.order.preview !== false) { sliders[settings.order.preview] = '
'; } } if (settings.grouping) { if (!!settings.hsvpanel + !!(settings.sliders && sliders.length > 0) + !!settings.swatches > 1) { color_picker_html += '