├── Gruntfile.js ├── LICENSE.md ├── README.md ├── bower.json ├── colors.js ├── demo ├── index.html ├── index.js └── mod.css ├── development ├── bg.gif ├── bg.png ├── colorPicker.css ├── colors-amd-wrapper.js ├── compatibility.css ├── favicon.ico ├── fmog.png ├── jqColorPicker-amd-wrapper.js ├── qr.png ├── screen-shot-all.jpg └── ui.html ├── index.css ├── index.html ├── index.js ├── jqColorPicker.js ├── jqColorPicker.js.map ├── jqColorPicker.min.js └── package.json /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // Project configuration. 4 | grunt.initConfig({ 5 | pkg: grunt.file.readJSON('package.json'), 6 | uglify: { 7 | options: { 8 | banner: '/*! <%= pkg.name %> - v<%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd") %> */\n', 9 | sourceMap: true, 10 | // sourceMapIncludeSources: true, 11 | sourceMapName: 'jqColorPicker.js.map', 12 | report: 'gzip' 13 | }, 14 | my_target: { 15 | files: [{ 16 | 'jqColorPicker.min.js': ['colors.js', 'jqColorPicker.js'] 17 | }] 18 | } 19 | } 20 | }); 21 | 22 | // Load the plugin that provides the "uglify" task. 23 | grunt.loadNpmTasks('grunt-contrib-uglify'); 24 | 25 | // Default task(s). 26 | grunt.registerTask('default', ['uglify']); 27 | 28 | }; -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Peter Dematté 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # tinyColorPicker and colors 3 | 4 | Looking for mobile first, tiny foot print, fast, scaleable, flexible, pluggable and a rich color model...
5 | This small (5.07KB gZip, 11.39KB minified, no extra HTML, images or css needed) HSB colorpicker is based on a subset of [colors.js](https://github.com/PitPik/colorPicker/blob/master/colors.js) from it's big brother [colorPicker](https://github.com/PitPik/colorPicker/) for a precise and rich color model, supports all modern features like touch and MS pointer, GPU accelerated rendering, battery friendly requestAnimationFrame and provides a lot of hooks for developers to write plugins or extend the UI. 6 | 7 | ##Demo 8 | See **demo** at [dematte.at/tinyColorPicker](http://dematte.at/tinyColorPicker) 9 | 10 | 11 | 12 | Supports WCAG 2.0 calculations for readability based on opacity levels of multiple layers.
13 | Supported color spaces are: rgb, hsv(b), hsl, HEX.
14 | CMYK, CMY, Lab and XYZ and more standards are supported if using [colors.js](https://github.com/PitPik/colorPicker/blob/master/colors.js) from [github.com/PitPik/colorPicker](https://github.com/PitPik/colorPicker/) 15 | 16 | ## Usage 17 | 18 | ```javascript 19 | 20 | 23 | ``` 24 | ```jqColorPicker.min.js``` holds all necessary data such as HTML, CSS and images in one file to run tinyColorPicker. So, it is not needed to include anything else than this single file.
25 | If you need to debug things for development, you can also use ```colors.js```, the color calculation module, and ```jqColorPicker.js```, the UI and interaction module seperately. 26 | ```javascript 27 | 28 | 29 | 32 | ``` 33 | 34 | ## AMD / CommonJS wrapper 35 | tinyColorPicker now supports AMD and CommonJS import (thanks to [Munawwar](https://github.com/Munawwar)) in both, the minified version and the single fies (```colors.js``` and ```jqColorPicker.js```). 36 | 37 | ```javascript 38 | // example for requirejs configuration 39 | requirejs.config({ 40 | baseUrl: 'scripts', 41 | paths: { 42 | jquery: 'lib/jquery-2.2.1.min' 43 | }, 44 | shim: { 45 | 'colorPicker': { 46 | deps: [ 'jquery' ], 47 | exports: 'jQuery.fn.colorPicker' 48 | } 49 | } 50 | }); 51 | 52 | // then use tinyColorPicker in your module... 53 | (function (root, factory) { 54 | if (typeof define === 'function' && define.amd) { 55 | define(['jquery', 'jqColorPicker'], function (jQuery) { 56 | return factory(root, jQuery); 57 | }); 58 | } else { 59 | factory(root, root.jQuery); 60 | } 61 | }(this, function(window, $){ 62 | $('.color').colorPicker(options); 63 | })); 64 | ``` 65 | 66 | ## Bower support 67 | tinyColorPicker can be received via bower: 68 | 69 | ```javascript 70 | bower install tinyColorPicker 71 | ``` 72 | 73 | ## jqColorPicker.js 74 | 75 | ```jqColorPicker.js``` is a jQuery plugin including the UI, CSS and images and uses an instance of Colors (from ```colors.js```) for all the color calculations. It passes the options to that instance, so some values might be the same when inspecting... 76 | 77 | ```javascript 78 | $('.color').colorPicker({ 79 | color: ..., // see Colors below... 80 | customBG: '#FFF' // see Colors below... 81 | animationSpeed: 150, // toggle animation speed 82 | GPU: true, // use transform: translate3d or regular rendereing (top, left) 83 | doRender: true | 'selector', // render color and bgColor of input field (on certain elements if selector) 84 | opacity: true, // enable / disable alpha slider 85 | buildCallback: function($elm) { 86 | // 'this': colorPicker instance; // will be the same as in positionCallback() and renderCallback(); 87 | // $elm: the UI (
) 88 | }, 89 | renderCallback: function($elm, toggled) { 90 | // 'this': current colorPicker instance; // instance has all kinds of information about colorPicker such as $UI including dimensions etc... 91 | // $elm: the input field or other element that just toggled the colorPicker; 92 | // toggle -> 'true': just appeared; 'false': just closed; 'undefined': is rendering 93 | }, 94 | positionCallback: function($elm) { 95 | // 'this': current colorPicker instance; 96 | // $elm: the input field or other element that just toggled the colorPicker; 97 | // optionally... 98 | return {top: y, left: x}; // positions colorPicker before appearing 99 | }, 100 | css: '', // String: replaces existing css 101 | cssAddon: '', // String: adds css to existing 102 | margin: '', // positioning margin (can also be set in cssAddon) 103 | scrollResize: true // toggle for repositioning colorPicker on window.resize/scroll 104 | gap: 4 // gap to right and bottom edge of view port if repositioned to fit 105 | dark: '#222' // default font color if background is light 106 | light: '#DDD' // default font color if background is dark 107 | preventFocus: false // prevents default on focus of input fields (e.g. no keyboard on mobile) 108 | body: document.body // the element where the events are attached to (touchstart, mousedown, pointerdown, focus, click, change), 109 | forceAlpha: // force printing alpha channel (undefined = auto; false = never print alpha), 110 | cssPrepend: // makes add CSS being added to the beginning of the instead of to the end 111 | }); 112 | ``` 113 | See the following section or the demos on how the callbacks work and what you can do with them... 114 | 115 | #### Some tips 116 | 117 | The positionCallback can be used to optionally position the colorPicker different from its default; in case you want it to also show above or to the left of the input field etc. 118 | The callback will also be called on scroll. 119 | If you return an object (```{left: x, top: y}``` to position the colorPicker) then those coordinates will be taken, otherwhise the function just executes (what you need to do: re-append for example) and it takes the internal algorithm to position the color picker. See ./demo/index.js for an example: 120 | 121 | ```javascript 122 | positionCallback: function($elm) { 123 | var $UI = this.$UI, // this is the instance; this.$UI is the colorPicker DOMElement 124 | position = $elm.offset(), // $elm is the current trigger that opened the UI 125 | gap = this.color.options.gap, // this.color.options stores all options 126 | top = 0, 127 | left = 0; 128 | 129 | // $UI.appendTo('#somwhereElse'); 130 | // do here your calculations with top and left and then... 131 | return { // the object will be used as in $('.something').css({...}); 132 | left: left, 133 | top: top 134 | } 135 | } 136 | ``` 137 | This callback is also good if you need to append your colorPicker to a different container than document.body. This way you can then calculate the coordinates relative to the appended container... 138 | 139 | 140 | The renderCallback can be used as openCallback and closeCallback: 141 | ```javascript 142 | renderCallback: function($elm, toggled) { 143 | if (toggled === true) { // simple, lightweight check 144 | // ... like an open callback 145 | } else if (toggled === false) { 146 | // ... like a close callback 147 | } else { 148 | // rendering... 149 | } 150 | } 151 | ``` 152 | Here you can fire events if necessary or check for a className or data attribute on $elm to see if there is a hint for hiding the opacity slider: 153 | ```javascript 154 | this.$UI.find('.cp-alpha').toggle(!$elm.hasClass('no-alpha')); 155 | ``` 156 | 157 | ## colors.js 158 | 159 | This section only shows the options for color.js. They are picked up automatically if set in ```$('.color').colorPicker({/* options */});``` 160 | 161 | ```javascript 162 | Colors({ // all options have a default value... 163 | color: 'rgba(204, 82, 37, 0.8)', // initial color (#RGB, RGB, #RRGGBB, RRGGBB, rgb(r, g, b), ...) 164 | grey: {r: 0.298954, g: 0.586434, b: 0.114612}, // CIE-XYZ 1931 165 | luminance: {r: 0.2126, g: 0.7152, b: 0.0722}, // W3C 2.0 166 | valueRanges: {rgb: {r: [0, 255], g: [0, 255], b: [0, 255]}, hsv:...}, // skip ranges if no conversion required 167 | customBG: '#808080' // the solid bgColor behind the chosen bgColor (saved color) 168 | convertCallback: function(colors, type){}, // callback function after color convertion for further calculations... 169 | }); 170 | ``` 171 | 172 | ## The color model, the methods and more 173 | 174 | After initializing Color or ColorPicker you'll get a clean but rhich model of the instance: 175 | 176 | ```javascript 177 | myColors: { 178 | colors: { all kinds of color values... see later}, 179 | options: { all the options you set or that are set as default... }, 180 | __proto__: { // all methods Color uses (See https://github.com/PitPik/colorPicker for details) 181 | setColor: function(newCol, type, alpha) {}, 182 | setCustomBackground: function(col) {}, 183 | saveAsBackground: function() {}, 184 | // new method: converts current color to HTML-String like: rgba(123, 234, 0, 0.89) 185 | // forceAlpha === true / false -> alway / never print alpha, === undefined -> auto 186 | toString: function('rgb' || 'hsl' || 'hex' || '' -> 'rgb', forceAlpha) {}, 187 | } 188 | } 189 | ``` 190 | colors.js is a quite handy tool for color calculations/conversion (gray value, contrast and luminance, etc...). It can also calculate layer mixes between background and foreground colors and therefore make calculations about readability (WCAG 2.0 standard). 191 | If you need more complex calculations or more color spaces, use the version from https://github.com/PitPik/colorPicker. It supports also cmy, cmyk, XYZ and Lab. 192 | ```javascript 193 | myColorPicker: { 194 | $trigger: ... // jQuery object of active trigger or null if none active 195 | $UI: ... // jQuery object of the colorPicker HTML element 196 | color: { // instance of Color inside colorPicker 197 | colors: { all kinds of color values... see later}, 198 | options: { all the options you set or that are set as default... }, 199 | __proto__: { all methods Color uses ... see above} 200 | }, 201 | __proto__: { // all methods ColorPicker uses 202 | render: function() {}, 203 | toggle: function(openClose) {} // openClose: true = open; false = close 204 | } 205 | } 206 | ``` 207 | 208 | 209 | ## The color model 210 | 211 | ```javascript 212 | HEX: // current color as HEX (upper case, 6 digits) 213 | rgb: // current RGB color as normalized values (0 - 1) 214 | r: // red 215 | g: // green 216 | b: // blue 217 | hsv: // current color values in normalized HSV (HSB) model 218 | h: // hue 219 | s: // saturation 220 | v: // value (brightness) 221 | hsl: // current color values in normalized HSL model 222 | h: // hue 223 | s: // saturation 224 | l: // lightness 225 | RND: // all above colors in their defined ranges 226 | rgb: // current RGB color, rounded between 0 and 255 227 | r: // red (0 - 255) 228 | g: // green (0 - 255) 229 | b: // blue (0 - 255) 230 | hsv: // see above 231 | h: // hue (0 - 360 degrees) 232 | s: // saturation (0 - 100 %) 233 | v: // value (brightness) (0 - 100 %) 234 | hsl: // see above 235 | h: // hue (0 - 360 degrees) 236 | s: // saturation (0 - 100 %) 237 | l: // lightness (0 - 100 %) 238 | background: // saved (background) color (saveAsBackground(){}) 239 | rgb: // color in RGB model 240 | r: // red 241 | g: // green 242 | b: // blue 243 | RGB: // RGB color, rounded between 0 and 255 244 | r: // red (0 - 255) 245 | g: // green (0 - 255) 246 | b: // blue (0 - 255) 247 | alpha: // alpha or opacity value (0 - 1) 248 | equivalentGrey: // r = g = b = (0 - 255) 249 | rgbaMixBlack: // saved (background) color mixed with solid black color 250 | r: // red 251 | g: // green 252 | b: // blue 253 | a: // resulting alpha or opacity value (0 - 1) 254 | luminance: // luminance of resulting mix (0 - 1) 255 | rgbaMixCustom: // saved (background) color mixed with custom (solid) color 256 | r: // red 257 | g: // green 258 | b: // blue 259 | a: // resulting alpha or opacity value (0 - 1) 260 | luminance: // luminance of resulting mix (0 - 1) 261 | rgbaMixWhite: // saved (background) color mixed with solid white color 262 | r: // red 263 | g: // green 264 | b: // blue 265 | a: // resulting alpha or opacity value (0 - 1) 266 | luminance: // luminance of resulting mix (0 - 1) 267 | alpha: // alpha or opacity value (0 - 1) of current color 268 | equivalentGrey: // r = g = b = (0 - 1) 269 | HUELuminance: // luminance of hue (in full brightnes and saturation) (0 - 1) 270 | RGBLuminance: // luminance of the current color 271 | hueRGB: // rounded integer value of current color in rgb model with full saturation and brightness 272 | r: // red (0 - 255) 273 | g: // green (0 - 255) 274 | b: // blue (0 - 255) 275 | saveColor: // '' or 'web smart' or 'web save', if so. 276 | webSave: // closest web-save color 277 | r: // red (0 - 255) 278 | g: // green (0 - 255) 279 | b: // blue (0 - 255) 280 | webSmart: // closest web-smart color 281 | r: // red (0 - 255) 282 | g: // green (0 - 255) 283 | b: // blue (0 - 255) 284 | rgbaMixBG: // color mix result: current color above saved (background) color 285 | r: // red (0 - 1) 286 | g: // green (0 - 1) 287 | b: // blue (0 - 1) 288 | a: // resulting alpha or opacity value (0 - 1) 289 | luminance: // luminance of resulting mix (0 - 1) 290 | rgbaMixBGMixCustom: // color mix result: current color above saved (background) color above solid custom color 291 | r: // red (0 - 1) 292 | g: // green (0 - 1) 293 | b: // blue (0 - 1) 294 | a: // resulting alpha or opacity value (0 - 1) 295 | luminance: // luminance of resulting mix (0 - 1) 296 | luminanceDelta: // luminance difference between current color and resulting saved-custom mix (0 - 1) 297 | hueDelta: // hue difference between current color and resulting saved-custom mix (0 - 1) 298 | WCAG2Ratio: // readability vale (1 - 21, 1:1 to 21:1) 299 | rgbaMixBlack: // color mix result: current color above solid black 300 | r: // red (0 - 1) 301 | g: // green (0 - 1) 302 | b: // blue (0 - 1) 303 | a: // resulting alpha or opacity value (0 - 1) 304 | luminance: // luminance of resulting mix (0 - 1) 305 | WCAG2Ratio: // readability vale (1 - 21, 1:1 to 21:1) 306 | rgbaMixWhite: // color mix result: current color above solid white 307 | r: // red (0 - 1) 308 | g: // green (0 - 1) 309 | b: // blue (0 - 1) 310 | a: // resulting alpha or opacity value (0 - 1) 311 | luminance: // luminance of resulting mix (0 - 1) 312 | WCAG2Ratio: // readability vale (1 - 21, 1:1 to 21:1) 313 | ``` 314 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tinyColorPicker", 3 | "description": "Tiny jQuery color picker for mobile and desktop with alpha channel", 4 | "main": "jqColorPicker.min.js", 5 | "authors": [ 6 | "Peter Dematté " 7 | ], 8 | "license": "MIT", 9 | "keywords": [ 10 | "jquery", 11 | "javascript", 12 | "color", 13 | "picker", 14 | "colorpicker", 15 | "mobile", 16 | "WCAG2.0", 17 | "requestAnimationFrame" 18 | ], 19 | "homepage": "https://github.com/PitPik/tinyColorPicker", 20 | "moduleType": [ 21 | "amd", 22 | "globals", 23 | "node" 24 | ], 25 | "ignore": [ 26 | "**/.*", 27 | "node_modules", 28 | "bower_components", 29 | "test", 30 | "tests" 31 | ], 32 | "dependencies": { 33 | "jquery": ">= 1.12.0 < 3.0.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /colors.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof exports === 'object') { 3 | module.exports = factory(root); 4 | } else if (typeof define === 'function' && define.amd) { 5 | define('colors', [], function () { 6 | return factory(root); 7 | }); 8 | } else { 9 | root.Colors = factory(root); 10 | } 11 | }(this, function(window, undefined) { 12 | "use strict" 13 | 14 | var _valueRanges = { 15 | rgb: {r: [0, 255], g: [0, 255], b: [0, 255]}, 16 | hsv: {h: [0, 360], s: [0, 100], v: [0, 100]}, 17 | hsl: {h: [0, 360], s: [0, 100], l: [0, 100]}, 18 | alpha: {alpha: [0, 1]}, 19 | HEX: {HEX: [0, 16777215]} // maybe we don't need this 20 | }, 21 | 22 | _Math = window.Math, 23 | _round = _Math.round, 24 | 25 | _instance = {}, 26 | _colors = {}, 27 | 28 | grey = {r: 0.298954, g: 0.586434, b: 0.114612}, // CIE-XYZ 1931 29 | luminance = {r: 0.2126, g: 0.7152, b: 0.0722}, // W3C 2.0 30 | 31 | Colors = function(options) { 32 | this.colors = {RND: {}}; 33 | this.options = { 34 | color: 'rgba(0,0,0,0)', // init value(s)... 35 | grey: grey, 36 | luminance: luminance, 37 | valueRanges: _valueRanges 38 | // customBG: '#808080' 39 | // convertCallback: undefined, 40 | // allMixDetails: false 41 | }; 42 | initInstance(this, options || {}); 43 | }, 44 | initInstance = function(THIS, options) { 45 | var importColor, 46 | _options = THIS.options, 47 | customBG; 48 | 49 | focusInstance(THIS); 50 | for (var option in options) { 51 | if (options[option] !== undefined) _options[option] = options[option]; 52 | } 53 | customBG = _options.customBG; 54 | _options.customBG = (typeof customBG === 'string') ? ColorConverter.txt2color(customBG).rgb : customBG; 55 | _colors = setColor(THIS.colors, _options.color, undefined, true); // THIS.colors = _colors = 56 | }, 57 | focusInstance = function(THIS) { 58 | if (_instance !== THIS) { 59 | _instance = THIS; 60 | _colors = THIS.colors; 61 | } 62 | }; 63 | 64 | Colors.prototype.setColor = function(newCol, type, alpha) { 65 | focusInstance(this); 66 | if (newCol) { 67 | return setColor(this.colors, newCol, type, undefined, alpha); 68 | } else { 69 | if (alpha !== undefined) { 70 | this.colors.alpha = limitValue(alpha, 0, 1); 71 | } 72 | return convertColors(type); 73 | } 74 | }; 75 | 76 | Colors.prototype.setCustomBackground = function(col) { // wild gues,... check again... 77 | focusInstance(this); // needed??? 78 | this.options.customBG = (typeof col === 'string') ? ColorConverter.txt2color(col).rgb : col; 79 | // return setColor(this.colors, this.options.customBG, 'rgb', true); // !!!!RGB 80 | return setColor(this.colors, undefined, 'rgb'); // just recalculate existing 81 | }; 82 | 83 | Colors.prototype.saveAsBackground = function() { // alpha 84 | focusInstance(this); // needed??? 85 | // return setColor(this.colors, this.colors.RND.rgb, 'rgb', true); 86 | return setColor(this.colors, undefined, 'rgb', true); 87 | }; 88 | 89 | Colors.prototype.toString = function(colorMode, forceAlpha) { 90 | return ColorConverter.color2text((colorMode || 'rgb').toLowerCase(), this.colors, forceAlpha); 91 | }; 92 | 93 | // ------------------------------------------------------ // 94 | // ---------- Color calculation related stuff ---------- // 95 | // -------------------------------------------------------// 96 | 97 | function setColor(colors, color, type, save, alpha) { // color only full range 98 | if (typeof color === 'string') { 99 | var color = ColorConverter.txt2color(color); // new object 100 | type = color.type; 101 | _colors[type] = color[type]; 102 | alpha = alpha !== undefined ? alpha : color.alpha; 103 | } else if (color) { 104 | for (var n in color) { 105 | colors[type][n] = limitValue(color[n] / _valueRanges[type][n][1], 0 , 1); 106 | } 107 | } 108 | if (alpha !== undefined) { 109 | colors.alpha = limitValue(+alpha, 0, 1); 110 | } 111 | return convertColors(type, save ? colors : undefined); 112 | } 113 | 114 | function saveAsBackground(RGB, rgb, alpha) { 115 | var grey = _instance.options.grey, 116 | color = {}; 117 | 118 | color.RGB = {r: RGB.r, g: RGB.g, b: RGB.b}; 119 | color.rgb = {r: rgb.r, g: rgb.g, b: rgb.b}; 120 | color.alpha = alpha; 121 | // color.RGBLuminance = getLuminance(RGB); 122 | color.equivalentGrey = _round(grey.r * RGB.r + grey.g * RGB.g + grey.b * RGB.b); 123 | 124 | color.rgbaMixBlack = mixColors(rgb, {r: 0, g: 0, b: 0}, alpha, 1); 125 | color.rgbaMixWhite = mixColors(rgb, {r: 1, g: 1, b: 1}, alpha, 1); 126 | color.rgbaMixBlack.luminance = getLuminance(color.rgbaMixBlack, true); 127 | color.rgbaMixWhite.luminance = getLuminance(color.rgbaMixWhite, true); 128 | 129 | if (_instance.options.customBG) { 130 | color.rgbaMixCustom = mixColors(rgb, _instance.options.customBG, alpha, 1); 131 | color.rgbaMixCustom.luminance = getLuminance(color.rgbaMixCustom, true); 132 | _instance.options.customBG.luminance = getLuminance(_instance.options.customBG, true); 133 | } 134 | 135 | return color; 136 | } 137 | 138 | function convertColors(type, colorObj) { 139 | // console.time('convertColors'); 140 | var colors = colorObj || _colors, 141 | convert = ColorConverter, 142 | options = _instance.options, 143 | ranges = _valueRanges, 144 | RND = colors.RND, 145 | // type = colorType, // || _mode.type, 146 | modes, mode = '', from = '', // value = '', 147 | exceptions = {hsl: 'hsv', rgb: type}, 148 | RGB = RND.rgb, SAVE, SMART; 149 | 150 | if (type !== 'alpha') { 151 | for (var typ in ranges) { 152 | if (!ranges[typ][typ]) { // no alpha|HEX 153 | if (type !== typ) { 154 | from = exceptions[typ] || 'rgb'; 155 | colors[typ] = convert[from + '2' + typ](colors[from]); 156 | } 157 | 158 | if (!RND[typ]) RND[typ] = {}; 159 | modes = colors[typ]; 160 | for(mode in modes) { 161 | RND[typ][mode] = _round(modes[mode] * ranges[typ][mode][1]); 162 | } 163 | } 164 | } 165 | 166 | RGB = RND.rgb; 167 | colors.HEX = convert.RGB2HEX(RGB); 168 | colors.equivalentGrey = 169 | options.grey.r * colors.rgb.r + 170 | options.grey.g * colors.rgb.g + 171 | options.grey.b * colors.rgb.b; 172 | colors.webSave = SAVE = getClosestWebColor(RGB, 51); 173 | // colors.webSave.HEX = convert.RGB2HEX(colors.webSave); 174 | colors.webSmart = SMART = getClosestWebColor(RGB, 17); 175 | // colors.webSmart.HEX = convert.RGB2HEX(colors.webSmart); 176 | colors.saveColor = 177 | RGB.r === SAVE.r && RGB.g === SAVE.g && RGB.b === SAVE.b ? 'web save' : 178 | RGB.r === SMART.r && RGB.g === SMART.g && RGB.b === SMART.b ? 'web smart' : ''; 179 | colors.hueRGB = ColorConverter.hue2RGB(colors.hsv.h); 180 | 181 | if (colorObj) { 182 | colors.background = saveAsBackground(RGB, colors.rgb, colors.alpha); 183 | } 184 | } // else RGB = RND.rgb; 185 | 186 | var rgb = colors.rgb, // for better minification... 187 | alpha = colors.alpha, 188 | luminance = 'luminance', 189 | background = colors.background, 190 | rgbaMixBlack, rgbaMixWhite, rgbaMixCustom, 191 | rgbaMixBG, rgbaMixBGMixBlack, rgbaMixBGMixWhite, rgbaMixBGMixCustom; 192 | 193 | rgbaMixBlack = mixColors(rgb, {r: 0, g: 0, b: 0}, alpha, 1); 194 | rgbaMixBlack[luminance] = getLuminance(rgbaMixBlack, true); 195 | colors.rgbaMixBlack = rgbaMixBlack; 196 | 197 | rgbaMixWhite = mixColors(rgb, {r: 1, g: 1, b: 1}, alpha, 1); 198 | rgbaMixWhite[luminance] = getLuminance(rgbaMixWhite, true); 199 | colors.rgbaMixWhite = rgbaMixWhite; 200 | 201 | if (options.customBG) { 202 | rgbaMixBGMixCustom = mixColors(rgb, background.rgbaMixCustom, alpha, 1); 203 | rgbaMixBGMixCustom[luminance] = getLuminance(rgbaMixBGMixCustom, true); 204 | rgbaMixBGMixCustom.WCAG2Ratio = getWCAG2Ratio(rgbaMixBGMixCustom[luminance], 205 | background.rgbaMixCustom[luminance]); 206 | colors.rgbaMixBGMixCustom = rgbaMixBGMixCustom; 207 | /* ------ */ 208 | rgbaMixBGMixCustom.luminanceDelta = _Math.abs( 209 | rgbaMixBGMixCustom[luminance] - background.rgbaMixCustom[luminance]); 210 | rgbaMixBGMixCustom.hueDelta = getHueDelta(background.rgbaMixCustom, rgbaMixBGMixCustom, true); 211 | /* ------ */ 212 | } 213 | 214 | colors.RGBLuminance = getLuminance(RGB); 215 | colors.HUELuminance = getLuminance(colors.hueRGB); 216 | 217 | // renderVars.readyToRender = true; 218 | if (options.convertCallback) { 219 | options.convertCallback(colors, type); //, convert); //, _mode); 220 | } 221 | 222 | // console.timeEnd('convertColors') 223 | // if (colorObj) 224 | return colors; 225 | } 226 | 227 | 228 | // ------------------------------------------------------ // 229 | // ------------------ color conversion ------------------ // 230 | // -------------------------------------------------------// 231 | 232 | var ColorConverter = { 233 | txt2color: function(txt) { 234 | var color = {}, 235 | parts = txt.replace(/(?:#|\)|%)/g, '').split('('), 236 | values = (parts[1] || '').split(/,\s*/), 237 | type = parts[1] ? parts[0].substr(0, 3) : 'rgb', 238 | m = ''; 239 | 240 | color.type = type; 241 | color[type] = {}; 242 | if (parts[1]) { 243 | for (var n = 3; n--; ) { 244 | m = type[n] || type.charAt(n); // IE7 245 | color[type][m] = +values[n] / _valueRanges[type][m][1]; 246 | } 247 | } else { 248 | color.rgb = ColorConverter.HEX2rgb(parts[0]); 249 | } 250 | // color.color = color[type]; 251 | color.alpha = values[3] ? +values[3] : 1; 252 | 253 | return color; 254 | }, 255 | 256 | color2text: function(colorMode, colors, forceAlpha) { 257 | var alpha = forceAlpha !== false && _round(colors.alpha * 100) / 100, 258 | hasAlpha = typeof alpha === 'number' && 259 | forceAlpha !== false && (forceAlpha || alpha !== 1), 260 | RGB = colors.RND.rgb, 261 | HSL = colors.RND.hsl, 262 | shouldBeHex = colorMode === 'hex' && hasAlpha, 263 | isHex = colorMode === 'hex' && !shouldBeHex, 264 | isRgb = colorMode === 'rgb' || shouldBeHex, 265 | innerText = isRgb ? RGB.r + ', ' + RGB.g + ', ' + RGB.b : 266 | !isHex ? HSL.h + ', ' + HSL.s + '%, ' + HSL.l + '%' : 267 | '#' + colors.HEX; 268 | 269 | return isHex ? innerText : (shouldBeHex ? 'rgb' : colorMode) + 270 | (hasAlpha ? 'a' : '') + '(' + innerText + 271 | (hasAlpha ? ', ' + alpha : '') + ')'; 272 | }, 273 | 274 | RGB2HEX: function(RGB) { 275 | return ( 276 | (RGB.r < 16 ? '0' : '') + RGB.r.toString(16) + 277 | (RGB.g < 16 ? '0' : '') + RGB.g.toString(16) + 278 | (RGB.b < 16 ? '0' : '') + RGB.b.toString(16) 279 | ).toUpperCase(); 280 | }, 281 | 282 | HEX2rgb: function(HEX) { 283 | HEX = HEX.split(''); // IE7 284 | return { 285 | r: +('0x' + HEX[0] + HEX[HEX[3] ? 1 : 0]) / 255, 286 | g: +('0x' + HEX[HEX[3] ? 2 : 1] + (HEX[3] || HEX[1])) / 255, 287 | b: +('0x' + (HEX[4] || HEX[2]) + (HEX[5] || HEX[2])) / 255 288 | }; 289 | }, 290 | 291 | hue2RGB: function(hue) { 292 | var h = hue * 6, 293 | mod = ~~h % 6, // _Math.floor(h) -> faster in most browsers 294 | i = h === 6 ? 0 : (h - mod); 295 | 296 | return { 297 | r: _round([1, 1 - i, 0, 0, i, 1][mod] * 255), 298 | g: _round([i, 1, 1, 1 - i, 0, 0][mod] * 255), 299 | b: _round([0, 0, i, 1, 1, 1 - i][mod] * 255) 300 | }; 301 | }, 302 | 303 | // ------------------------ HSV ------------------------ // 304 | 305 | rgb2hsv: function(rgb) { // faster 306 | var r = rgb.r, 307 | g = rgb.g, 308 | b = rgb.b, 309 | k = 0, chroma, min, s; 310 | 311 | if (g < b) { 312 | g = b + (b = g, 0); 313 | k = -1; 314 | } 315 | min = b; 316 | if (r < g) { 317 | r = g + (g = r, 0); 318 | k = -2 / 6 - k; 319 | min = _Math.min(g, b); // g < b ? g : b; ??? 320 | } 321 | chroma = r - min; 322 | s = r ? (chroma / r) : 0; 323 | return { 324 | h: s < 1e-15 ? ((_colors && _colors.hsl && _colors.hsl.h) || 0) : 325 | chroma ? _Math.abs(k + (g - b) / (6 * chroma)) : 0, 326 | s: r ? (chroma / r) : ((_colors && _colors.hsv && _colors.hsv.s) || 0), // ??_colors.hsv.s || 0 327 | v: r 328 | }; 329 | }, 330 | 331 | hsv2rgb: function(hsv) { 332 | var h = hsv.h * 6, 333 | s = hsv.s, 334 | v = hsv.v, 335 | i = ~~h, // _Math.floor(h) -> faster in most browsers 336 | f = h - i, 337 | p = v * (1 - s), 338 | q = v * (1 - f * s), 339 | t = v * (1 - (1 - f) * s), 340 | mod = i % 6; 341 | 342 | return { 343 | r: [v, q, p, p, t, v][mod], 344 | g: [t, v, v, q, p, p][mod], 345 | b: [p, p, t, v, v, q][mod] 346 | }; 347 | }, 348 | 349 | // ------------------------ HSL ------------------------ // 350 | 351 | hsv2hsl: function(hsv) { 352 | var l = (2 - hsv.s) * hsv.v, 353 | s = hsv.s * hsv.v; 354 | 355 | s = !hsv.s ? 0 : l < 1 ? (l ? s / l : 0) : s / (2 - l); 356 | 357 | return { 358 | h: hsv.h, 359 | s: !hsv.v && !s ? ((_colors && _colors.hsl && _colors.hsl.s) || 0) : s, // ??? 360 | l: l / 2 361 | }; 362 | }, 363 | 364 | rgb2hsl: function(rgb, dependent) { // not used in Color 365 | var hsv = ColorConverter.rgb2hsv(rgb); 366 | 367 | return ColorConverter.hsv2hsl(dependent ? hsv : (_colors.hsv = hsv)); 368 | }, 369 | 370 | hsl2rgb: function(hsl) { 371 | var h = hsl.h * 6, 372 | s = hsl.s, 373 | l = hsl.l, 374 | v = l < 0.5 ? l * (1 + s) : (l + s) - (s * l), 375 | m = l + l - v, 376 | sv = v ? ((v - m) / v) : 0, 377 | sextant = ~~h, // _Math.floor(h) -> faster in most browsers 378 | fract = h - sextant, 379 | vsf = v * sv * fract, 380 | t = m + vsf, 381 | q = v - vsf, 382 | mod = sextant % 6; 383 | 384 | return { 385 | r: [v, q, m, m, t, v][mod], 386 | g: [t, v, v, q, m, m][mod], 387 | b: [m, m, t, v, v, q][mod] 388 | }; 389 | } 390 | }; 391 | 392 | // ------------------------------------------------------ // 393 | // ------------------ helper functions ------------------ // 394 | // -------------------------------------------------------// 395 | 396 | function getClosestWebColor(RGB, val) { 397 | var out = {}, 398 | tmp = 0, 399 | half = val / 2; 400 | 401 | for (var n in RGB) { 402 | tmp = RGB[n] % val; // 51 = 'web save', 17 = 'web smart' 403 | out[n] = RGB[n] + (tmp > half ? val - tmp : -tmp); 404 | } 405 | return out; 406 | } 407 | 408 | function getHueDelta(rgb1, rgb2, nominal) { 409 | return (_Math.max(rgb1.r - rgb2.r, rgb2.r - rgb1.r) + 410 | _Math.max(rgb1.g - rgb2.g, rgb2.g - rgb1.g) + 411 | _Math.max(rgb1.b - rgb2.b, rgb2.b - rgb1.b)) * (nominal ? 255 : 1) / 765; 412 | } 413 | 414 | function getLuminance(rgb, normalized) { 415 | var div = normalized ? 1 : 255, 416 | RGB = [rgb.r / div, rgb.g / div, rgb.b / div], 417 | luminance = _instance.options.luminance; 418 | 419 | for (var i = RGB.length; i--; ) { 420 | RGB[i] = RGB[i] <= 0.03928 ? RGB[i] / 12.92 : _Math.pow(((RGB[i] + 0.055) / 1.055), 2.4); 421 | } 422 | return ((luminance.r * RGB[0]) + (luminance.g * RGB[1]) + (luminance.b * RGB[2])); 423 | } 424 | 425 | function mixColors(topColor, bottomColor, topAlpha, bottomAlpha) { 426 | var newColor = {}, 427 | alphaTop = (topAlpha !== undefined ? topAlpha : 1), 428 | alphaBottom = (bottomAlpha !== undefined ? bottomAlpha : 1), 429 | alpha = alphaTop + alphaBottom * (1 - alphaTop); // 1 - (1 - alphaTop) * (1 - alphaBottom); 430 | 431 | for(var n in topColor) { 432 | newColor[n] = (topColor[n] * alphaTop + bottomColor[n] * alphaBottom * (1 - alphaTop)) / alpha; 433 | } 434 | newColor.a = alpha; 435 | return newColor; 436 | } 437 | 438 | function getWCAG2Ratio(lum1, lum2) { 439 | var ratio = 1; 440 | 441 | if (lum1 >= lum2) { 442 | ratio = (lum1 + 0.05) / (lum2 + 0.05); 443 | } else { 444 | ratio = (lum2 + 0.05) / (lum1 + 0.05); 445 | } 446 | return _round(ratio * 100) / 100; 447 | } 448 | 449 | function limitValue(value, min, max) { 450 | // return _Math.max(min, _Math.min(max, value)); // faster?? 451 | return (value > max ? max : value < min ? min : value); 452 | } 453 | 454 | return Colors; 455 | })); -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | tiny jQuery color picker demo 20 | 21 | 22 |
23 |

Tiny jQuery colorPicker

24 |

This is a demo that describes tinyColorPicker custumization 'Skinned dev-tools like with RGB sliders' in a more understandable way.

25 | 26 |

Skinned dev-tools like, with RGB sliders

27 |
28 | 29 | 30 | 31 |
32 |
33 |
34 |
35 |
36 |
37 | 38 | Fork me on GitHub 39 |
40 | 41 | -------------------------------------------------------------------------------- /demo/index.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | 'use strict'; 3 | 4 | var options = { 5 | customBG: '#222', // bg of page is dark, so if opcity close to 0 -> dark shines through 6 | doRender: 'div div', // tell it where to render bg-color if no input 7 | colorNames: { // get more colors in the other demo... will be displayed next to color patch 8 | '808080': 'grey', 9 | '00FFFF': 'cyan', 10 | '000000': 'black', 11 | '0000FF': 'blue', 12 | 'FF00FF': 'magenta', 13 | '008000': 'green', 14 | 'FF0000': 'red', 15 | 'C0C0C0': 'silver', 16 | 'FFFFFF': 'white', 17 | 'FFFF00': 'yellow' 18 | }, 19 | buildCallback: function($elm) { // called the first time colorPicker gets triggered 20 | var that = this; // for callback function 21 | var currentRGB = ''; // either r, g or b 22 | var $currentSlider = $(); // the clicked rgb slider 23 | var currentOffset = {}; // of slider 24 | var $window = $(window); 25 | var mouseMove = function(e) { // don't render sliders here. Just setColor; 26 | var color = {}; // new calculated color 27 | 28 | color[currentRGB] = (e.pageX - currentOffset.left) / that.currentWidth * 255; 29 | that.color.setColor(color, 'rgb'); // set calculated value 30 | that.render(); // tell colorPicker to render 31 | }; 32 | 33 | $elm.append( // render extra sliders and patch 34 | '
' + 35 | '
' + 36 | '
' + 37 | '
'); 38 | 39 | this.$sliders = $elm.find('.cp-rgb-r, .cp-rgb-g, .cp-rgb-b'); 40 | this.cursorRStyle = this.$sliders.find('.cp-rgb-r-cursor')[0].style; // caching for faster render renderCallback 41 | this.cursorGStyle = this.$sliders.find('.cp-rgb-g-cursor')[0].style; 42 | this.cursorBStyle = this.$sliders.find('.cp-rgb-b-cursor')[0].style; 43 | 44 | this.patchStyle = $('.cp-patch div')[0].style; 45 | this.$display = $('.cp-disp'); 46 | this.$alpha = $elm.find('.cp-alpha'); 47 | 48 | $elm.on('mousedown', '.cp-rgb-r, .cp-rgb-g, .cp-rgb-b', function(e) { // event delegation 49 | $currentSlider = $(this); // well ;o) 50 | currentRGB = this.className.replace(/cp-rgb-(\D){1}/, "$1"); // cp-rgb-r -> r 51 | currentOffset = $currentSlider.offset(); // for later calculations 52 | that.currentWidth = $currentSlider.width(); // ... also here 53 | $window.on('mousemove.rgb', mouseMove); // install mousemove listener 54 | e.preventDefault && e.preventDefault(); // prevent selecting text 55 | mouseMove(e); // render color picker the first time 56 | return false; // for IE 57 | }); 58 | 59 | $window.on('mouseup', function(e) { 60 | $window.off('mousemove.rgb'); // turn off mousemove event handler 61 | }); 62 | 63 | // append css after just generated / use cssAddon instead if you want 64 | $('#colorPickerMod').appendTo('head'); 65 | }, 66 | positionCallback: function($elm) { // optional function to position colorPicker on toggle 67 | var _$UI = this.$UI, // this is the instance; this.$UI is the colorPicker DOMElement 68 | position = $elm.offset(), // $elm is the current trigger / element that opened the colorPicker 69 | $window = $(window), 70 | gap = this.color.options.gap; // this.color.options stores all options 71 | 72 | // _$UI.appendTo($elm.closest('.wrapper').eq(0)); // demonstration only 73 | 74 | return { // this demo is a copy of the internal usage (to show how it works); 75 | 'left': (_$UI._left = position.left) - 76 | ((_$UI._left += _$UI._width - 77 | ($window.scrollLeft() + $window.width())) + gap > 0 ? 78 | _$UI._left + gap : 0), 79 | 'top': (_$UI._top = position.top + $elm.outerHeight()) - 80 | ((_$UI._top += _$UI._height - 81 | ($window.scrollTop() + $window.height())) + gap > 0 ? 82 | _$UI._top + gap : 0) 83 | } 84 | }, 85 | renderCallback: function($elm, toggled) { 86 | var colors = this.color.colors; // the whole color object 87 | var rgb = colors.RND.rgb; // the RGB color in 0-255 88 | var oldValue = ''; 89 | var currentValue = ''; 90 | 91 | // the following 6 lines are not necessary if you don't have the trigger icons with the arrows... 92 | // if (toggled === true) { // just showing (only on show) 93 | // $('.trigger').removeClass('active'); // turns arrow of color triggers 94 | // $elm.closest('.trigger').addClass('active'); 95 | // } else if (toggled === false) { // just hiding (only on hide) 96 | // $elm.closest('.trigger').removeClass('active'); 97 | // } 98 | 99 | // demonstrates not showing numbers in input field (part 1) 100 | // if (toggled === false) { 101 | // $elm.css({'color': 'transparent'}); 102 | // } 103 | 104 | // following section (13 lines) show how to get values on every switch to an other 105 | // input field and on close... 106 | /* 107 | if (toggled === true) { // this happens on open (first time or when switching to another one) 108 | if (this.$oldElement && this.$oldElement[0] !== $elm[0]) { // previously closed while opening this one 109 | currentValue = this.color.toString(); // store current value 110 | oldValue = this.$oldElement.val(); // actual value of previous element 111 | oldValue = this.color.setColor(oldValue); // set color to that old value 112 | console.log(this.color.toString()); // show color of previously opened in rgba mode 113 | this.color.setColor(currentValue); // set it back to normal 114 | } 115 | this.$oldElement = $elm; // store for next switch... 116 | } else if (toggled === false) { // this happens on close (only) 117 | console.log(this.color.toString()); // show color model of just closed 118 | this.$oldElement = null; // delete $oldElement as there is no other swich possible 119 | } 120 | */ 121 | if (toggled === true) { // on show colorPicker 122 | this.$alpha.toggle(!$elm.hasClass('no-alpha')); 123 | this.$sliders.toggle(!$elm.hasClass('no-sliders')); 124 | 125 | // demonstrates not showing numbers in input field (part 2) 126 | // $(this.$oldElm).css({'color': 'transparent'}); 127 | // this.$oldElm = $elm; 128 | // $elm.css({'color': colors.RGBLuminance > 0.22 ? '#222' : '#ddd'}); 129 | } 130 | 131 | // this.patchStyle.backgroundColor = $elm[0].style.backgroundColor; // set patch color... 132 | this.patchStyle.backgroundColor = this.color.toString(); // no DOM access 133 | this.$display.text(this.color.options.colorNames[colors.HEX] || $elm.val()); // ...and text aside 134 | 135 | this.currentWidth = this.currentWidth || this.$UI.find('.cp-rgb-r')[0].clientWidth; // first time 136 | this.cursorRStyle.left = (rgb.r / 255 * this.currentWidth) + 'px'; // render sliders 137 | this.cursorGStyle.left = (rgb.g / 255 * this.currentWidth) + 'px'; // faster than with $().css 138 | this.cursorBStyle.left = (rgb.b / 255 * this.currentWidth) + 'px'; 139 | } 140 | }; 141 | 142 | window.myColorPicker = 143 | $('.color').colorPicker(options) 144 | // .css({'color': 'transparent'}); // demonstrates not showing numbers in input field (part 3) 145 | $('.trigger').colorPicker(options); 146 | }); -------------------------------------------------------------------------------- /demo/mod.css: -------------------------------------------------------------------------------- 1 | .cp-color-picker { 2 | border: 1px solid #999; 3 | padding: 8px; 4 | box-shadow: 5px 5px 16px rgba(0,0,0,0.4); 5 | background: #eee; 6 | overflow: visible; 7 | border-radius: 3px; 8 | margin: 5px 0 0; 9 | } 10 | 11 | #content-wrapper { 12 | /* position: relative; */ 13 | } 14 | 15 | .cp-color-picker:after, 16 | .cp-color-picker:before { 17 | content: ""; 18 | display: block; 19 | position: absolute; 20 | top: -8px; 21 | left: 8px; 22 | border: 8px solid #eee; 23 | border-width: 0px 8px 8px; 24 | border-color: transparent transparent #eee; 25 | } 26 | 27 | .cp-color-picker:before { 28 | top: -9px; 29 | border-color: transparent transparent #999; 30 | } 31 | 32 | .cp-xy-slider { 33 | border: 1px solid #aaa; 34 | margin-bottom: 10px; 35 | width: 150px; 36 | height: 150px; 37 | } 38 | .cp-xy-slider:active { 39 | cursor: none; 40 | } 41 | 42 | .cp-xy-cursor{ 43 | width: 12px; 44 | height: 12px; 45 | margin: -6px; 46 | } 47 | 48 | .cp-z-slider { 49 | margin-left: 8px; 50 | border: 1px solid #aaa; 51 | height: 150px; 52 | width: 24px; 53 | } 54 | 55 | .cp-z-cursor{ 56 | border-width: 5px; 57 | margin-top: -5px; 58 | } 59 | 60 | .cp-color-picker .cp-alpha, 61 | .cp-color-picker .cp-rgb-r, 62 | .cp-color-picker .cp-rgb-g, 63 | .cp-color-picker .cp-rgb-b { 64 | clear: both; 65 | overflow: visible; 66 | width: 152px; 67 | margin: 12px 0 0; 68 | height: 6px; 69 | border-radius: 6px; 70 | overflow: visible; 71 | border: 1px solid #aaa; 72 | box-sizing: border-box; 73 | background-image: linear-gradient(to right, rgba(238,238,238,1) 0%, rgba(238,238,238,0) 100%); 74 | } 75 | 76 | .cp-alpha-cursor, 77 | .cp-rgb-r-cursor, 78 | .cp-rgb-g-cursor, 79 | .cp-rgb-b-cursor{ 80 | box-sizing: border-box; 81 | position: absolute; 82 | background: #eee; 83 | border-radius: 100%; 84 | width: 14px; 85 | height: 14px; 86 | margin: -5px -7px; 87 | border: 1px solid #999!important; 88 | box-shadow: inset -2px -4px 3px #ccc; 89 | } 90 | 91 | .cp-alpha:after, 92 | .cp-rgb-r:after, 93 | .cp-rgb-g:after, 94 | .cp-rgb-b:after { 95 | position: relative; 96 | content: "α"; 97 | color: #666; 98 | font-size: 16px; 99 | font-family: monospace; 100 | position: absolute; 101 | right: -26px; 102 | top: -8px 103 | } 104 | 105 | .cp-rgb-r:after { 106 | content: "R"; 107 | } 108 | .cp-rgb-g:after { 109 | content: "G"; 110 | } 111 | .cp-rgb-b:after { 112 | content: "B"; 113 | } 114 | 115 | div.cp-rgb-r { 116 | background-color: red; 117 | } 118 | div.cp-rgb-g { 119 | background-color: green; 120 | } 121 | div.cp-rgb-b { 122 | background-color: blue; 123 | } 124 | 125 | .cp-patch { 126 | float: left; 127 | margin: 9px 0 0; 128 | height: 24px; 129 | width: 24px; 130 | border: 1px solid #aaa; 131 | background-image: url('data:image/gif;base64,R0lGODlhDAAMAIABAMzMzP///yH5BAEAAAEALAAAAAAMAAwAAAIWhB+ph5ps3IMyQFBvzVRq3zmfGC5QAQA7'); 132 | } 133 | 134 | .cp-patch div { 135 | height: 24px; 136 | width: 24px; 137 | } 138 | 139 | .cp-disp { 140 | padding: 4px 0 4px 4px; 141 | margin-top: 10px; 142 | font-size: 12px; 143 | height: 16px; 144 | line-height: 16px; 145 | color: #333; 146 | } -------------------------------------------------------------------------------- /development/bg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PitPik/tinyColorPicker/999178d0891e59646a6eafab50031edc8076f9b4/development/bg.gif -------------------------------------------------------------------------------- /development/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PitPik/tinyColorPicker/999178d0891e59646a6eafab50031edc8076f9b4/development/bg.png -------------------------------------------------------------------------------- /development/colorPicker.css: -------------------------------------------------------------------------------- 1 | .cp-color-picker { 2 | position: absolute; 3 | padding: 6px 6px 0; 4 | background-color: #444; 5 | color: #bbb; 6 | font: 600 12px Arial,Helvetica,sans-serif; 7 | cursor: default; 8 | border-radius: 5px; 9 | } 10 | .cp-color-picker div { 11 | box-sizing: border-box; 12 | } 13 | .cp-color-picker>div { 14 | position: relative; 15 | overflow: hidden; 16 | } 17 | .cp-xy-slider { 18 | float: left; 19 | height: 128px; 20 | width: 128px; 21 | margin-bottom: 6px; 22 | background: linear-gradient(to right,#FFF,rgba(255,255,255,0)); 23 | } 24 | .cp-white { 25 | height: 100%; 26 | width: 100%; 27 | background: linear-gradient(rgba(0,0,0,0),#000); 28 | } 29 | .cp-xy-cursor { 30 | position: absolute; 31 | top: 0; 32 | width: 10px; 33 | height: 10px; 34 | margin: -5px; 35 | border: 1px solid #fff; 36 | border-radius: 100%; 37 | } 38 | .cp-z-slider { 39 | float: right; 40 | margin-left: 6px; 41 | height: 128px; 42 | width: 22px; 43 | background: linear-gradient(red 0,#f0f 17%,#00f 33%,#0ff 50%,#0f0 67%,#ff0 83%,red 100%); 44 | } 45 | .cp-z-cursor { 46 | position: absolute; 47 | margin-top: -4px; 48 | width: 100%; 49 | border: 4px solid #fff; 50 | border-color: transparent #fff; 51 | } 52 | .cp-alpha { 53 | clear: both; 54 | width: 100%; 55 | height: 18px; 56 | margin: 6px 0; 57 | background: #666 url('data:image/gif;base64,R0lGODlhDAAMAIABAMzMzP///yH5BAEAAAEALAAAAAAMAAwAAAIWhB+ph5ps3IMyQFBvzVRq3zmfGC5QAQA7'); 58 | } 59 | .cp-alpha-alpha { 60 | height: 100%; 61 | background: linear-gradient(to left,#f00,rgba(0,0,0,0)); 62 | } 63 | .cp-alpha-cursor { 64 | position: absolute; 65 | top: 0; 66 | margin-left: -4px; 67 | height: 100%; 68 | border: 4px solid #fff; 69 | border-color: #fff transparent; 70 | } 71 | -------------------------------------------------------------------------------- /development/colors-amd-wrapper.js: -------------------------------------------------------------------------------- 1 | (function (factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define([], function () { 4 | return factory(window); 5 | }); 6 | } else { 7 | window.Colors = factory(window); 8 | } 9 | }( 10 | // paste colors.js without self invoking part: 11 | // beginning: drop 'window.Colors = (' 12 | // end: drop ')(window);' 13 | )); -------------------------------------------------------------------------------- /development/compatibility.css: -------------------------------------------------------------------------------- 1 | .cp-xy-slider { 2 | /* IE9 SVG, needs conditional override of 'filter' to 'none' */ 3 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 4 | background: -moz-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); /* FF3.6+ */ 5 | background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(255,255,255,1)), color-stop(100%,rgba(255,255,255,0))); /* Chrome,Safari4+ */ 6 | background: -webkit-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* Chrome10+,Safari5.1+ */ 7 | background: -o-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* Opera 11.10+ */ 8 | background: -ms-linear-gradient(left, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* IE10+ */ 9 | background: linear-gradient(to right, rgba(255,255,255,1) 0%,rgba(255,255,255,0) 100%); /* W3C */ 10 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#00ffffff',GradientType=1 ); /* IE6-8 */ 11 | } 12 | 13 | .cp-white { 14 | /* IE9 SVG, needs conditional override of 'filter' to 'none' */ 15 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIwIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 16 | background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 100%); /* FF3.6+ */ 17 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,1))); /* Chrome,Safari4+ */ 18 | background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* Chrome10+,Safari5.1+ */ 19 | background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* Opera 11.10+ */ 20 | background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* IE10+ */ 21 | background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,1) 100%); /* W3C */ 22 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#000000',GradientType=0 ); /* IE6-8 */ 23 | } 24 | .cp-z-slider { 25 | background: url(rainbow.png); /* Old browsers */ 26 | /* IE9 SVG, needs conditional override of 'filter' to 'none' */ 27 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZmMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjE3JSIgc3RvcC1jb2xvcj0iI2ZmMDBmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjMzJSIgc3RvcC1jb2xvcj0iIzAwMDBmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzAwZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjY3JSIgc3RvcC1jb2xvcj0iIzAwZmYwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjgzJSIgc3RvcC1jb2xvcj0iI2ZmZmYwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZjAwMDAiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 28 | background: -moz-linear-gradient(top, rgba(255,0,0,1) 0%, rgba(255,0,255,1) 17%, rgba(0,0,255,1) 33%, rgba(0,255,255,1) 50%, rgba(0,255,0,1) 67%, rgba(255,255,0,1) 83%, rgba(255,0,0,1) 100%); /* FF3.6+ */ 29 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,0,0,1)), color-stop(17%,rgba(255,0,255,1)), color-stop(33%,rgba(0,0,255,1)), color-stop(50%,rgba(0,255,255,1)), color-stop(67%,rgba(0,255,0,1)), color-stop(83%,rgba(255,255,0,1)), color-stop(100%,rgba(255,0,0,1))); /* Chrome,Safari4+ */ 30 | background: -webkit-linear-gradient(top, rgba(255,0,0,1) 0%,rgba(255,0,255,1) 17%,rgba(0,0,255,1) 33%,rgba(0,255,255,1) 50%,rgba(0,255,0,1) 67%,rgba(255,255,0,1) 83%,rgba(255,0,0,1) 100%); /* Chrome10+,Safari5.1+ */ 31 | background: -o-linear-gradient(top, rgba(255,0,0,1) 0%,rgba(255,0,255,1) 17%,rgba(0,0,255,1) 33%,rgba(0,255,255,1) 50%,rgba(0,255,0,1) 67%,rgba(255,255,0,1) 83%,rgba(255,0,0,1) 100%); /* Opera 11.10+ */ 32 | background: -ms-linear-gradient(top, rgba(255,0,0,1) 0%,rgba(255,0,255,1) 17%,rgba(0,0,255,1) 33%,rgba(0,255,255,1) 50%,rgba(0,255,0,1) 67%,rgba(255,255,0,1) 83%,rgba(255,0,0,1) 100%); /* IE10+ */ 33 | background: linear-gradient(to bottom, rgba(255,0,0,1) 0%,rgba(255,0,255,1) 17%,rgba(0,0,255,1) 33%,rgba(0,255,255,1) 50%,rgba(0,255,0,1) 67%,rgba(255,255,0,1) 83%,rgba(255,0,0,1) 100%); /* W3C */ 34 | } 35 | .cp-alpha { 36 | /* IE9 SVG, needs conditional override of 'filter' to 'none' */ 37 | background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzQ0NDQ0NCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMCIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); 38 | background: -moz-linear-gradient(left, rgba(68,68,68,1) 0%, rgba(0,0,0,0) 100%); /* FF3.6+ */ 39 | background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(68,68,68,1)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */ 40 | background: -webkit-linear-gradient(left, rgba(68,68,68,1) 0%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */ 41 | background: -o-linear-gradient(left, rgba(68,68,68,1) 0%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */ 42 | background: -ms-linear-gradient(left, rgba(68,68,68,1) 0%,rgba(0,0,0,0) 100%); /* IE10+ */ 43 | background: linear-gradient(to right, rgba(68,68,68,1) 0%,rgba(0,0,0,0) 100%); /* W3C */ 44 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#00000000',GradientType=1 ); /* IE6-8 */ 45 | } 46 | -------------------------------------------------------------------------------- /development/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PitPik/tinyColorPicker/999178d0891e59646a6eafab50031edc8076f9b4/development/favicon.ico -------------------------------------------------------------------------------- /development/fmog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PitPik/tinyColorPicker/999178d0891e59646a6eafab50031edc8076f9b4/development/fmog.png -------------------------------------------------------------------------------- /development/jqColorPicker-amd-wrapper.js: -------------------------------------------------------------------------------- 1 | (function (factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define(['jquery', 'colors'], function (jQuery, Colors) { 4 | return factory(window, jQuery, Colors); 5 | }); 6 | } else { 7 | factory(window, jQuery, Colors); 8 | } 9 | }( 10 | // jqColorPicker without self invoking part: 11 | // beginning: drop first '(' 12 | // end: drop ')(window, jQuery, Colors);' 13 | )); -------------------------------------------------------------------------------- /development/qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PitPik/tinyColorPicker/999178d0891e59646a6eafab50031edc8076f9b4/development/qr.png -------------------------------------------------------------------------------- /development/screen-shot-all.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PitPik/tinyColorPicker/999178d0891e59646a6eafab50031edc8076f9b4/development/screen-shot-all.jpg -------------------------------------------------------------------------------- /development/ui.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | UI dev 9 | 10 | 11 |

Tiny jQuery colorPicker UI

12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 | -------------------------------------------------------------------------------- /index.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | height: 100%; 3 | } 4 | body { 5 | color: #ccc; 6 | padding: .5em 1em; 7 | margin: 0; 8 | font: normal normal normal 1em/1.35em Georgia, "Times New Roman", Times, serif; 9 | background: url(data:image/jpg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/2wBDAAQDAwMDAwQDAwQGBAMEBgcFBAQFBwgGBgcGBggKCAkJCQkICgoMDAwMDAoMDA0NDAwRERERERQUFBQUFBQUFBT/2wBDAQQFBQgHCA8KCg8UDg4OFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wgARCADlAOUDAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAQACB//EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAeSAaAQI0ACAgQgRAJEREJAICRAIgREBAaAiASASECNGQESAiISIgIiIgISIQAjQEQiQEZEgEQIQASIQIhAiARAgEhAjREQgZIiEhAgASA0BGjJCRk0BEIEBCAgJoyAkREQgQgQgJkQEBEiIgAhISASEgICITJoBMEaITJoyJEREBoBAiIiEDRkgISASIiIhASEDIkJAQCIEQgAkIEAkAiJGRASAiIiIBIhAQAQIhIhMiBoiICIiEgECEAEiA0AEQgaABIiASIRMkREQmRIgEiAQESIAEiI0ZIiEDQAREQGgNGRAiECIQNGCISETJEICAgJEQmRAiNGSASITIkICZEiISIiASAiIRAgA0JkiEAIQEBASEyJEREAgaMmgNABEREREQgICAgRERAaAhAgISIiAhIQIjRkgISECISIjIkREREJEBGjIgQkBEQCIARoCIiASIiEyIkJkiIgEiIiIiAiNEREIERAAkICAgAkRCBEREQkBCACRCBEQCREAkJkSEBIyJEREAiQAREIgQgAiREBCZESMiICACREaAgIDRCAmSASIiIiIBIiAhECIgEiASEgIjRAACRoAIRMEJERCBEREBs//xAAeEAAABgMBAQAAAAAAAAAAAAABESAhMEEAEEBQYP/aAAgBAQABBQJZSVOGiwseAp2XZ8x6FF+EeGo4346bG8EkhyVKWwhZQzBBe60Oh8EO0Od8fxSwsLC4aiDymSXW2FhcRQkgYCVU5Jv1QmrTfMPwFs+E9VACamqB8dFR/wD/xAAUEQEAAAAAAAAAAAAAAAAAAACQ/9oACAEDAQE/AVJ//8QAFBEBAAAAAAAAAAAAAAAAAAAAkP/aAAgBAgEBPwFSf//EABYQAQEBAAAAAAAAAAAAAAAAADFwYP/aAAgBAQAGPwLTFnNoWFk//8QAJhAAAgEEAgICAwEBAQAAAAAAAAERECExQVGBYXHR8CCRsaHB8f/aAAgBAQABPyEWyMU12IWqIFNNux1RCY20nZE2G3I8jo6L8Ucnunp6/wCUYkR/Dsvz/SfJoPwehKCPI3ukuJLsUjm5FkNuSHFNDRcvxRwWL0Q4LCUCwo5MRc7JsIT5DE10cU+a7VL8nAxYfuk36pNJ+2PrBI1kTWbDRN+TdG8HH4OLU2R4E8SOBNSybm3SxA01JDR2X5IIH/zwbRoZF6J368DZEvv/AIJ14Jh0ST4EzZOSfJJPjQ2fdEwOiZ0dDXgej5Gy32Sx8DovZ3RTOGPR4EFlRN8kLg2cDzmvGBU7IHRx5PCHj8IHT5OPu6LDOTohcEeSFIw8uEXjFHqxkR7/AERmx0P0fdVtGDonNj9kjORNHBwcliwjzo7o8V2JG8Cm9i9y/wBghkiMEKcmGTstJbmrbkcciJ5FtE+Ti5bmmQ1iV/RpC368myWSyb5IzTn2fs7OzAWPxgtychowfdnpS4z8jfl0L3o7F7EpIGqJLxnyd/01n+i9iESSWkhUSdGv5Ts0XOhogaQjkinbHouRc6OhRC8joXo4JUG6TRDfg5sap0cXqyxYbQ1ImPgtDLcEo3AlTWDgWCPB0L0aF76Niy4LshnY5tfZtdGgy/1l/wALCgsqbL8UWKJ+aX5IZhRXc02X5OBYea/cn7O2W8/ezYkK5knuj2NmN0T8V2KnjRBAl/D9mh6U0NQ6c/J2KeS9htySyXkRlgnwSHn8G2S/rJ8f7XWSLnxSNSWJsTOxySXop8l8yyXb5PuaLMmzodHKZfgzojwXk0W5LNZGgkMsWkgQbp9zRY6o1VOjrBauHWFT4GkZGV0JCFI4OS5emjd2bObHR0Q62jBBhNIO6Zq4M8UmmVOBk+DyPJclWEQQNDiiSGsX0NHAl5EayRJv8HeYo4pFsCSHkXJdiJ5/VJLU0TjRMIUFrDj7Avf5XHoZ8UzR+xexojQ80eqT5OeTkejTFsm4xfb0uXilzQyUSofqps7p3TdxUciwOJZbk7Nrij/CxgWLcijkXunVI/g1RpChIcUd/hHlHY6eaWpJNfuqt5NV5Oqs2dGsU5IZqjpcuX8UbgvWzk4pcguKRzkZ0aNlpLckLk8ybpe42XJZclouOXkS38EeH+fNJ2PVjWCK9mlRbJotkOwm/vBAsmQ+xl7WJtg6GyUTS800dCPkkTUYnwhdU3oeWSJkuOxr5JfJPkjyQR/RNiarBCLcf6apov8AY5H2a3/o8nyoi9L3LmxTcVwje880/RbgXpeT7otFbU0ff9P/2gAMAwEAAgADAAAAEIBBIBBBJBJBJAAIBIIABJJBIAABJAIABJAIBAAABIBJBIAJAIJAIJJIABJBAIIBIBAIJABIAIBBIJAIJAAJABIJABBBJJBBBBIIIJJBBBIIJJAAJJBBJAAIIBIAIAJBBJJJIABJIBJABBIBIBABAIAAJIJAJBBBABIJJJBAIBAJIIBAJIJAIBAJIBBAABBIAAAJABBBJAAIABIJIAABJAAIAJIBBIBAJJBIJBJJJJJIJIBAAJABIAJIBAAJABAAJBJIIIIJBBJJAJBAIJAIIIBJABAJIIIAIIIBJIBBJJBJBIIJABAIAJBJAABJJIABABBAIBBJAAIAIJBBBAIIJJBJBJIJABIBIJBJBIJAIJAAJIJJBJAABJJBBAJIJIBAJJABJAAJIBABJJIJIAAIAABBIBAJBBBBAAJJBJ//xAAUEQEAAAAAAAAAAAAAAAAAAACQ/9oACAEDAQE/EFJ//8QAFBEBAAAAAAAAAAAAAAAAAAAAkP/aAAgBAgEBPxBSf//EACUQAQACAgIBAwUBAQAAAAAAAAERIQAxQVFhcYGRobHB0fDh8f/aAAgBAQABPxBdN+3pkUTs7xJO7BnjIgFOJ7yAHok9v9zZDcVf9OGWk2lvm8ZTCChXM12YtlYuIqufGCRZEpZX2y1aEokB78ZegUxJ5y5ZkgRUc9ZviG547wEzNbPW8Sfe7nv3zQRUtffJpHkNYqWhjrvEqTOiK7xmnsYCg2JYTC1XYip98Wagm+sXaJ/qybJLLkkURc2n7wlRCYReJ/vbC1MHNx1gaklOffF0jBbnrweMhYhSk8v4zQZRJ/KwRKKIDn9YxQydSvPWEkZShc+f8ySbMw9/XIRA7YCXDkNjXvhJGbTMycmMzNmpufXHkGuXy3vCK9Vbg2C5mDevXBATVV7YrYxTV5JETu9dZZ1Nbju8RlZPX+fOBJJNNzzOSJq+Z8fvBVRIVd+NGUgR2VjwMEPX1wyiSZ3CfjADImjh69MiXtPHWKd8e32xEEhqGMQ4mjrrIrQSRtMoZsC5f1gengucgB2l4n84p6DK+BbOSgybiPjE7oZIa1D24qJpFwGn/ckm4sIYO/OKZJk9nvAsPRYg4whOd+PfjIFnMLadY6saIlxiRU0xF9Zx4szGJpkdvWUBoXXD/mMyIupvGTW5eRyVbp/d5c8ibm+PPrkRI3XRmxrt7ZPnj2+2IZLIdAyYCH5jXeKlnUEex4wQvUA8decKpN1iGp4+UYPzy8YKkqeQbyFHZq/3jEcyTIC4pEaiOHzgrF436+mO10pbXHL75AVmnAmDOhNeMk1AvhT/AJgigApuU4xAkgEE3PvkEkRF4AlE3MxJlQKFrsyR0iOJ6zokTxP9xnIhi2PfGhHKKjziEpBNxYV6YkyLWyIwHRsoePXOeeOjCbA1N/fWQQDZ4MbA7S4OYzYb0OvGShF0c4wLpwqFonH/AHLAa6j+ckp2Hh785PUztuNfOVg5AONJEa6ecVozTEhWSkCWVmt3geS2Xo+uamKtSh4PGe4s106jKaIiAkOvTJKdw6gwKREyzP8AGSQQc7BnjKEiebTKVetO/wDuCQYsSfn65cgCJ3894AbK8RGsiyfRXeWKDbKz4y+Pn/dYXE8Rs+uTnoTSmKmZHw3iJKWIjAZdEwQ398Jil32P+ZQpiFed4SzaZdR+s5FHH19MAUNydsZZfAZnvADAjUvO8YhGkSBfXOBMqWxyu/DkplhMRaTTBvxkACDKlfpiIYYo398I74Zr84BuH1/WVAcFq8djtvl/eDpJLl/uMg72n5zhlU+uFUuvrEOcgrR3zll6b46M4ukbMAaMwT6dZBSDnpPvkESgb8/LOEmgCOvStYjGyPB/mJHI0PGKwIlETX7rJWVKn8f8wVEk4n5wN0qIsyFsgRtj+5wAjMkExE7xRYBZZ4a71h2jYYY7cAUB1NwV85C3nmuDzhqZIiPO8edNFYAqxsaGufOBZON0398CITG5v7347yHa1cXN/PWCCNKCPS85Xls9H7yvGvH1MAmOie+P9wEJHyevnCd/lOjpzx5jICOkFfxncKY/qwauSU+h4wPMEFQnHjA1SY5j9ZMsQTRx16Y6kCPT9ZGkEUKB/mQuuBy5wciTZwlfOQ2q1OnvAvGZtjCkIImwNMmzqoo84RJuI3B1vJWzfHt1gkRKdT+6yCoSzA/HjGZf+NemWd/Pp3i+23HenPvXrkAJB9Fv5wih5uK2fGeg0vP1wSjPOvT+3iW6isRgK+fE58HD+MQpCxE6/OO98zMGGBfPvoxYX4h9sNR45r4yB9he8kJidx9MhkiDdffeKqXDoMmWwryhzlBPTcvzmzUicmFTHv7ZGUjNPPnCx089GLV5cTPGEQj6GY56yJLL9/xeAZZPEgvfjOgVSHXjGRklEjJE419Mh3TdA/dyEl8L2lnE40MNXvv1ybKDcRM5IQFBe3BYlyavWaTHW/ORNaeJ/ORBqybnr7YywEUeWSoQtdT3glEEehgpQagqbrV5CEvZLA/fBpFetz+cArlFs373iPKb659fvkck2V/mEkr016euSRuSXnSIowWH2Q/isltuZPkxKOd+XnJJGKLmOcYBq/QXnzgohTrrrJKX5r7msjbzRU9GI1Ba5+2QlkgeH+3gQGqJiO/XCVMDbXOTKUTHP+sZhW579+cj1/ODF3431lCWUAEOJWyRd9ZKpna89/XIiwhlqvzhcsok1PnzkXnL2+eLyYs9xLPDk5aCK3HGMQ1L3Pbe8Ai4CJ5/f3yCky+h6ZAjTkrwyABH2t9snDwlqy+9YkKWdqMcmJkZZhWV84thVKNL48ZozNUX/mAgRyczx4M2W12z+MY4jgqeuoxcvHE1nIetOMQLSIvzkDTcdYhegcX1koColp3xkx5j36yKPJ6jRzPnPFEVSTgJGLqVjLOueQd84L45OMgBLOqI/f4xAEG413LdYCQRmG/b+5wSKOUJvIQJbBet4U7K/GSJQsLYx14wgEnBPP8AnjFOWNx/RkCTmQfBlpwrJAbUzJe28XpOiy9GdQbO5nBIMXO7jWsdyN7d+PGAZvdgT16YRfOvPOCUh4ZiJ54xZaTRPO5+cEptUtrvy5IrywQDxilVPNh3nB5PUaHc5Zo2j/RlykzF4LTJE8RkJlsvXrgTN88H4zVu48/3OVg8Ie+AMpULBfGQL3/zGBXqqZECJYPGLOWV+nWLkRc+/wAZA+hZOQcQq8+DzhEMg135MElyhBPX1xhaRrXpvAQk5LffCF8L2OXOkRXOJlLTHnjCZMOzvvWVbUxAGHeMKuK29/nJEy5Imn/Mlv2sY00Vyz3kUU6j39MV0I7ZoujvJUFEWajx8YEupZqfOQ1XR1T75RJeO8uYua1Hb3goUTW6/WVNzau+b8YEFv09/TA5k0LSYyUc39MZ1Bvt6y7QUVf+4aMJJarj1wGGjoVnk84LkC3986jd6lysFHYffJkledv7yZBr74SrMxHf6yShbtpMJGT9O/GNw88KGaciJqesNjUxLtxmFdRkxmEYim24yYkwk6mbxWhX3jFZuYvkj2nJdX2wPsZTDMNcP5wheCPD+cray3Z6YpIKjPEHzOSscSD8/wC40EvOr9tecgNnXl+InjJTVo8+mCmUBF8YkSkuevHeTb3ER2ecGl3MxR2YsAcuIeDBaEPcMZh16kRs/eLInRVVV6wxL5JiA8ZHDPPTrFVBJrcvnWHGKCZuPVyrEtM0vfpi0wycJxIhjwmcjy6wA2STV5Bc23UfvJA3vrxjGhjdzGFVWw0tXxlhJ0i/8y1tqO/vluz6GDLwSSRjqSWa1hPtLXK8Zx2rNQ+2QnZD9dYc+kM+v2yUTDwk/bJiYg6vsyGGvNT+cDiIkS/78YLTPpcdecP60F+nnxhKKFKYZvZRn9MJgaj279fxjLF+9fCziI44d/reIXDLEz/uARxNv7zlNNbyHHHrjN8SMe3WAhDAq6Z+cQp2Jv2/zOl+P7zgrG5BbPGDoUTwD9DEimVvgLvsxQphsCevXKBY5mTrz5x0FvVvreSw7fFo+uE1upCLqcDISXyLhYIuHdYkkvAVm/3kksJeBXJdx7MuMEapON4yTaI3fG9+MhE87Y9/1grmV84C05OcFLKMumLPGC7VMTxuMN9NBSHfnGA7UJP7WHbBAO1ajnBETAC0SbyZeJmPbrEmhaghwAtjbz2YBYWDgZjGtiLRa5wBgrpBj75EWHNQJxuWpnamQ39FGTIeY68ZJ6lXeA93Hvhxct/fIJJSeB84DSS7L9c00sPORPFdfFbwKiJfXEMc77SjIXDJC78ZACRDMa4wphKnbvEASLenqfzgCQlbnXE/nEJrepmsICJloTIIBqI3vKlJ3tfXphUK5FJmsjlYmIyImiQxLMMA8hhcDR2YQhFizD/mVIhmZr/mBRJ16c4k4TzcORseCtddfrAJGmuu/rikpHmTJLbHhnKizXfnyZXYeWnvA3o8T6uULGochiJ5GpmzHbIqXj6rZ8YCYimBT/mAZGHY+i39MAVlOeP3iBJSEHRzPnxgpCQmWgPzm0edwenrgNBmJdmzrIoWK5ygVbiC/TLC5d8v9rNvlGO1jff9+cKOridlZCvyEYBkiCuvXIFqSiO8ZFNlzETv3wKEEFNp/mCB2YAj36cFmjQfjFeZX4+N4DiF5iZ85tKa41v1wkgdy+e8SGw0TMSfOTTRQEsb/OAdVRMMYI1W9pPGISm7O+f8ywpE6afxkaVXjBVOief7nBlyiHD3iGlUlmHIRFxASf7iDKpRKj24yERN+Y+mIFrJFX11khVoTUjvO39/e+QErrd5wJtTTFZJJ5qH13ktCbZL5PN4oVXgmQ8ec45QsgDzinEww6Dn0xkmFxaOdkkiIMUWVMyA4UUljqvt64BC7jvtzkmivLvnFliXi94C9xF6+uDFXiI465yQkJ9nyby1ssev4/3FQTgszPP2xSkr3DWNbn5vjxiuVzrj9Yr2lJX+MsluNwcnjLWJNv2yPJHzxlpAnVHr48YMCSDAxMV7c5F65nIQunsg/OSIXBDet5R9nW80Go+WXEIOgSP74yEebjWQCEEJo/z9ZCEINV753b3Vce2IizuYCJ3175ek7evrgQDRu/V6wlmFiN35wMgSWqHvJQpiuJ7yUck79f8AMZmXqNHGLXlGs0RVPrtwjz1qznJFCaPxeARJpg/uMKsleqOSk4YOBcnnAZ3d8nT5ybswSc+HJmN3LPp64zbviUZyITz3B+8QkJDFYChIqa9cbCaNxf5xgp6cGcb6IxETzZYH3wBJo1QP2z4k8VU9GEwwqyxMd4ytibbvrJ1L57ySAJa6DAPJHXOT1G6+T9YDUxBO5+MlRefyZNY65+2KCunfvizBsCcz9srsTRca9MNpVNi+vTFuI7YbiMWCuyXr5ya+lN4XGXPHj67wPyEbJ4d1kNUJUqDXpiLM/wB85FRgANbqvXJSiQlup8YiNcR9fvkDI8m30nA7idbMpHhqw/OKRxZNv785IvA3FeP3hAxDf9/TlRxPv4xIibvzPO8IlZCI784KpLwhGAEkMDbHEVkwpEkSFusVVRbxY4s0uwi3+4wky087x3Gpdk4Ik4a5P7WNJWlWpioxtCal+3eIDDHXH7weeieW+H4wkluVOjs785LMzuY56xAlD6j9MgtH9OQsS14R5M0RcRHGXAtn077xgYlId+PTGJItvbi1Rzv4wPrKVeRSvifGjLHlE7nvJeHZxnLAS0FvGRMiJp8/bAbO/X74LwJvo68ZNNeHTG8FwVNfbIZezAKqxJtQ/OEZVorfJnBVEG0+05BCwRuZPoYkCufO4yeCTMzB5/DlTPLevTusktU60RUdeucBO+MqNGa+27zRGrs45/eaDPfJiqqAUhU5MsRFzd/1e+C9cxuecrkbIYjjgydVT6fvNi0jr284llPfeAd7fw5smezWAgTa7jBFkc69MiCAZqEyGSx3U7+MZFK5kT/MbKrZTX4xBolLI9vGbadzO+Z6yuYZ9v1iw0rOkPjG1Ldxq/SL1htbURXn0+2V0WlwdOK0D+es5xSIgnBlYrnr7z4wUvbuXjACiQb2W3l9BJc5KiKlIvsyNjG2OOfXJqOdsS/nBO8SyX+8WQl0/wBvHhGNt28ZLkRPR0d4pqT0g/XWVd9ag7yyEHuzr1weEfbEKwxTEglEZTiMiQs1Onk8YghLDPTzjEY4JxhnQzHOHAEyhUc18cxggHKfRjrWAkkzBdHccZqd6dx3jwiAmpnnCeF67yZK64vWWL71GCsUODr84qBPRp/3Emhh6v8AOXWv+vXFhouQ134xBDB3nMRPbipICTediKEn4856OU89YNuje8YOjdDiGwJivbJCRqb4N81iK87nSfbLJJEnIDQ+dz6YbIXOp7xSRBZjZ84tpolWfvITEyrGz95IMxw/rwAJhh5jrL1J1PGBNSXELWIkWS+/OQhyu7DLtb8n9xlblLv+GU0EJ5cY9bOZ7yDpNRzzk0YN4SqODPzhrcofdnYsTzPnK2/l5y/5GSud878YXfU7xmDUy/jC3r9tec8t+fXCZdyzM54W2ZnK8R4ygnz33m0Dtz6eMdk784RJHIzppf3zwiPE9Zc8zea+4qYzgv0rb5w8Exon8Vh4jz1rCPb8z849B+T9Ybo+phEvaPnLren7M//Z); 10 | } 11 | #content-wrapper { 12 | margin: auto; 13 | max-width: 600px; 14 | } 15 | input:focus { 16 | outline: none; 17 | } 18 | h1, h2 { 19 | line-height: 1em; 20 | } 21 | h2 { 22 | margin-top: 1.5em; 23 | } 24 | a { 25 | color: #ccc; 26 | text-decoration: none; 27 | border-bottom: 1px solid #777; 28 | display: inline-block; 29 | height: 1.1em; 30 | padding: 0 1px; 31 | } 32 | a:hover { 33 | color: #fff; 34 | border-color: #aaa; 35 | } 36 | .a-inline { 37 | display:inline; 38 | padding: 0; 39 | } 40 | pre { 41 | display: inline; 42 | background-color: rgba(255, 255, 255, .19); 43 | padding: .5em; 44 | } 45 | .color { 46 | padding: .5em; 47 | margin-right: .4em; 48 | border: 1px solid #aaa; 49 | border-radius: 3px; 50 | width: 140px; 51 | } 52 | .div-toggles { 53 | margin-top: 1em; 54 | } 55 | .div-toggles .trigger { 56 | position: relative; 57 | display: inline-block; 58 | width: 40px; 59 | padding: 4px; 60 | height: 25px; 61 | border: 1px solid #666; 62 | border-radius: 2px; 63 | background: #eee; 64 | box-shadow: inset 0 -17px 8px rgba(0,0,0,0.3), inset 0 -4px 7px rgba(0,0,0,0.3); 65 | } 66 | .div-toggles .trigger:after { 67 | content: ""; 68 | display: block; 69 | position: absolute; 70 | top: 50%; 71 | right: 5px; 72 | margin-top: -2px; 73 | border: 5px solid; 74 | border-color: #000 transparent transparent; 75 | } 76 | .div-toggles .trigger:before { 77 | content: ""; 78 | display: block; 79 | position: absolute; 80 | top: 50%; 81 | right: 4px; 82 | margin-top: -1px; 83 | border: 5px solid; 84 | border-color: #eee transparent transparent; 85 | } 86 | .div-toggles .active:before { 87 | margin-top: -7px; 88 | border-color: transparent transparent #eee; 89 | } 90 | .div-toggles .active:after { 91 | margin-top: -8px; 92 | border-color: transparent transparent #000; 93 | } 94 | .div-toggles .trigger div { 95 | display: inline-block; 96 | width: 23px; 97 | height: 23px; 98 | background: #fff url('data:image/gif;base64,R0lGODlhDAAMAIABAMzMzP///yH5BAEAAAEALAAAAAAMAAwAAAIWhB+ph5ps3IMyQFBvzVRq3zmfGC5QAQA7'); 99 | } 100 | .div-toggles .trigger div div { 101 | border: 1px solid #666; 102 | border-color: #666 #ccc #ccc #666; 103 | background: #aaa; 104 | } 105 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | tiny jQuery color picker 23 | 24 | 25 |
26 |

Tiny jQuery colorPicker

27 |

Looking for mobile first, tiny foot print, fast, scaleable, flexible and pluggable...
28 | This 5.07KB (gZip; 11.39KB minified) small HSB color picker is based on a subset of colors.js from it's big brother colorPicker, supports all modern features like touch and MS pointer, GPU accelerated rendering, battery friendly requestAnimationFrame and provides a lot of hooks for developers to write plugins (See demo plugins below in Demo).

29 | 30 |

Demo

31 | On all elements with className 'color':
$('.color').colorPicker();
32 |

Switch between plugins: 33 | 47 | (see index.html for more details...) 48 |

49 |
50 | 51 | 52 | 53 |
54 |
55 |
56 |
57 |
58 | 59 |
60 |

Usage

61 |

There is only one file you need to load... No images and no CSS required.

62 |
 63 | <script type="text/javascript" src="jqColorPicker.min.js">
 64 | <script type="text/javascript">
 65 |     $('.color').colorPicker(); // that's it
 66 | </script>
 67 | 
68 |

Features

69 |

Tiny jQuery colorPicker only loads into memory if triggered to show and auto repositiones inside view-port if it doesn't fit. It uses battery saving technologies, super fast rendering for best performance on desktop and mobile browsers and renders perfectly smooth on retina and high resolution displays.
70 | This colorPicker is very flexible to modify and customize and there is an easy way to write plugins to extend functionality, look and feel...
71 | As Tiny jQuery colorPicker uses colors.js from it's big brother colorPicker, it provides a clean and rich color model and API that enables flexible extending for programmers. (See colorPicker on GitHub for more details)

72 |

The following snipped shows how easy it is to make plugins: use for mobile

73 |
 74 | window.myColorPicker = $('input.color').colorPicker({
 75 |     buildCallback: function($elm) {
 76 |         this.$colorPatch = $elm.prepend('<div class="cp-disp">').find('.cp-disp');
 77 |     },
 78 |     cssAddon:
 79 |         '.cp-disp {padding:10px; margin-bottom:6px; font-size:19px; height:20px; line-height:20px}' +
 80 |         '.cp-xy-slider {width:200px; height:200px;}' +
 81 |         '.cp-xy-cursor {width:16px; height:16px; border-width:2px; margin:-8px}' +
 82 |         '.cp-z-slider {height:200px; width:40px;}' +
 83 |         '.cp-z-cursor {border-width:8px; margin-top:-8px;}' +
 84 |         '.cp-alpha {height:40px;}' +
 85 |         '.cp-alpha-cursor {border-width:8px; margin-left:-8px;}',
 86 | 
 87 |     renderCallback: function($elm, toggled) {
 88 |         var colors = this.color.colors;
 89 | 
 90 |         this.$colorPatch.css({
 91 |             backgroundColor: '#' + colors.HEX,
 92 |             color: colors.RGBLuminance > 0.22 ? '#222' : '#ddd'
 93 |         }).text(this.color.toString($elm._colorMode)); // $elm.val();
 94 |     }
 95 | });
 96 | 
97 |

API and usage

98 |

Will follow... See tinyColorPicker on GitHub for now.

99 |
100 | Fork me on GitHub 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | (function(window, $, undefined){ 2 | 'use strict'; 3 | 4 | var plugin = {}, 5 | $pluginSelect = $('#pluginSelect'), 6 | getQueryVariable = function(variable) { 7 | var query = window.location.search.substring(1), 8 | vars = query.split('&'), 9 | pair, i; 10 | 11 | for (i = vars.length; i--; ) { 12 | pair = vars[i].split('='); 13 | if(pair[0] === variable){ 14 | return pair[1].replace(/^\s*|\s*$/, ''); 15 | } 16 | } 17 | return(false); 18 | }, 19 | type = getQueryVariable('type'); 20 | 21 | // plugin for mobile use (bigger and value/color display on top) 22 | plugin.mobile = { 23 | customBG: '#222', 24 | margin: '4px -2px 0', 25 | doRender: 'div div', 26 | preventFocus: true, 27 | animationSpeed: 0, 28 | 29 | // demo on how to make plugins... mobile support plugin 30 | buildCallback: function($elm) { 31 | this.$colorPatch = $elm.prepend('
').find('.cp-disp'); 32 | $('.color').on('click', function(e) { 33 | e.preventDefault && e.preventDefault(); 34 | }); 35 | }, 36 | cssAddon: // could also be in a css file instead 37 | '.cp-disp{padding:10px; margin-bottom:6px; font-size:19px; height:20px; line-height:20px}' + 38 | '.cp-xy-slider{width:200px; height:200px;}' + 39 | '.cp-xy-cursor{width:16px; height:16px; border-width:2px; margin:-8px}' + 40 | '.cp-z-slider{height:200px; width:40px;}' + 41 | '.cp-z-cursor{border-width:8px; margin-top:-8px;}' + 42 | '.cp-alpha{height:40px;}' + 43 | '.cp-alpha-cursor{border-width: 8px; margin-left:-8px;}', 44 | 45 | renderCallback: function($elm, toggled) { 46 | var colors = this.color.colors; 47 | 48 | this.$colorPatch.css({ 49 | backgroundColor: '#' + colors.HEX, 50 | color: colors.RGBLuminance > 0.22 ? '#222' : '#ddd' 51 | }).text(this.color.toString($elm._colorMode)); // $elm.val(); 52 | } 53 | }; 54 | 55 | // shows input fields for rgb and hsv; changeable 56 | plugin.input = { 57 | customBG: '#222', 58 | margin: '4px -2px 0', 59 | doRender: 'div div', 60 | 61 | buildCallback: function($elm) { 62 | var colorInstance = this.color, 63 | colorPicker = this; 64 | 65 | $elm.prepend('
' + 66 | 'R
' + 67 | 'G
' + 68 | 'B
' + 69 | 'H
' + 70 | 'S
' + 71 | 'B
' + 72 | '' + 73 | '
').on('change', 'input', function(e) { 74 | var value = this.value, 75 | className = this.className, 76 | type = className.split('-')[1], 77 | color = {}; 78 | 79 | color[type] = value; 80 | colorInstance.setColor(type === 'HEX' ? value : color, 81 | type === 'HEX' ? 'HEX' : /(?:r|g|b)/.test(type) ? 'rgb' : 'hsv'); 82 | colorPicker.render(); 83 | this.blur(); 84 | }); 85 | }, 86 | 87 | cssAddon: // could also be in a css file instead 88 | '.cp-color-picker{box-sizing:border-box; width:226px;}' + 89 | '.cp-color-picker .cp-panel {line-height: 21px; float:right;' + 90 | 'padding:0 1px 0 8px; margin-top:-1px; overflow:visible}' + 91 | '.cp-xy-slider:active {cursor:none;}' + 92 | '.cp-panel, .cp-panel input {color:#bbb; font-family:monospace,' + 93 | '"Courier New",Courier,mono; font-size:12px; font-weight:bold;}' + 94 | '.cp-panel input {width:28px; height:12px; padding:2px 3px 1px;' + 95 | 'text-align:right; line-height:12px; background:transparent;' + 96 | 'border:1px solid; border-color:#222 #666 #666 #222;}' + 97 | '.cp-panel hr {margin:0 -2px 2px; height:1px; border:0;' + 98 | 'background:#666; border-top:1px solid #222;}' + 99 | '.cp-panel .cp-HEX {width:44px; position:absolute; margin:1px -3px 0 -2px;}' + 100 | '.cp-alpha {width:155px;}', 101 | 102 | renderCallback: function($elm, toggled) { 103 | var colors = this.color.colors.RND, 104 | modes = { 105 | r: colors.rgb.r, g: colors.rgb.g, b: colors.rgb.b, 106 | h: colors.hsv.h, s: colors.hsv.s, v: colors.hsv.v, 107 | HEX: this.color.colors.HEX 108 | }; 109 | 110 | $('input', '.cp-panel').each(function() { 111 | this.value = modes[this.className.substr(3)]; 112 | }); 113 | } 114 | }; 115 | 116 | // shows memory fields 117 | plugin.memory = { 118 | customBG: '#222', 119 | margin: '4px -2px 0', 120 | doRender: 'div div', 121 | opacity: false, 122 | 123 | buildCallback: function($elm) { 124 | var colorInstance = this.color, 125 | colorPicker = this, 126 | random = function(n) { 127 | return Math.round(Math.random() * (n || 255)); 128 | }; 129 | 130 | $elm.append('
' + 131 | '
' + 132 | '
S
'). 133 | on('click', '.cp-memory div', function(e) { 134 | var $this = $(this); 135 | 136 | if (this.className) { 137 | $this.parent().prepend($this.prev()).children().eq(0). 138 | css('background-color', '#' + colorInstance.colors.HEX); 139 | } else { 140 | colorInstance.setColor($this.css('background-color')); 141 | colorPicker.render(); 142 | } 143 | }).find('.cp-memory div').each(function() { 144 | !this.className && $(this).css({background: 145 | 'rgb(' + random() + ', ' + random() + ', ' + random() + ')' 146 | }); 147 | }); 148 | }, 149 | 150 | cssAddon: // could also be in a css file instead 151 | '.cp-memory {margin-bottom:6px; clear:both;}' + 152 | '.cp-xy-slider:active {cursor:none;}' + 153 | '.cp-memory div {float:left; width:17px; height:17px; margin-right:2px;' + 154 | 'background:rgba(0,0,0,1); text-align:center; line-height:17px;}' + 155 | '.cp-memory .cp-store {width:21px; margin:0; background:none; font-weight:bold;' + 156 | 'box-sizing:border-box; border: 1px solid; border-color: #666 #222 #222 #666;}' 157 | }; 158 | 159 | // the default; no extra stuff 160 | plugin.desktop = { 161 | customBG: '#222', 162 | margin: '4px -2px 0', 163 | doRender: 'div div', 164 | cssAddon:'.cp-xy-slider:active {cursor:none;}' 165 | }; 166 | 167 | // the default without alpha chanel though 168 | plugin.noalpha = { 169 | customBG: '#222', 170 | margin: '4px -2px 0', 171 | doRender: 'div div', 172 | cssAddon:'.cp-xy-slider:active {cursor:none;}', 173 | opacity: false 174 | }; 175 | 176 | // the default but smaller 177 | plugin.small = { 178 | customBG: '#222', 179 | margin: '4px -2px 0', 180 | doRender: 'div div', 181 | cssAddon: // could also be in a css file instead 182 | '.cp-color-picker{padding:5px 5px 0;}' + 183 | '.cp-xy-slider{width:100px; height:100px; margin-bottom:3px;}' + 184 | '.cp-z-slider{height:100px; margin-left:4px;}' + 185 | '.cp-alpha{margin:4px 0;}' + 186 | '.cp-xy-slider:active {cursor:none;}' 187 | }; 188 | 189 | // better IE support 190 | plugin.IE8 = { 191 | customBG: '#222', 192 | margin: '4px -2px 0', 193 | doRender: 'div div', 194 | // this demo adds divs with gradiends,... you could simply load an image as well 195 | buildCallback: function($elm) { 196 | var that = this; 197 | 198 | $elm.find('.cp-z-slider').prepend( 199 | '
' + 200 | '
' + 201 | '
' + 202 | '
' + 203 | '
' + 204 | '
' 205 | ); 206 | }, 207 | cssAddon: // could also be in a css file instead 208 | '.cp-r-rb{filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#ff0000\', endColorstr=\'#ff00ff\',GradientType=0 ); height:21px; width: 100%;}' + 209 | '.cp-rb-b{filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#FF00FF\', endColorstr=\'#0000FF\',GradientType=0 ); height:21px; width: 100%;}' + 210 | '.cp-b-bg{filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#0000FF\', endColorstr=\'#00FFFF\',GradientType=0 ); height:22px; width: 100%;}' + 211 | '.cp-bg-g{filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#00FFFF\', endColorstr=\'#00FF00\',GradientType=0 ); height:21px; width: 100%;}' + 212 | '.cp-g-gr{filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#00FF00\', endColorstr=\'#FFFF00\',GradientType=0 ); height:21px; width: 100%;}' + 213 | '.cp-gr-r{filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=\'#FFFF00\', endColorstr=\'#FF0000\',GradientType=0 ); height:22px; width: 100%;}' + 214 | '.cp-z-cursor{top:0;height:0;}' + 215 | '.cp-xy-slider:active {cursor:none;}', 216 | 217 | renderCallback: function($elm, toggled) { 218 | // to avoid selection 219 | window.event && (window.event.returnValue = false); 220 | } 221 | }; 222 | 223 | 224 | // the default skinned and white 225 | plugin.skinned = { 226 | customBG: '#222', 227 | margin: '5px -2px 0', 228 | doRender: 'div div', 229 | cssAddon: // could also be in a css file instead 230 | '.cp-color-picker{border:1px solid #999; padding:10px 10px 0;' + 231 | 'background:#eee; overflow:visible; border-radius:3px;}' + 232 | '.cp-color-picker:after{content:""; display:block; ' + 233 | 'position:absolute; top:-15px; left:12px; border:8px solid #eee;' + 234 | 'border-color: transparent transparent #eee}' + 235 | // simulate border... 236 | '.cp-color-picker:before{content:""; display:block; ' + 237 | 'position:absolute; top:-16px; left:12px; border:8px solid #eee;' + 238 | 'border-color: transparent transparent #999}' + 239 | '.cp-xy-slider:active {cursor:none;}' + 240 | '.cp-xy-slider{border:1px solid #999; margin-bottom:10px;}' + 241 | '.cp-xy-cursor{width:12px; height:12px; margin:-6px}' + 242 | '.cp-z-slider{margin-left:10px; border:1px solid #999;}' + 243 | '.cp-z-cursor{border-width:5px; margin-top:-5px;}' + 244 | '.cp-color-picker .cp-alpha{margin:10px 0 0; height:6px; border-radius:6px;' + 245 | 'overflow:visible; border:1px solid #999; box-sizing:border-box;' + 246 | 'background: linear-gradient(to right, rgba(238,238,238,1) 0%,rgba(238,238,238,0) 100%);}' + 247 | '.cp-color-picker .cp-alpha{margin:10px 0}' + 248 | '.cp-alpha-cursor{background: #eee; border-radius: 100%;' + 249 | 'width:14px; height:14px; margin:-5px -7px; border:1px solid #666!important;' + 250 | 'box-shadow:inset -2px -4px 3px #ccc}' 251 | }; 252 | 253 | // the default skinned and white 254 | plugin.skinned_sa = $.extend({}, plugin.skinned, { 255 | renderCallback: function($elm, toggled) { 256 | if (typeof toggled === 'boolean') { 257 | $('.cp-alpha', this.$UI).css('display', $elm.hasClass('no-alpha') ? 'none' : '') 258 | } 259 | }}); 260 | 261 | // skinned similar to dev tools color picker (but then way smaller and faster...) 262 | plugin.dev_skinned = { 263 | customBG: '#222', 264 | margin: '5px 0 0', 265 | doRender: 'div div', 266 | colorNames: { 267 | '191970': 'midnightblue', 268 | '696969': 'dimgrey', 269 | '708090': 'slategrey', 270 | '778899': 'lightslategrey', 271 | '800000': 'maroon', 272 | '800080': 'purple', 273 | '808000': 'olive', 274 | '808080': 'grey', 275 | 'F0F8FF': 'aliceblue', 276 | 'FAEBD7': 'antiquewhite', 277 | '00FFFF': 'cyan', 278 | '7FFFD4': 'aquamarine', 279 | 'F0FFFF': 'azure', 280 | 'F5F5DC': 'beige', 281 | 'FFE4C4': 'bisque', 282 | '000000': 'black', 283 | 'FFEBCD': 'blanchedalmond', 284 | '0000FF': 'blue', 285 | '8A2BE2': 'blueviolet', 286 | 'A52A2A': 'brown', 287 | 'DEB887': 'burlywood', 288 | '5F9EA0': 'cadetblue', 289 | '7FFF00': 'chartreuse', 290 | 'D2691E': 'chocolate', 291 | 'FF7F50': 'coral', 292 | '6495ED': 'cornflowerblue', 293 | 'FFF8DC': 'cornsilk', 294 | 'DC143C': 'crimson', 295 | '00008B': 'darkblue', 296 | '008B8B': 'darkcyan', 297 | 'B8860B': 'darkgoldenrod', 298 | 'A9A9A9': 'darkgrey', 299 | '006400': 'darkgreen', 300 | 'BDB76B': 'darkkhaki', 301 | '8B008B': 'darkmagenta', 302 | '556B2F': 'darkolivegreen', 303 | 'FF8C00': 'darkorange', 304 | '9932CC': 'darkorchid', 305 | '8B0000': 'darkred', 306 | 'E9967A': 'darksalmon', 307 | '8FBC8F': 'darkseagreen', 308 | '483D8B': 'darkslateblue', 309 | '2F4F4F': 'darkslategrey', 310 | '00CED1': 'darkturquoise', 311 | '9400D3': 'darkviolet', 312 | 'FF1493': 'deeppink', 313 | '00BFFF': 'deepskyblue', 314 | '1E90FF': 'dodgerblue', 315 | 'B22222': 'firebrick', 316 | 'FFFAF0': 'floralwhite', 317 | '228B22': 'forestgreen', 318 | 'FF00FF': 'magenta', 319 | 'DCDCDC': 'gainsboro', 320 | 'F8F8FF': 'ghostwhite', 321 | 'FFD700': 'gold', 322 | 'DAA520': 'goldenrod', 323 | '008000': 'green', 324 | 'ADFF2F': 'greenyellow', 325 | 'F0FFF0': 'honeydew', 326 | 'FF69B4': 'hotpink', 327 | 'CD5C5C': 'indianred', 328 | '4B0082': 'indigo', 329 | 'FFFFF0': 'ivory', 330 | 'F0E68C': 'khaki', 331 | 'E6E6FA': 'lavender', 332 | 'FFF0F5': 'lavenderblush', 333 | '7CFC00': 'lawngreen', 334 | 'FFFACD': 'lemonchiffon', 335 | 'ADD8E6': 'lightblue', 336 | 'F08080': 'lightcoral', 337 | 'E0FFFF': 'lightcyan', 338 | 'FAFAD2': 'lightgoldenrodyellow', 339 | 'D3D3D3': 'lightgrey', 340 | '90EE90': 'lightgreen', 341 | 'FFB6C1': 'lightpink', 342 | 'FFA07A': 'lightsalmon', 343 | '20B2AA': 'lightseagreen', 344 | '87CEFA': 'lightskyblue', 345 | 'B0C4DE': 'lightsteelblue', 346 | 'FFFFE0': 'lightyellow', 347 | '00FF00': 'lime', 348 | '32CD32': 'limegreen', 349 | 'FAF0E6': 'linen', 350 | '66CDAA': 'mediumaquamarine', 351 | '0000CD': 'mediumblue', 352 | 'BA55D3': 'mediumorchid', 353 | '9370DB': 'mediumpurple', 354 | '3CB371': 'mediumseagreen', 355 | '7B68EE': 'mediumslateblue', 356 | '00FA9A': 'mediumspringgreen', 357 | '48D1CC': 'mediumturquoise', 358 | 'C71585': 'mediumvioletred', 359 | 'F5FFFA': 'mintcream', 360 | 'FFE4E1': 'mistyrose', 361 | 'FFE4B5': 'moccasin', 362 | 'FFDEAD': 'navajowhite', 363 | '000080': 'navy', 364 | 'FDF5E6': 'oldlace', 365 | '6B8E23': 'olivedrab', 366 | 'FFA500': 'orange', 367 | 'FF4500': 'orangered', 368 | 'DA70D6': 'orchid', 369 | 'EEE8AA': 'palegoldenrod', 370 | '98FB98': 'palegreen', 371 | 'AFEEEE': 'paleturquoise', 372 | 'DB7093': 'palevioletred', 373 | 'FFEFD5': 'papayawhip', 374 | 'FFDAB9': 'peachpuff', 375 | 'CD853F': 'peru', 376 | 'FFC0CB': 'pink', 377 | 'DDA0DD': 'plum', 378 | 'B0E0E6': 'powderblue', 379 | 'FF0000': 'red', 380 | 'BC8F8F': 'rosybrown', 381 | '4169E1': 'royalblue', 382 | '8B4513': 'saddlebrown', 383 | 'FA8072': 'salmon', 384 | 'F4A460': 'sandybrown', 385 | '2E8B57': 'seagreen', 386 | 'FFF5EE': 'seashell', 387 | 'A0522D': 'sienna', 388 | 'C0C0C0': 'silver', 389 | '87CEEB': 'skyblue', 390 | '6A5ACD': 'slateblue', 391 | 'FFFAFA': 'snow', 392 | '00FF7F': 'springgreen', 393 | '4682B4': 'steelblue', 394 | 'D2B48C': 'tan', 395 | '008080': 'teal', 396 | 'D8BFD8': 'thistle', 397 | 'FF6347': 'tomato', 398 | '40E0D0': 'turquoise', 399 | 'EE82EE': 'violet', 400 | 'F5DEB3': 'wheat', 401 | 'FFFFFF': 'white', 402 | 'F5F5F5': 'whitesmoke', 403 | 'FFFF00': 'yellow', 404 | '9ACD32': 'yellowgreen' 405 | }, 406 | 407 | buildCallback: function($elm) { 408 | var that = this; 409 | 410 | $elm.append('
'); 411 | // $('.trigger').parent().on('click', '.trigger', function(e) { 412 | // if (e.target === this && $(this).hasClass('active')) { 413 | // e.cancelBubble = true; 414 | // e.stopPropagation && e.stopPropagation(); 415 | // that.toggle(); 416 | // } 417 | // }); 418 | // if input type="color" 419 | // $('.color').on('click', function(e){ 420 | // e.preventDefault && e.preventDefault(); 421 | // }); 422 | }, 423 | 424 | cssAddon: // could also be in a css file instead 425 | '.cp-patch{float:left; margin:9px 0 0;' + 426 | 'height:24px; width: 24px; border:1px solid #aaa;}' + 427 | '.cp-patch{background-image: url(\'data:image/gif;base64,R0lGODlhDAAMAIABAMzMzP///yH5BAEAAAEALAAAAAAMAAwAAAIWhB+ph5ps3IMyQFBvzVRq3zmfGC5QAQA7\');}' + 428 | '.cp-patch div{height:24px; width: 24px;}' + 429 | '.cp-disp{padding:4px 0 4px 4px; margin-top:10px; font-size:12px;' + 430 | 'height:16px; line-height:16px; color:#333;}' + 431 | '.cp-color-picker{border:1px solid #999; padding:8px; box-shadow:5px 5px 16px rgba(0,0,0,0.4);' + 432 | 'background:#eee; overflow:visible; border-radius:3px;}' + 433 | '.cp-color-picker:after{content:""; display:block; ' + 434 | 'position:absolute; top:-8px; left:8px; border:8px solid #eee; border-width: 0px 8px 8px;' + 435 | 'border-color: transparent transparent #eee}' + 436 | // simulate border... 437 | '.cp-color-picker:before{content:""; display:block; ' + 438 | 'position:absolute; top:-9px; left:8px; border:8px solid #eee; border-width: 0px 8px 8px;' + 439 | 'border-color: transparent transparent #999}' + 440 | '.cp-xy-slider{border:1px solid #aaa; margin-bottom:10px; width:150px; height:150px;}' + 441 | '.cp-xy-slider:active {cursor:none;}' + 442 | '.cp-xy-cursor{width:12px; height:12px; margin:-6px}' + 443 | '.cp-z-slider{margin-left:8px; border:1px solid #aaa; height:150px; width:24px;}' + 444 | '.cp-z-cursor{border-width:5px; margin-top:-5px;}' + 445 | '.cp-color-picker .cp-alpha{width:152px; margin:10px 0 0; height:6px; border-radius:6px;' + 446 | 'overflow:visible; border:1px solid #aaa; box-sizing:border-box;' + 447 | 'background: linear-gradient(to right, rgba(238,238,238,1) 0%,rgba(238,238,238,0) 100%);}' + 448 | '.cp-alpha-cursor{background: #eee; border-radius: 100%;' + 449 | 'width:14px; height:14px; margin:-5px -7px; border:1px solid #999!important;' + 450 | 'box-shadow:inset -2px -4px 3px #ccc}' + 451 | '.cp-alpha:after{position:relative; content:"α"; color:#666; font-size:16px;' + 452 | 'font-family:monospace; position:absolute; right:-26px; top:-8px}', 453 | 454 | renderCallback: function($elm, toggled) { 455 | var colors = this.color.colors, 456 | rgb = colors.RND.rgb; 457 | 458 | $('.cp-patch div').css({'background-color': $elm[0].style.backgroundColor}); 459 | $('.cp-disp').text(this.color.options.colorNames[colors.HEX] || $elm.val()); 460 | if (toggled === true) { 461 | // here you can recalculate position after showing the color picker 462 | // in case it doesn't fit into view. 463 | $('.trigger').removeClass('active'); 464 | $elm.closest('.trigger').addClass('active'); 465 | } else if (toggled === false) { 466 | $elm.closest('.trigger').removeClass('active'); 467 | } 468 | } 469 | }; 470 | 471 | plugin.dev_skinned_hh = $.extend({}, plugin.dev_skinned, 472 | {cssAddon: plugin.dev_skinned.cssAddon + 473 | '.cp-xy-slider{height:100px}' + 474 | '.cp-z-slider{height:100px}' + 475 | '.cp-xy-slider, .cp-patch, .cp-z-slider{box-shadow: inset 1px 1px 8px rgba(0,0,0,.15),' + 476 | ' inset -1px -1px 6px rgba(0,0,0,.15);'}); 477 | 478 | 479 | 480 | plugin.dev_skinned_rgb = { 481 | customBG: '#222', 482 | margin: '5px 0 0', 483 | doRender: 'div div', 484 | colorNames: plugin.dev_skinned.colorNames, 485 | buildCallback: function($elm) { 486 | var that = this; 487 | var currentRGB = ''; 488 | var $currentSlider = $(); 489 | var currentOffset = {}; 490 | var $window = $(window); 491 | var mouseMove = function(e) { // don't render here. Just setColor; 492 | var color = {}; 493 | 494 | color[currentRGB] = (e.pageX - currentOffset.left) / that.currentWidth * 255; 495 | that.color.setColor(color, 'rgb', that.color.colors.alpha); 496 | that.render(); 497 | }; 498 | 499 | $elm.append( 500 | '
' + 501 | '
' + 502 | '
' + 503 | '
'); 504 | 505 | this.$cursorR = $elm.find('.cp-rgb-r-cursor'); // caching for render renderCallback 506 | this.$cursorG = $elm.find('.cp-rgb-g-cursor'); 507 | this.$cursorB = $elm.find('.cp-rgb-b-cursor'); 508 | 509 | $elm.on('mousedown', '.cp-rgb-r, .cp-rgb-g, .cp-rgb-b', function(e) { 510 | $currentSlider = $(this); 511 | currentRGB = this.className.replace(/cp-rgb-(\D){1}/, "$1"); 512 | currentOffset = $currentSlider.offset(); 513 | that.currentWidth = $currentSlider[0].clientWidth; 514 | $window.on('mousemove.rgb', mouseMove); 515 | e.preventDefault && e.preventDefault(); 516 | mouseMove(e); 517 | return false; 518 | }); 519 | $window.on('mouseup', function(e) { 520 | $window.off('mousemove.rgb'); 521 | }); 522 | }, 523 | 524 | cssAddon: plugin.dev_skinned.cssAddon.replace('152px; margin:10px 0 0', '152px; margin:12px 0 0'). 525 | replace( 526 | '.cp-alpha{', '.cp-alpha, div.cp-rgb-r, div.cp-rgb-g, div.cp-rgb-b{' + 527 | 'overflow: visible;'). 528 | replace( 529 | '.cp-alpha-cursor{', '.cp-alpha-cursor, .cp-rgb-r-cursor, .cp-rgb-g-cursor, .cp-rgb-b-cursor{' + 530 | 'box-sizing: border-box; position: absolute;'). 531 | replace( 532 | '.cp-alpha:after{', '.cp-alpha:after, .cp-rgb-r:after, .cp-rgb-g:after, .cp-rgb-b:after{') + 533 | 534 | '.cp-rgb-r:after{content:"R";}.cp-rgb-g:after{content:"G";}.cp-rgb-b:after{content:"B";}' + 535 | 'div.cp-rgb-r{background-color: red;}' + 536 | 'div.cp-rgb-g{background-color: green;}' + 537 | 'div.cp-rgb-b{background-color: blue;}', 538 | 539 | 540 | renderCallback: function($elm, toggled) { 541 | var colors = this.color.colors, 542 | rgb = colors.RND.rgb; 543 | 544 | $('.cp-patch div').css({'background-color': $elm[0].style.backgroundColor}); 545 | $('.cp-disp').text(this.color.options.colorNames[colors.HEX] || $elm.val()); 546 | 547 | this.currentWidth = this.currentWidth || this.$UI.find('.cp-rgb-r')[0].clientWidth; 548 | this.$cursorR.css({left: rgb.r / 255 * this.currentWidth}); 549 | this.$cursorG.css({left: rgb.g / 255 * this.currentWidth}); 550 | this.$cursorB.css({left: rgb.b / 255 * this.currentWidth}); 551 | } 552 | }; 553 | 554 | 555 | $pluginSelect.val(type || 'desktop'). 556 | on('change', function(e) { 557 | window.location = 'index.html?type=' + this.value + '#demo' 558 | }); 559 | 560 | 561 | var isMobile = /webOS|iPhone|iPad|iPod|BlackBerry|Windows Phone/i. 562 | test(window.navigator.userAgent); 563 | 564 | type === 'mobile' && !isMobile && $('#qr').show(); 565 | isMobile && $('.div-toggles').hide(); 566 | 567 | window.myColorPicker = $('.color').colorPicker( 568 | plugin[type] || plugin.desktop 569 | ); 570 | $('.trigger').colorPicker(plugin[type] || plugin.desktop); 571 | $('pre').colorPicker(plugin[type] || plugin.desktop); 572 | })(window, jQuery); -------------------------------------------------------------------------------- /jqColorPicker.js: -------------------------------------------------------------------------------- 1 | (function (root, factory) { 2 | if (typeof exports === 'object') { 3 | module.exports = factory(root, require('jquery'), require('colors')); 4 | } else if (typeof define === 'function' && define.amd) { 5 | define(['jquery', 'colors'], function (jQuery, Colors) { 6 | return factory(root, jQuery, Colors); 7 | }); 8 | } else { 9 | factory(root, root.jQuery, root.Colors); 10 | } 11 | }(this, function(window, $, Colors, undefined){ 12 | 'use strict'; 13 | 14 | var $document = $(document), 15 | _instance = $(), 16 | _colorPicker, 17 | _color, 18 | _options, 19 | 20 | _$trigger, _$UI, 21 | _$z_slider, _$xy_slider, 22 | _$xy_cursor, _$z_cursor , _$alpha , _$alpha_cursor, 23 | 24 | _pointermove = 'touchmove.tcp mousemove.tcp pointermove.tcp', 25 | _pointerdown = 'touchstart.tcp mousedown.tcp pointerdown.tcp', 26 | _pointerup = 'touchend.tcp mouseup.tcp pointerup.tcp', 27 | _GPU = false, 28 | _animate = window.requestAnimationFrame || 29 | window.webkitRequestAnimationFrame || function(cb){cb()}, 30 | _html = '
', 34 | // 'grunt-contrib-uglify' puts all this back to one single string... 35 | _css = '.cp-color-picker{position:absolute;overflow:hidden;padding:6p' + 36 | 'x 6px 0;background-color:#444;color:#bbb;font-family:Arial,Helve' + 37 | 'tica,sans-serif;font-size:12px;font-weight:400;cursor:default;bo' + 38 | 'rder-radius:5px}.cp-color-picker>div{position:relative;overflow:' + 39 | 'hidden}.cp-xy-slider{float:left;height:128px;width:128px;margin-' + 40 | 'bottom:6px;background:linear-gradient(to right,#FFF,rgba(255,255' + 41 | ',255,0))}.cp-white{height:100%;width:100%;background:linear-grad' + 42 | 'ient(rgba(0,0,0,0),#000)}.cp-xy-cursor{position:absolute;top:0;w' + 43 | 'idth:10px;height:10px;margin:-5px;border:1px solid #fff;border-r' + 44 | 'adius:100%;box-sizing:border-box}.cp-z-slider{float:right;margin' + 45 | '-left:6px;height:128px;width:20px;background:linear-gradient(red' + 46 | ' 0,#f0f 17%,#00f 33%,#0ff 50%,#0f0 67%,#ff0 83%,red 100%)}.cp-z-' + 47 | 'cursor{position:absolute;margin-top:-4px;width:100%;border:4px s' + 48 | 'olid #fff;border-color:transparent #fff;box-sizing:border-box}.c' + 49 | 'p-alpha{clear:both;width:100%;height:16px;margin:6px 0;backgroun' + 50 | 'd:linear-gradient(to right,#444,rgba(0,0,0,0))}.cp-alpha-cursor{' + 51 | 'position:absolute;margin-left:-4px;height:100%;border:4px solid ' + 52 | '#fff;border-color:#fff transparent;box-sizing:border-box}', 53 | 54 | ColorPicker = function(options) { 55 | _color = this.color = new Colors(options); 56 | _options = _color.options; 57 | _colorPicker = this; 58 | }; 59 | 60 | ColorPicker.prototype = { 61 | render: preRender, 62 | toggle: toggle 63 | }; 64 | 65 | function extractValue(elm) { 66 | return elm.value || elm.getAttribute('value') || 67 | $(elm).css('background-color') || '#FFF'; 68 | } 69 | 70 | function resolveEventType(event) { 71 | event = event.originalEvent && event.originalEvent.touches ? 72 | event.originalEvent.touches[0] : event; 73 | 74 | return event.originalEvent ? event.originalEvent : event; 75 | } 76 | 77 | function findElement($elm) { 78 | return $($elm.find(_options.doRender)[0] || $elm[0]); 79 | } 80 | 81 | function toggle(event) { 82 | var $this = $(this), 83 | position = $this.offset(), 84 | $window = $(window), 85 | gap = _options.gap; 86 | 87 | if (event) { 88 | _$trigger = findElement($this); 89 | _$trigger._colorMode = _$trigger.data('colorMode'); 90 | 91 | _colorPicker.$trigger = $this; 92 | 93 | (_$UI || build()).css( 94 | _options.positionCallback.call(_colorPicker, $this) || 95 | {'left': (_$UI._left = position.left) - 96 | ((_$UI._left += _$UI._width - 97 | ($window.scrollLeft() + $window.width())) + gap > 0 ? 98 | _$UI._left + gap : 0), 99 | 'top': (_$UI._top = position.top + $this.outerHeight()) - 100 | ((_$UI._top += _$UI._height - 101 | ($window.scrollTop() + $window.height())) + gap > 0 ? 102 | _$UI._top + gap : 0) 103 | }).show(_options.animationSpeed, function() { 104 | if (event === true) { // resize, scroll 105 | return; 106 | } 107 | _$alpha.toggle(!!_options.opacity)._width = _$alpha.width(); 108 | _$xy_slider._width = _$xy_slider.width(); 109 | _$xy_slider._height = _$xy_slider.height(); 110 | _$z_slider._height = _$z_slider.height(); 111 | _color.setColor(extractValue(_$trigger[0])); 112 | 113 | preRender(true); 114 | }) 115 | .off('.tcp').on(_pointerdown, 116 | '.cp-xy-slider,.cp-z-slider,.cp-alpha', pointerdown); 117 | } else if (_colorPicker.$trigger) { 118 | $(_$UI).hide(_options.animationSpeed, function() { 119 | preRender(false); 120 | _colorPicker.$trigger = null; 121 | }).off('.tcp'); 122 | } 123 | } 124 | 125 | function build() { 126 | $('head')[_options.cssPrepend ? 'prepend' : 'append'] 127 | (''); 129 | 130 | return $(_html).css({'margin': _options.margin}) 131 | .appendTo('body') 132 | .show(0, function() { 133 | _colorPicker.$UI = _$UI = $(this); 134 | 135 | _GPU = _options.GPU && _$UI.css('perspective') !== undefined; 136 | _$z_slider = $('.cp-z-slider', this); 137 | _$xy_slider = $('.cp-xy-slider', this); 138 | _$xy_cursor = $('.cp-xy-cursor', this); 139 | _$z_cursor = $('.cp-z-cursor', this); 140 | _$alpha = $('.cp-alpha', this); 141 | _$alpha_cursor = $('.cp-alpha-cursor', this); 142 | _options.buildCallback.call(_colorPicker, _$UI); 143 | _$UI.prepend('
').children().eq(0).css('width', 144 | _$UI.children().eq(0).width()); // stabilizer 145 | _$UI._width = this.offsetWidth; 146 | _$UI._height = this.offsetHeight; 147 | }).hide(); 148 | } 149 | 150 | function pointerdown(e) { 151 | var action = this.className 152 | .replace(/cp-(.*?)(?:\s*|$)/, '$1').replace('-', '_'); 153 | 154 | if ((e.button || e.which) > 1) return; 155 | 156 | e.preventDefault && e.preventDefault(); 157 | e.returnValue = false; 158 | 159 | _$trigger._offset = $(this).offset(); 160 | 161 | (action = action === 'xy_slider' ? xy_slider : 162 | action === 'z_slider' ? z_slider : alpha)(e); 163 | preRender(); 164 | 165 | $document.on(_pointerup, function(e) { 166 | $document.off('.tcp'); 167 | }).on(_pointermove, function(e) { 168 | action(e); 169 | preRender(); 170 | }); 171 | } 172 | 173 | function xy_slider(event) { 174 | var e = resolveEventType(event), 175 | x = e.pageX - _$trigger._offset.left, 176 | y = e.pageY - _$trigger._offset.top; 177 | 178 | _color.setColor({ 179 | s: x / _$xy_slider._width * 100, 180 | v: 100 - (y / _$xy_slider._height * 100) 181 | }, 'hsv'); 182 | } 183 | 184 | function z_slider(event) { 185 | var z = resolveEventType(event).pageY - _$trigger._offset.top; 186 | 187 | _color.setColor({h: 360 - (z / _$z_slider._height * 360)}, 'hsv'); 188 | } 189 | 190 | function alpha(event) { 191 | var x = resolveEventType(event).pageX - _$trigger._offset.left, 192 | alpha = x / _$alpha._width; 193 | 194 | _color.setColor({}, 'rgb', alpha); 195 | } 196 | 197 | function preRender(toggled) { 198 | var colors = _color.colors, 199 | hueRGB = colors.hueRGB, 200 | RGB = colors.RND.rgb, 201 | HSL = colors.RND.hsl, 202 | dark = _options.dark, 203 | light = _options.light, 204 | colorText = _color.toString(_$trigger._colorMode, _options.forceAlpha), 205 | HUEContrast = colors.HUELuminance > 0.22 ? dark : light, 206 | alphaContrast = colors.rgbaMixBlack.luminance > 0.22 ? dark : light, 207 | h = (1 - colors.hsv.h) * _$z_slider._height, 208 | s = colors.hsv.s * _$xy_slider._width, 209 | v = (1 - colors.hsv.v) * _$xy_slider._height, 210 | a = colors.alpha * _$alpha._width, 211 | translate3d = _GPU ? 'translate3d' : '', 212 | triggerValue = _$trigger[0].value, 213 | hasNoValue = _$trigger[0].hasAttribute('value') && // question this 214 | triggerValue === '' && toggled !== undefined; 215 | 216 | _$xy_slider._css = { 217 | backgroundColor: 'rgb(' + 218 | hueRGB.r + ',' + hueRGB.g + ',' + hueRGB.b + ')'}; 219 | _$xy_cursor._css = { 220 | transform: translate3d + '(' + s + 'px, ' + v + 'px, 0)', 221 | left: !_GPU ? s : '', 222 | top: !_GPU ? v : '', 223 | borderColor : colors.RGBLuminance > 0.22 ? dark : light 224 | }; 225 | _$z_cursor._css = { 226 | transform: translate3d + '(0, ' + h + 'px, 0)', 227 | top: !_GPU ? h : '', 228 | borderColor : 'transparent ' + HUEContrast 229 | }; 230 | _$alpha._css = {backgroundColor: '#' + colors.HEX}; 231 | _$alpha_cursor._css = { 232 | transform: translate3d + '(' + a + 'px, 0, 0)', 233 | left: !_GPU ? a : '', 234 | borderColor : alphaContrast + ' transparent' 235 | }; 236 | _$trigger._css = { 237 | backgroundColor : hasNoValue ? '' : colorText, 238 | color: hasNoValue ? '' : 239 | colors.rgbaMixBGMixCustom.luminance > 0.22 ? dark : light 240 | }; 241 | _$trigger.text = hasNoValue ? '' : triggerValue !== colorText ? colorText : ''; 242 | 243 | toggled !== undefined ? render(toggled) : _animate(render); 244 | } 245 | 246 | // As _animate() is actually requestAnimationFrame(), render() gets called 247 | // decoupled from any pointer action (whenever the browser decides to do 248 | // so) as an event. preRender() is coupled to toggle() and all pointermove 249 | // actions; that's where all the calculations happen. render() can now be 250 | // called without extra calculations which results in faster rendering. 251 | function render(toggled) { 252 | _$xy_slider.css(_$xy_slider._css); 253 | _$xy_cursor.css(_$xy_cursor._css); 254 | _$z_cursor.css(_$z_cursor._css); 255 | _$alpha.css(_$alpha._css); 256 | _$alpha_cursor.css(_$alpha_cursor._css); 257 | 258 | _options.doRender && _$trigger.css(_$trigger._css); 259 | _$trigger.text && _$trigger.val(_$trigger.text); 260 | 261 | _options.renderCallback.call( 262 | _colorPicker, 263 | _$trigger, 264 | typeof toggled === 'boolean' ? toggled : undefined 265 | ); 266 | } 267 | 268 | $.fn.colorPicker = function(options) { 269 | var _this = this, 270 | noop = function(){}; 271 | 272 | options = $.extend({ 273 | animationSpeed: 150, 274 | GPU: true, 275 | doRender: true, 276 | customBG: '#FFF', 277 | opacity: true, 278 | renderCallback: noop, 279 | buildCallback: noop, 280 | positionCallback: noop, 281 | body: document.body, 282 | scrollResize: true, 283 | gap: 4, 284 | dark: '#222', 285 | light: '#DDD', 286 | // cssPrepend: true, 287 | // forceAlpha: undefined, 288 | // css: '', 289 | // cssAddon: '', 290 | // margin: '', 291 | // preventFocus: false 292 | }, options); 293 | 294 | !_colorPicker && options.scrollResize && $(window) 295 | .on('resize.tcp scroll.tcp', function() { 296 | if (_colorPicker.$trigger) { 297 | _colorPicker.toggle.call(_colorPicker.$trigger[0], true); 298 | } 299 | }); 300 | _instance = _instance.add(this); 301 | this.colorPicker = _colorPicker || new ColorPicker(options); 302 | this.options = options; 303 | 304 | $(options.body).off('.tcp').on(_pointerdown, function(e) { 305 | _instance.add(_$UI).add($(_$UI).find(e.target)). 306 | index(e.target) === -1 && toggle(); 307 | }); 308 | 309 | return this.on('focusin.tcp click.tcp', function(event) { 310 | _colorPicker.color.options = // swap options to fake new instance 311 | $.extend(_colorPicker.color.options, _options = _this.options); 312 | toggle.call(this, event); 313 | }) 314 | .on('change.tcp', function() { 315 | _color.setColor(this.value || '#FFF'); 316 | _this.colorPicker.render(true); 317 | }) 318 | .each(function() { 319 | var value = extractValue(this), 320 | mode = value.split('('), 321 | $elm = findElement($(this)); 322 | 323 | $elm.data('colorMode', mode[1] ? mode[0].substr(0, 3) : 'HEX') 324 | .attr('readonly', _options.preventFocus); 325 | options.doRender && 326 | $elm.css({'background-color': value, 327 | 'color': function() { 328 | return _color.setColor(value) 329 | .rgbaMixBGMixCustom.luminance > 0.22 ? 330 | options.dark : options.light 331 | } 332 | }); 333 | }); 334 | }; 335 | 336 | $.fn.colorPicker.destroy = function() { 337 | $('*').off('.tcp'); // slower but saver 338 | _colorPicker.toggle(false); 339 | _instance = $(); 340 | // destroy _colorPicker 341 | }; 342 | 343 | })); -------------------------------------------------------------------------------- /jqColorPicker.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"jqColorPicker.min.js","sources":["colors.js","jqColorPicker.js"],"names":["root","factory","exports","module","define","amd","Colors","this","window","undefined","setColor","colors","color","type","save","alpha","ColorConverter","txt2color","_colors","n","limitValue","_valueRanges","convertColors","saveAsBackground","RGB","rgb","grey","_instance","options","r","g","b","equivalentGrey","_round","rgbaMixBlack","mixColors","rgbaMixWhite","luminance","getLuminance","customBG","rgbaMixCustom","colorObj","modes","SAVE","SMART","convert","ranges","RND","mode","from","exceptions","hsl","typ","HEX","RGB2HEX","webSave","getClosestWebColor","webSmart","saveColor","hueRGB","hue2RGB","hsv","h","background","rgbaMixBGMixCustom","WCAG2Ratio","getWCAG2Ratio","luminanceDelta","_Math","abs","hueDelta","getHueDelta","RGBLuminance","HUELuminance","convertCallback","val","out","tmp","half","rgb1","rgb2","nominal","max","normalized","div","i","length","pow","topColor","bottomColor","topAlpha","bottomAlpha","newColor","alphaTop","alphaBottom","a","lum1","lum2","ratio","value","min","s","v","l","Math","round","valueRanges","initInstance","THIS","_options","focusInstance","option","prototype","newCol","setCustomBackground","col","toString","colorMode","forceAlpha","color2text","toLowerCase","txt","parts","replace","split","values","substr","m","charAt","HEX2rgb","hasAlpha","HSL","shouldBeHex","isHex","isRgb","innerText","toUpperCase","hue","mod","rgb2hsv","chroma","k","hsv2rgb","f","p","q","t","hsv2hsl","rgb2hsl","dependent","hsl2rgb","sv","sextant","fract","vsf","require","jQuery","$","extractValue","elm","getAttribute","css","resolveEventType","event","originalEvent","touches","findElement","$elm","find","doRender","toggle","$this","position","offset","$window","gap","_$trigger","_colorMode","data","_colorPicker","$trigger","_$UI","build","positionCallback","call","left","_left","_width","scrollLeft","width","top","_top","outerHeight","_height","scrollTop","height","show","animationSpeed","_$alpha","opacity","_$xy_slider","_$z_slider","_color","preRender","off","on","_pointerdown","pointerdown","hide","cssPrepend","_css","cssAddon","_html","margin","appendTo","$UI","_GPU","GPU","_$xy_cursor","_$z_cursor","_$alpha_cursor","buildCallback","prepend","children","eq","offsetWidth","offsetHeight","e","action","className","button","which","preventDefault","returnValue","_offset","xy_slider","z_slider","$document","_pointerup","_pointermove","x","pageX","y","pageY","z","toggled","dark","light","colorText","HUEContrast","alphaContrast","translate3d","triggerValue","hasNoValue","hasAttribute","backgroundColor","transform","borderColor","text","render","_animate","renderCallback","document","requestAnimationFrame","webkitRequestAnimationFrame","cb","ColorPicker","fn","colorPicker","_this","noop","extend","body","scrollResize","add","target","index","each","attr","preventFocus","background-color","destroy"],"mappings":"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"} -------------------------------------------------------------------------------- /jqColorPicker.min.js: -------------------------------------------------------------------------------- 1 | /*! tinyColorPicker - v1.1.1 2016-08-30 */ 2 | 3 | !function(a,b){"object"==typeof exports?module.exports=b(a):"function"==typeof define&&define.amd?define("colors",[],function(){return b(a)}):a.Colors=b(a)}(this,function(a,b){"use strict";function c(a,c,d,f,g){if("string"==typeof c){var c=v.txt2color(c);d=c.type,p[d]=c[d],g=g!==b?g:c.alpha}else if(c)for(var h in c)a[d][h]=k(c[h]/l[d][h][1],0,1);return g!==b&&(a.alpha=k(+g,0,1)),e(d,f?a:b)}function d(a,b,c){var d=o.options.grey,e={};return e.RGB={r:a.r,g:a.g,b:a.b},e.rgb={r:b.r,g:b.g,b:b.b},e.alpha=c,e.equivalentGrey=n(d.r*a.r+d.g*a.g+d.b*a.b),e.rgbaMixBlack=i(b,{r:0,g:0,b:0},c,1),e.rgbaMixWhite=i(b,{r:1,g:1,b:1},c,1),e.rgbaMixBlack.luminance=h(e.rgbaMixBlack,!0),e.rgbaMixWhite.luminance=h(e.rgbaMixWhite,!0),o.options.customBG&&(e.rgbaMixCustom=i(b,o.options.customBG,c,1),e.rgbaMixCustom.luminance=h(e.rgbaMixCustom,!0),o.options.customBG.luminance=h(o.options.customBG,!0)),e}function e(a,b){var c,e,k,q=b||p,r=v,s=o.options,t=l,u=q.RND,w="",x="",y={hsl:"hsv",rgb:a},z=u.rgb;if("alpha"!==a){for(var A in t)if(!t[A][A]){a!==A&&(x=y[A]||"rgb",q[A]=r[x+"2"+A](q[x])),u[A]||(u[A]={}),c=q[A];for(w in c)u[A][w]=n(c[w]*t[A][w][1])}z=u.rgb,q.HEX=r.RGB2HEX(z),q.equivalentGrey=s.grey.r*q.rgb.r+s.grey.g*q.rgb.g+s.grey.b*q.rgb.b,q.webSave=e=f(z,51),q.webSmart=k=f(z,17),q.saveColor=z.r===e.r&&z.g===e.g&&z.b===e.b?"web save":z.r===k.r&&z.g===k.g&&z.b===k.b?"web smart":"",q.hueRGB=v.hue2RGB(q.hsv.h),b&&(q.background=d(z,q.rgb,q.alpha))}var B,C,D,E=q.rgb,F=q.alpha,G="luminance",H=q.background;return B=i(E,{r:0,g:0,b:0},F,1),B[G]=h(B,!0),q.rgbaMixBlack=B,C=i(E,{r:1,g:1,b:1},F,1),C[G]=h(C,!0),q.rgbaMixWhite=C,s.customBG&&(D=i(E,H.rgbaMixCustom,F,1),D[G]=h(D,!0),D.WCAG2Ratio=j(D[G],H.rgbaMixCustom[G]),q.rgbaMixBGMixCustom=D,D.luminanceDelta=m.abs(D[G]-H.rgbaMixCustom[G]),D.hueDelta=g(H.rgbaMixCustom,D,!0)),q.RGBLuminance=h(z),q.HUELuminance=h(q.hueRGB),s.convertCallback&&s.convertCallback(q,a),q}function f(a,b){var c={},d=0,e=b/2;for(var f in a)d=a[f]%b,c[f]=a[f]+(d>e?b-d:-d);return c}function g(a,b,c){return(m.max(a.r-b.r,b.r-a.r)+m.max(a.g-b.g,b.g-a.g)+m.max(a.b-b.b,b.b-a.b))*(c?255:1)/765}function h(a,b){for(var c=b?1:255,d=[a.r/c,a.g/c,a.b/c],e=o.options.luminance,f=d.length;f--;)d[f]=d[f]<=.03928?d[f]/12.92:m.pow((d[f]+.055)/1.055,2.4);return e.r*d[0]+e.g*d[1]+e.b*d[2]}function i(a,c,d,e){var f={},g=d!==b?d:1,h=e!==b?e:1,i=g+h*(1-g);for(var j in a)f[j]=(a[j]*g+c[j]*h*(1-g))/i;return f.a=i,f}function j(a,b){var c=1;return c=a>=b?(a+.05)/(b+.05):(b+.05)/(a+.05),n(100*c)/100}function k(a,b,c){return a>c?c:b>a?b:a}var l={rgb:{r:[0,255],g:[0,255],b:[0,255]},hsv:{h:[0,360],s:[0,100],v:[0,100]},hsl:{h:[0,360],s:[0,100],l:[0,100]},alpha:{alpha:[0,1]},HEX:{HEX:[0,16777215]}},m=a.Math,n=m.round,o={},p={},q={r:.298954,g:.586434,b:.114612},r={r:.2126,g:.7152,b:.0722},s=function(a){this.colors={RND:{}},this.options={color:"rgba(0,0,0,0)",grey:q,luminance:r,valueRanges:l},t(this,a||{})},t=function(a,d){var e,f=a.options;u(a);for(var g in d)d[g]!==b&&(f[g]=d[g]);e=f.customBG,f.customBG="string"==typeof e?v.txt2color(e).rgb:e,p=c(a.colors,f.color,b,!0)},u=function(a){o!==a&&(o=a,p=a.colors)};s.prototype.setColor=function(a,d,f){return u(this),a?c(this.colors,a,d,b,f):(f!==b&&(this.colors.alpha=k(f,0,1)),e(d))},s.prototype.setCustomBackground=function(a){return u(this),this.options.customBG="string"==typeof a?v.txt2color(a).rgb:a,c(this.colors,b,"rgb")},s.prototype.saveAsBackground=function(){return u(this),c(this.colors,b,"rgb",!0)},s.prototype.toString=function(a,b){return v.color2text((a||"rgb").toLowerCase(),this.colors,b)};var v={txt2color:function(a){var b={},c=a.replace(/(?:#|\)|%)/g,"").split("("),d=(c[1]||"").split(/,\s*/),e=c[1]?c[0].substr(0,3):"rgb",f="";if(b.type=e,b[e]={},c[1])for(var g=3;g--;)f=e[g]||e.charAt(g),b[e][f]=+d[g]/l[e][f][1];else b.rgb=v.HEX2rgb(c[0]);return b.alpha=d[3]?+d[3]:1,b},color2text:function(a,b,c){var d=c!==!1&&n(100*b.alpha)/100,e="number"==typeof d&&c!==!1&&(c||1!==d),f=b.RND.rgb,g=b.RND.hsl,h="hex"===a&&e,i="hex"===a&&!h,j="rgb"===a||h,k=j?f.r+", "+f.g+", "+f.b:i?"#"+b.HEX:g.h+", "+g.s+"%, "+g.l+"%";return i?k:(h?"rgb":a)+(e?"a":"")+"("+k+(e?", "+d:"")+")"},RGB2HEX:function(a){return((a.r<16?"0":"")+a.r.toString(16)+(a.g<16?"0":"")+a.g.toString(16)+(a.b<16?"0":"")+a.b.toString(16)).toUpperCase()},HEX2rgb:function(a){return a=a.split(""),{r:+("0x"+a[0]+a[a[3]?1:0])/255,g:+("0x"+a[a[3]?2:1]+(a[3]||a[1]))/255,b:+("0x"+(a[4]||a[2])+(a[5]||a[2]))/255}},hue2RGB:function(a){var b=6*a,c=~~b%6,d=6===b?0:b-c;return{r:n(255*[1,1-d,0,0,d,1][c]),g:n(255*[d,1,1,1-d,0,0][c]),b:n(255*[0,0,d,1,1,1-d][c])}},rgb2hsv:function(a){var b,c,d,e=a.r,f=a.g,g=a.b,h=0;return g>f&&(f=g+(g=f,0),h=-1),c=g,f>e&&(e=f+(f=e,0),h=-2/6-h,c=m.min(f,g)),b=e-c,d=e?b/e:0,{h:1e-15>d?p&&p.hsl&&p.hsl.h||0:b?m.abs(h+(f-g)/(6*b)):0,s:e?b/e:p&&p.hsv&&p.hsv.s||0,v:e}},hsv2rgb:function(a){var b=6*a.h,c=a.s,d=a.v,e=~~b,f=b-e,g=d*(1-c),h=d*(1-f*c),i=d*(1-(1-f)*c),j=e%6;return{r:[d,h,g,g,i,d][j],g:[i,d,d,h,g,g][j],b:[g,g,i,d,d,h][j]}},hsv2hsl:function(a){var b=(2-a.s)*a.v,c=a.s*a.v;return c=a.s?1>b?b?c/b:0:c/(2-b):0,{h:a.h,s:a.v||c?c:p&&p.hsl&&p.hsl.s||0,l:b/2}},rgb2hsl:function(a,b){var c=v.rgb2hsv(a);return v.hsv2hsl(b?c:p.hsv=c)},hsl2rgb:function(a){var b=6*a.h,c=a.s,d=a.l,e=.5>d?d*(1+c):d+c-c*d,f=d+d-e,g=e?(e-f)/e:0,h=~~b,i=b-h,j=e*g*i,k=f+j,l=e-j,m=h%6;return{r:[e,l,f,f,k,e][m],g:[k,e,e,l,f,f][m],b:[f,f,k,e,e,l][m]}}};return s}),function(a,b){"object"==typeof exports?module.exports=b(a,require("jquery"),require("colors")):"function"==typeof define&&define.amd?define(["jquery","colors"],function(c,d){return b(a,c,d)}):b(a,a.jQuery,a.Colors)}(this,function(a,b,c,d){"use strict";function e(a){return a.value||a.getAttribute("value")||b(a).css("background-color")||"#FFF"}function f(a){return a=a.originalEvent&&a.originalEvent.touches?a.originalEvent.touches[0]:a,a.originalEvent?a.originalEvent:a}function g(a){return b(a.find(r.doRender)[0]||a[0])}function h(c){var d=b(this),f=d.offset(),h=b(a),k=r.gap;c?(s=g(d),s._colorMode=s.data("colorMode"),p.$trigger=d,(t||i()).css(r.positionCallback.call(p,d)||{left:(t._left=f.left)-((t._left+=t._width-(h.scrollLeft()+h.width()))+k>0?t._left+k:0),top:(t._top=f.top+d.outerHeight())-((t._top+=t._height-(h.scrollTop()+h.height()))+k>0?t._top+k:0)}).show(r.animationSpeed,function(){c!==!0&&(y.toggle(!!r.opacity)._width=y.width(),v._width=v.width(),v._height=v.height(),u._height=u.height(),q.setColor(e(s[0])),n(!0))}).off(".tcp").on(D,".cp-xy-slider,.cp-z-slider,.cp-alpha",j)):p.$trigger&&b(t).hide(r.animationSpeed,function(){n(!1),p.$trigger=null}).off(".tcp")}function i(){return b("head")[r.cssPrepend?"prepend":"append"]('"),b(H).css({margin:r.margin}).appendTo("body").show(0,function(){p.$UI=t=b(this),F=r.GPU&&t.css("perspective")!==d,u=b(".cp-z-slider",this),v=b(".cp-xy-slider",this),w=b(".cp-xy-cursor",this),x=b(".cp-z-cursor",this),y=b(".cp-alpha",this),z=b(".cp-alpha-cursor",this),r.buildCallback.call(p,t),t.prepend("
").children().eq(0).css("width",t.children().eq(0).width()),t._width=this.offsetWidth,t._height=this.offsetHeight}).hide()}function j(a){var c=this.className.replace(/cp-(.*?)(?:\s*|$)/,"$1").replace("-","_");(a.button||a.which)>1||(a.preventDefault&&a.preventDefault(),a.returnValue=!1,s._offset=b(this).offset(),(c="xy_slider"===c?k:"z_slider"===c?l:m)(a),n(),A.on(E,function(){A.off(".tcp")}).on(C,function(a){c(a),n()}))}function k(a){var b=f(a),c=b.pageX-s._offset.left,d=b.pageY-s._offset.top;q.setColor({s:c/v._width*100,v:100-d/v._height*100},"hsv")}function l(a){var b=f(a).pageY-s._offset.top;q.setColor({h:360-b/u._height*360},"hsv")}function m(a){var b=f(a).pageX-s._offset.left,c=b/y._width;q.setColor({},"rgb",c)}function n(a){var b=q.colors,c=b.hueRGB,e=(b.RND.rgb,b.RND.hsl,r.dark),f=r.light,g=q.toString(s._colorMode,r.forceAlpha),h=b.HUELuminance>.22?e:f,i=b.rgbaMixBlack.luminance>.22?e:f,j=(1-b.hsv.h)*u._height,k=b.hsv.s*v._width,l=(1-b.hsv.v)*v._height,m=b.alpha*y._width,n=F?"translate3d":"",p=s[0].value,t=s[0].hasAttribute("value")&&""===p&&a!==d;v._css={backgroundColor:"rgb("+c.r+","+c.g+","+c.b+")"},w._css={transform:n+"("+k+"px, "+l+"px, 0)",left:F?"":k,top:F?"":l,borderColor:b.RGBLuminance>.22?e:f},x._css={transform:n+"(0, "+j+"px, 0)",top:F?"":j,borderColor:"transparent "+h},y._css={backgroundColor:"#"+b.HEX},z._css={transform:n+"("+m+"px, 0, 0)",left:F?"":m,borderColor:i+" transparent"},s._css={backgroundColor:t?"":g,color:t?"":b.rgbaMixBGMixCustom.luminance>.22?e:f},s.text=t?"":p!==g?g:"",a!==d?o(a):G(o)}function o(a){v.css(v._css),w.css(w._css),x.css(x._css),y.css(y._css),z.css(z._css),r.doRender&&s.css(s._css),s.text&&s.val(s.text),r.renderCallback.call(p,s,"boolean"==typeof a?a:d)}var p,q,r,s,t,u,v,w,x,y,z,A=b(document),B=b(),C="touchmove.tcp mousemove.tcp pointermove.tcp",D="touchstart.tcp mousedown.tcp pointerdown.tcp",E="touchend.tcp mouseup.tcp pointerup.tcp",F=!1,G=a.requestAnimationFrame||a.webkitRequestAnimationFrame||function(a){a()},H='
',I=".cp-color-picker{position:absolute;overflow:hidden;padding:6px 6px 0;background-color:#444;color:#bbb;font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:400;cursor:default;border-radius:5px}.cp-color-picker>div{position:relative;overflow:hidden}.cp-xy-slider{float:left;height:128px;width:128px;margin-bottom:6px;background:linear-gradient(to right,#FFF,rgba(255,255,255,0))}.cp-white{height:100%;width:100%;background:linear-gradient(rgba(0,0,0,0),#000)}.cp-xy-cursor{position:absolute;top:0;width:10px;height:10px;margin:-5px;border:1px solid #fff;border-radius:100%;box-sizing:border-box}.cp-z-slider{float:right;margin-left:6px;height:128px;width:20px;background:linear-gradient(red 0,#f0f 17%,#00f 33%,#0ff 50%,#0f0 67%,#ff0 83%,red 100%)}.cp-z-cursor{position:absolute;margin-top:-4px;width:100%;border:4px solid #fff;border-color:transparent #fff;box-sizing:border-box}.cp-alpha{clear:both;width:100%;height:16px;margin:6px 0;background:linear-gradient(to right,#444,rgba(0,0,0,0))}.cp-alpha-cursor{position:absolute;margin-left:-4px;height:100%;border:4px solid #fff;border-color:#fff transparent;box-sizing:border-box}",J=function(a){q=this.color=new c(a),r=q.options,p=this};J.prototype={render:n,toggle:h},b.fn.colorPicker=function(c){var d=this,f=function(){};return c=b.extend({animationSpeed:150,GPU:!0,doRender:!0,customBG:"#FFF",opacity:!0,renderCallback:f,buildCallback:f,positionCallback:f,body:document.body,scrollResize:!0,gap:4,dark:"#222",light:"#DDD"},c),!p&&c.scrollResize&&b(a).on("resize.tcp scroll.tcp",function(){p.$trigger&&p.toggle.call(p.$trigger[0],!0)}),B=B.add(this),this.colorPicker=p||new J(c),this.options=c,b(c.body).off(".tcp").on(D,function(a){-1===B.add(t).add(b(t).find(a.target)).index(a.target)&&h()}),this.on("focusin.tcp click.tcp",function(a){p.color.options=b.extend(p.color.options,r=d.options),h.call(this,a)}).on("change.tcp",function(){q.setColor(this.value||"#FFF"),d.colorPicker.render(!0)}).each(function(){var a=e(this),d=a.split("("),f=g(b(this));f.data("colorMode",d[1]?d[0].substr(0,3):"HEX").attr("readonly",r.preventFocus),c.doRender&&f.css({"background-color":a,color:function(){return q.setColor(a).rgbaMixBGMixCustom.luminance>.22?c.dark:c.light}})})},b.fn.colorPicker.destroy=function(){b("*").off(".tcp"),p.toggle(!1),B=b()}}); 4 | //# sourceMappingURL=jqColorPicker.js.map -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tinyColorPicker", 3 | "version": "1.1.1", 4 | "repository": { 5 | "type": "git", 6 | "url": "http://github.com/PitPik/tinyColorPicker.git" 7 | }, 8 | "devDependencies": { 9 | "grunt": "^0.4.5", 10 | "grunt-contrib-uglify": "^0.5.1", 11 | "grunt-smushit": "^1.3.0" 12 | } 13 | } 14 | --------------------------------------------------------------------------------