├── .gitignore ├── bower.json ├── package.json ├── LISCENSE-MIT ├── gulpfile.js ├── Please_docs.txt ├── README.md ├── dist └── Please.js └── src └── Please.js /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | node_modules 3 | testing -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pleasejs", 3 | "version": "0.4.2", 4 | "homepage": "https://github.com/Fooidge/PleaseJS", 5 | "authors": [ 6 | "Fooidge" 7 | ], 8 | "description": "JS library to generate random pleasing colors/color schemes", 9 | "main": "dist/Please.js", 10 | "keywords": [ 11 | "color", 12 | "scheme", 13 | "random" 14 | ], 15 | "license": "MIT", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pleasejs", 3 | "version": "0.4.2", 4 | "description": "JS library to generate random pleasing colors/color schemes", 5 | "main": "./dist/Please.js", 6 | "scripts": { 7 | "test": "Please.make_color();" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/Fooidge/PleaseJS.git" 12 | }, 13 | "keywords": [ 14 | "color", 15 | "scheme", 16 | "random" 17 | ], 18 | "author": "Jordan Checkman", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/Fooidge/PleaseJS/issues" 22 | }, 23 | "homepage": "https://github.com/Fooidge/PleaseJS", 24 | "devDependencies": { 25 | "gulp": "^3.8.9", 26 | "gulp-bump": "^0.1.11", 27 | "gulp-jshint": "^1.7.1", 28 | "gulp-uglify": "^0.3.2", 29 | "gulp-watch": "^0.6.10", 30 | "jshint-stylish": "^0.4.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LISCENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright © 2014 Jordan Checkman 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | jshint = require('gulp-jshint'), 3 | uglify = require('gulp-uglify'), 4 | watch = require('gulp-watch'), 5 | bump = require('gulp-bump'); 6 | 7 | gulp.task('uglify', function(){ 8 | gulp.src('src/Please.js') 9 | .pipe(uglify({ 10 | preserveComments: 'some', 11 | })) 12 | .pipe(gulp.dest('dist')); 13 | }); 14 | gulp.task('lint', function(){ 15 | return gulp.src('src/Please.js') 16 | .pipe(jshint()) 17 | .pipe(jshint.reporter('jshint-stylish')); 18 | }); 19 | gulp.task('bump-major', function(){ 20 | gulp.src(['./bower.json', './component.json', './package.json']) 21 | .pipe(bump({type:'major'})) 22 | .pipe(gulp.dest('./')); 23 | }); 24 | gulp.task('bump-minor', function(){ 25 | gulp.src(['./bower.json', './component.json', './package.json']) 26 | .pipe(bump({type:'minor'})) 27 | .pipe(gulp.dest('./')); 28 | }); 29 | gulp.task('bump-patch', function(){ 30 | gulp.src(['./bower.json', './component.json', './package.json']) 31 | .pipe(bump({type:'patch'})) 32 | .pipe(gulp.dest('./')); 33 | }); 34 | /* 35 | gulp.task('watch', function(){ 36 | gulp.watch('Please.js',['uglify']); 37 | }); 38 | */ 39 | gulp.task('default', [], function(){ 40 | gulp.start('uglify'); 41 | gulp.start('lint'); 42 | }); -------------------------------------------------------------------------------- /Please_docs.txt: -------------------------------------------------------------------------------- 1 | Please.js 2 | Jordan Checkman 3 | Checkman.io 4 | 5 | Please.js is a polite companion that wants to help you make your projects beautiful. It uses HSV color space to create random pleasing colors as well as color schemes based on a given color. 6 | 7 | It has two core functions and a bunch of little helpers for you to use. 8 | 9 | -----CORE----- 10 | Please.make_color(options) 11 | 12 | The make_color function by default will generate and return a random hex string using the golden ratio to ensure that the color will look nice on your screen. 13 | 14 | You can also pass an options object to make_color and have it do a whole bunch of different things. 15 | 16 | make_color options: 17 | 18 | hue: (0-360) 19 | By setting the hue, you determine the color. 20 | 21 | saturation: (0.0-1.0) 22 | By setting the saturation, you determine the distance from gray. 23 | 24 | value: (0.0-1.0) 25 | By setting the value, you determine the balance between black and white. 26 | 27 | base_color: ("the name of an HTML color") 28 | Setting a base_color (e.g. "pink") will create a random color within the HSV range of the chosen color. Please will recognize any of the 146 standard HTML colors, it has a very good memory. 29 | 30 | greyscale | grayscale: (true/false) 31 | Setting either greyscale or grayscale (but we all know which one is correct) to true will cause all of the colors you generate to be within the grey or gray range. This is effectively the same as setting your saturation to 0. 32 | 33 | golden: (true/false) 34 | Setting golden to true randomizes your hue (overrides hue setting) and makes you a spectacular color based on the golden ratio. It's so good, it's the default. Make sure to turn it off if you want to have more control over your generated colors. 35 | 36 | full_random: (true/false) 37 | Setting full_random to true will make Please lose its mind. It will completely randomize the hue, saturation, and value of the colors it makes. 38 | 39 | colors_returned: (1-infinity) 40 | Setting colors_returned to higher than 1 will return an array full of the colors Please has made for you. If you set it to 1, you'll just get the one color! It makes a sort of sense if you think about it. 41 | 42 | format: ("format string") 43 | Setting format string, will change the format of what make_color will return for you. The options are as follows (example is the color black): 44 | "hex" = "#000000" 45 | "rgb" = {r: 0, g: 0, b: 0} 46 | "rgb-string" = "rgb(0,0,0)" 47 | "hsv" = {h: 0, s: 0, v: 0} 48 | 49 | Here are the defaults for each option: 50 | { 51 | hue: null, 52 | saturation: null, 53 | value: null, 54 | base_color: '', 55 | greyscale: false, 56 | grayscale: false, 57 | golden: true, 58 | full_random: false, 59 | colors_returned: 1, 60 | format: 'hex' 61 | } 62 | 63 | Here is an example of a fully random color call: 64 | Please.make_color({ 65 | golden: false, 66 | full_random:true 67 | }); 68 | 69 | Here is an example that will produce 100 reds as RGB strings: 70 | Please.make_color({ 71 | golden: false, 72 | base_color: 'red', 73 | colors_returned: 100, 74 | format: 'rgb-string' 75 | }); 76 | 77 | -------------- 78 | 79 | The second core function allows Please to make a color scheme for you. 80 | 81 | Please.make_scheme(base_color, options) 82 | 83 | The make scheme function will return a series of colors based upon the color and options you feed it. The base_color must be in HSV color space and is an object in the format of 84 | { 85 | h: ___, 86 | s: ___, 87 | v: ___ 88 | } 89 | 90 | make_scheme options: 91 | 92 | scheme_type 93 | "monochromatic" | "mono" - Makes a 5 color scheme using your provided color, all the colors will be fairly similar to each other. 94 | 95 | "complementary" | "complement" - Makes a two color scheme using your provided color, the 2nd color will be the complement of the 1st, such that mixing them will create a neutral grey. 96 | 97 | "split-complementary" | "split-complement" | "split" - Makes a three color scheme where the 2nd and 3rd colors are at a 30 degree split from the complement of the 1st color. 98 | 99 | "double-complementary" | "double-complement" | "double" - Makes a four color scheme where the 2nd color is the complement of the 1st, and the 3rd and 4th colors are complements of each other at a 30 degree ofset from the first pair 100 | 101 | "analogous" | "ana" - Makes a six color scheme where each additional color is offset from the 1st by 20 degrees. 102 | 103 | "triadic" | "triad" | "tri" - Makes a 3 color scheme where the 2nd and 3rd color are equally spaced from the 1st. 104 | 105 | format: ("format string") 106 | Setting format string, will change the format of what make scheme will return for you. The options are as follows (example is the color white): 107 | "hex" = "#ffffff" 108 | "rgb" = {r: 255, g: 255,b: 255} 109 | "rgb-string" = "rgb(255,255,255)" 110 | "hsv" = {h: 0, s: 0, v: 1} 111 | 112 | Here is an example of a complementary scheme in hex: 113 | Please.make_scheme( 114 | { 115 | h: 130, 116 | s: .7, 117 | v: .75 118 | }, 119 | { 120 | scheme_type: "complement", 121 | format: "hex" 122 | }); 123 | 124 | Here is an example that will produce a triadic scheme in rgb-strings: 125 | Please.make_scheme( 126 | { 127 | h: 130, 128 | s: .7, 129 | v: .75 130 | }, 131 | { 132 | scheme_type: "triadic", 133 | format: "rgb-string" 134 | }); 135 | 136 | Here are the defaults for each option: 137 | { 138 | scheme_type: 'analogous', 139 | format: 'hex' 140 | } 141 | 142 | -----BONUS----- 143 | 144 | Please also has some bonus features, it allows you to convert freely between the color formats of RGB, HSV, and HEX. 145 | 146 | RGB_to_HEX() 147 | HEX_to_RGB() 148 | RGB_to_HSV() 149 | HSV_to_RGB() 150 | HEX_to_HSV() 151 | HSV_to_HEX() 152 | 153 | conversion from HSV or RGB expect an object with the properties 154 | { 155 | r: 0-255, 156 | g: 0-255, 157 | b: 0-255 158 | } 159 | and 160 | { 161 | h: 0-360, 162 | s: 0.0-1.0, 163 | v: 0,0-1.0 164 | } 165 | respectively, while converstions from HEX expect a string. Return formats are modeled the same way as the arguments. 166 | 167 | In addition Please, can convert from an HTML color name into HEX, RGB, or HSV. 168 | 169 | NAME_to_HEX() 170 | NAME_to_RGB() 171 | NAME_to_HSV() 172 | 173 | These functions take a string and return a HEX string or an RGB/HSV object. 174 | 175 | I hope you enjoy using Please. Have fun, and remember to say the magic word. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #PleaseJS 2 | 3 | www.checkman.io/please 4 | 5 | Please.js is a polite companion that wants to help you make your projects beautiful. It uses HSV color space to create random pleasing colors as well as color schemes based on a given color. 6 | It has two core functions and a bunch of little helpers for you to use. 7 | 8 | 9 | ```js 10 | Please.make_color(); 11 | //or 12 | Please.make_scheme( 13 | { 14 | h: 145, 15 | s: .7, 16 | v: .6 17 | }, 18 | { 19 | scheme_type: 'triadic', 20 | format: 'rgb-string' 21 | }); 22 | ``` 23 | 24 | ##Core 25 | 26 | ### make_color 27 | 28 | ```js 29 | Please.make_color({options}) 30 | ``` 31 | 32 | The make_color function by default will generate and return a random hex string using the golden ratio to ensure that the color will look nice on your screen. 33 | 34 | You can also pass an options object to make_color and have it do a whole bunch of different things. 35 | 36 | #### make_color options: 37 | 38 | * **hue**: `(0-360)` By setting the hue, you determine the color. 39 | * **saturation**: `(0.0-1.0)` By setting the saturation, you determine the distance from gray. 40 | * **value**: `(0.0-1.0)` By setting the value, you determine the balance between black and white. 41 | * **base_color**: `('the name of an HTML color')` Setting a base_color (e.g. 'pink') will create a random color within the HSV range of the chosen color. Please will recognize any of the 146 standard HTML colors, it has a very good memory. 42 | * **greyscale** | **grayscale**: `(true/false)` Setting either greyscale or grayscale (but we all know which one is correct) to true will cause all of the colors you generate to be within the grey or gray range. This is effectively the same as setting your saturation to 0. 43 | * **golden**: `(true/false)` Setting golden to true randomizes your hue (overrides hue setting) and makes you a spectacular color based on the golden ratio. It's so good, it's the default. Make sure to turn it off if you want to have more control over your generated colors. 44 | * **full_random**: `(true/false)` Setting full_random to true will make Please lose its mind. It will completely randomize the hue, saturation, and value of the colors it makes. 45 | * **colors_returned**: `(1-infinity)` Setting colors_returned to higher than 1 will return an array full of the colors Please has made for you. If you set it to 1, you'll just get the one color! It makes a sort of sense if you think about it. 46 | * **format**: `('format string')` Setting format string, will change the format of what make_color will return for you. The options are as follows (example is the color black): 47 | * `'hex'` = '#000000' 48 | * `'rgb'` = {r: 0, g: 0,b: 0} 49 | * `'rgb-string'` = 'rgb(0,0,0)' 50 | * `'hsv'` = {h: 0, s: 0, v: 0} 51 | 52 | Here are the defaults for each option: 53 | ```js 54 | { 55 | hue: null, 56 | saturation: null, 57 | value: null, 58 | base_color: '', 59 | greyscale: false, 60 | grayscale: false, 61 | golden: true, 62 | full_random: false, 63 | colors_returned: 1, 64 | format: 'hex', 65 | } 66 | ``` 67 | 68 | Here is an example of a fully random color call: 69 | ```js 70 | Please.make_color({ 71 | golden: false, 72 | full_random: true 73 | }); 74 | ``` 75 | 76 | Here is an example that will produce 100 reds as RGB strings: 77 | ```js 78 | Please.make_color({ 79 | golden: false, 80 | base_color: 'red', 81 | colors_returned: 100, 82 | format: 'rgb-string' 83 | }); 84 | ``` 85 | 86 | -------------- 87 | 88 | ### make_scheme 89 | 90 | The second core function allows Please to make a color scheme for you. 91 | 92 | ```js 93 | Please.make_scheme(base_color,{options}) 94 | ``` 95 | 96 | The make scheme function will return a series of colors based upon the color and options you feed it. The base_color must be in HSV color space and is an object in the format of 97 | ```js 98 | { 99 | h: ___, 100 | s: ___, 101 | v: ___ 102 | } 103 | ``` 104 | 105 | #### make_scheme options: 106 | 107 | * **scheme_type** 108 | * `'monochromatic'` | `'mono'` - Makes a 5 color scheme using your provided color, all the colors will be fairly similar to each other. 109 | * `'complementary'` | `'complement'` - Makes a two color scheme using your provided color, the 2nd color will be the complement of the 1st, such that mixing them will create a neutral grey. 110 | * `'split-complementary'` | `'split-complement'` | `'split'` - Makes a three color scheme where the 2nd and 3rd colors are at a 30 degree split from the complement of the 1st color. 111 | * `'double-complementary'` | `'double-complement'` | `'double'` - Makes a four color scheme where the 2nd color is the complement of the 1st, and the 3rd and 4th colors are complements of each other at a 30 degree ofset from the first pair 112 | * `'analogous'` | `'ana'` - Makes a six color scheme where each additional color is offset from the 1st by 20 degrees. 113 | * `'triadic'` | `'triad'` | `'tri'` - Makes a 3 color scheme where the 2nd and 3rd color are equally spaced from the 1st. 114 | * **format**: `('format string')` Setting format string, will change the format of what make scheme will return for you. The options are as follows (example is the color white): 115 | * `'hex'` = '#ffffff' 116 | * `'rgb'` = {r: 255, g: 255,b: 255} 117 | * `'rgb-string'` = 'rgb(255,255,255)' 118 | * `'hsv'` = {h: 0, s: 0, v: 1} 119 | 120 | Here is an example of a complementary scheme in hex: 121 | ```js 122 | Please.make_scheme( 123 | { 124 | h: 130, 125 | s: .7. 126 | v: .75 127 | }, 128 | { 129 | scheme_type: 'complement', 130 | format: 'hex' 131 | }); 132 | ``` 133 | 134 | Here is an example that will produce a triadic scheme in rgb-strings: 135 | ```js 136 | Please.make_scheme( 137 | { 138 | h: 130, 139 | s: .7. 140 | v: .75 141 | }, 142 | { 143 | scheme_type: 'triadic', 144 | format: 'rgb-string' 145 | }); 146 | ``` 147 | 148 | Here are the defaults for each option: 149 | ```js 150 | { 151 | scheme_type: 'analogous', 152 | format: 'hex' 153 | } 154 | ``` 155 | 156 | -------------- 157 | 158 | ## Other Methods 159 | 160 | Please also has some bonus features. It allows you to convert freely between the color formats of RGB, HSV, and HEX. 161 | 162 | RGB_to_HEX() 163 | HEX_to_RGB() 164 | RGB_to_HSV() 165 | HSV_to_RGB() 166 | HEX_to_HSV() 167 | HSV_to_HEX() 168 | 169 | conversion from HSV or RGB expect an object with the properties 170 | ```js 171 | { 172 | r: 0-255, 173 | g: 0-255, 174 | b: 0-255 175 | } 176 | ``` 177 | and 178 | ```js 179 | { 180 | h: 0-360, 181 | s: 0.0-1.0, 182 | v: 0,0-1.0 183 | } 184 | ``` 185 | 186 | respectively, while converstions from HEX expect a string. Return formats are modeled the same way as the arguments. 187 | 188 | In addition Please, can convert from an HTML color name into HEX, RGB, or HSV. 189 | 190 | ```js 191 | NAME_to_HEX() 192 | NAME_to_RGB() 193 | NAME_to_HSV() 194 | ``` 195 | 196 | These functions take a string and return a HEX string or an RGB/HSV object. 197 | 198 | I hope you enjoy using Please. Have fun, and remember to say the magic word. 199 | 200 | -------------- 201 | 202 | ## License 203 | 204 | MIT 205 | -------------------------------------------------------------------------------- /dist/Please.js: -------------------------------------------------------------------------------- 1 | /*!Please JS v0.4.2, Jordan Checkman 2014, Checkman.io, MIT License, Have fun.*/ 2 | !function(e,r,a){"function"==typeof define&&define.amd?define([],a):"object"==typeof exports?module.exports=a():r[e]=a()}("Please",this,function(){"use strict";function e(){function e(e,r,a){var o=Math.random;return a instanceof l&&(o=a.random),Math.floor(o()*(r-e+1))+e}function r(e,r,a){var o=Math.random;return a instanceof l&&(o=a.random),o()*(r-e)+e}function a(e,r,a){return Math.max(r,Math.min(e,a))}function o(e,r){var a;switch(e){case"hex":for(a=0;a=128?"dark":"light"}function t(e){var r={};for(var a in e)e.hasOwnProperty(a)&&(r[a]=e[a]);return r}function l(e){function r(){o=(o+1)%256,n=(n+a[o])%256;var e=a[o];return a[o]=a[n],a[n]=e,a[(a[o]+a[n])%256]}for(var a=[],o=0,n=0,t=0;256>t;t++)a[t]=t;for(var l=0,F=0;256>l;l++){F=(F+a[l]+e.charCodeAt(l%e.length))%256;var s=a[l];a[l]=a[F],a[F]=s}this.random=function(){for(var e=0,a=0,o=1;8>e;e++)a+=r()*o,o*=256;return a/0x10000000000000000}}var F={},s={aliceblue:"F0F8FF",antiquewhite:"FAEBD7",aqua:"00FFFF",aquamarine:"7FFFD4",azure:"F0FFFF",beige:"F5F5DC",bisque:"FFE4C4",black:"000000",blanchedalmond:"FFEBCD",blue:"0000FF",blueviolet:"8A2BE2",brown:"A52A2A",burlywood:"DEB887",cadetblue:"5F9EA0",chartreuse:"7FFF00",chocolate:"D2691E",coral:"FF7F50",cornflowerblue:"6495ED",cornsilk:"FFF8DC",crimson:"DC143C",cyan:"00FFFF",darkblue:"00008B",darkcyan:"008B8B",darkgoldenrod:"B8860B",darkgray:"A9A9A9",darkgrey:"A9A9A9",darkgreen:"006400",darkkhaki:"BDB76B",darkmagenta:"8B008B",darkolivegreen:"556B2F",darkorange:"FF8C00",darkorchid:"9932CC",darkred:"8B0000",darksalmon:"E9967A",darkseagreen:"8FBC8F",darkslateblue:"483D8B",darkslategray:"2F4F4F",darkslategrey:"2F4F4F",darkturquoise:"00CED1",darkviolet:"9400D3",deeppink:"FF1493",deepskyblue:"00BFFF",dimgray:"696969",dimgrey:"696969",dodgerblue:"1E90FF",firebrick:"B22222",floralwhite:"FFFAF0",forestgreen:"228B22",fuchsia:"FF00FF",gainsboro:"DCDCDC",ghostwhite:"F8F8FF",gold:"FFD700",goldenrod:"DAA520",gray:"808080",grey:"808080",green:"008000",greenyellow:"ADFF2F",honeydew:"F0FFF0",hotpink:"FF69B4",indianred:"CD5C5C",indigo:"4B0082",ivory:"FFFFF0",khaki:"F0E68C",lavender:"E6E6FA",lavenderblush:"FFF0F5",lawngreen:"7CFC00",lemonchiffon:"FFFACD",lightblue:"ADD8E6",lightcoral:"F08080",lightcyan:"E0FFFF",lightgoldenrodyellow:"FAFAD2",lightgray:"D3D3D3",lightgrey:"D3D3D3",lightgreen:"90EE90",lightpink:"FFB6C1",lightsalmon:"FFA07A",lightseagreen:"20B2AA",lightskyblue:"87CEFA",lightslategray:"778899",lightslategrey:"778899",lightsteelblue:"B0C4DE",lightyellow:"FFFFE0",lime:"00FF00",limegreen:"32CD32",linen:"FAF0E6",magenta:"FF00FF",maroon:"800000",mediumaquamarine:"66CDAA",mediumblue:"0000CD",mediumorchid:"BA55D3",mediumpurple:"9370D8",mediumseagreen:"3CB371",mediumslateblue:"7B68EE",mediumspringgreen:"00FA9A",mediumturquoise:"48D1CC",mediumvioletred:"C71585",midnightblue:"191970",mintcream:"F5FFFA",mistyrose:"FFE4E1",moccasin:"FFE4B5",navajowhite:"FFDEAD",navy:"000080",oldlace:"FDF5E6",olive:"808000",olivedrab:"6B8E23",orange:"FFA500",orangered:"FF4500",orchid:"DA70D6",palegoldenrod:"EEE8AA",palegreen:"98FB98",paleturquoise:"AFEEEE",palevioletred:"D87093",papayawhip:"FFEFD5",peachpuff:"FFDAB9",peru:"CD853F",pink:"FFC0CB",plum:"DDA0DD",powderblue:"B0E0E6",purple:"800080",rebeccapurple:"663399",red:"FF0000",rosybrown:"BC8F8F",royalblue:"4169E1",saddlebrown:"8B4513",salmon:"FA8072",sandybrown:"F4A460",seagreen:"2E8B57",seashell:"FFF5EE",sienna:"A0522D",silver:"C0C0C0",skyblue:"87CEEB",slateblue:"6A5ACD",slategray:"708090",slategrey:"708090",snow:"FFFAFA",springgreen:"00FF7F",steelblue:"4682B4",tan:"D2B48C",teal:"008080",thistle:"D8BFD8",tomato:"FF6347",turquoise:"40E0D0",violet:"EE82EE",wheat:"F5DEB3",white:"FFFFFF",whitesmoke:"F5F5F5",yellow:"FFFF00",yellowgreen:"9ACD32"},i=.618033988749895,u={hue:null,saturation:null,value:null,base_color:"",greyscale:!1,grayscale:!1,golden:!0,full_random:!1,colors_returned:1,format:"hex",seed:null},c={scheme_type:"analogous",format:"hex"},h={golden:!1,format:"hex"};return F.NAME_to_HEX=function(e){return e=e.toLowerCase(),e in s?s[e]:(console.error("Color name not recognized."),void 0)},F.NAME_to_RGB=function(e){return F.HEX_to_RGB(F.NAME_to_HEX(e))},F.NAME_to_HSV=function(e){return F.HEX_to_HSV(F.NAME_to_HEX(e))},F.HEX_to_RGB=function(e){var r=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;e=e.replace(r,function(e,r,a,o){return r+r+a+a+o+o});var a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(e);return a?{r:parseInt(a[1],16),g:parseInt(a[2],16),b:parseInt(a[3],16)}:null},F.RGB_to_HEX=function(e){return"#"+((1<<24)+(e.r<<16)+(e.g<<8)+e.b).toString(16).slice(1)},F.HSV_to_RGB=function(e){var r,a,o,n,t,l,F,s,i=e.h,u=e.s,c=e.v;if(0===u)return{r:c,g:c,b:c};switch(i/=60,n=Math.floor(i),t=i-n,l=c*(1-u),F=c*(1-u*t),s=c*(1-u*(1-t)),n){case 0:r=c,a=s,o=l;break;case 1:r=F,a=c,o=l;break;case 2:r=l,a=c,o=s;break;case 3:r=l,a=F,o=c;break;case 4:r=s,a=l,o=c;break;case 5:r=c,a=l,o=F}return{r:Math.floor(255*r),g:Math.floor(255*a),b:Math.floor(255*o)}},F.RGB_to_HSV=function(e){var r=e.r/255,a=e.g/255,o=e.b/255,n=0,t=0,l=0,F=Math.min(r,Math.min(a,o)),s=Math.max(r,Math.max(a,o));if(F===s)return l=F,{h:0,s:0,v:l};var i=r===F?a-o:o===F?r-a:o-r,u=r===F?3:o===F?1:5;return n=60*(u-i/(s-F)),t=(s-F)/s,l=s,{h:n,s:t,v:l}},F.HSV_to_HEX=function(e){return F.RGB_to_HEX(F.HSV_to_RGB(e))},F.HEX_to_HSV=function(e){return F.RGB_to_HSV(F.HEX_to_RGB(e))},F.make_scheme=function(e,r){function n(e){return{h:e.h,s:e.s,v:e.v}}var l,F,s,i,u,h=t(c);if(null!==r)for(var d in r)r.hasOwnProperty(d)&&(h[d]=r[d]);var g=[e];switch(h.scheme_type.toLowerCase()){case"monochromatic":case"mono":for(u=1;2>=u;u++)l=n(e),s=l.s+.1*u,s=a(s,0,1),i=l.v+.1*u,i=a(i,0,1),l.s=s,l.v=i,g.push(l);for(u=1;2>=u;u++)l=n(e),s=l.s-.1*u,s=a(s,0,1),i=l.v-.1*u,i=a(i,0,1),l.s=s,l.v=i,g.push(l);break;case"complementary":case"complement":case"comp":l=n(e),l.h=(l.h+180)%360,g.push(l);break;case"split-complementary":case"split-complement":case"split":l=n(e),l.h=(l.h+165)%360,g.push(l),l=n(e),l.h=Math.abs((l.h-165)%360),g.push(l);break;case"double-complementary":case"double-complement":case"double":l=n(e),l.h=(l.h+180)%360,g.push(l),l.h=(l.h+30)%360,F=n(l),g.push(l),l.h=(l.h+180)%360,g.push(F);break;case"analogous":case"ana":for(u=1;5>=u;u++)l=n(e),l.h=(l.h+20*u)%360,g.push(l);break;case"triadic":case"triad":case"tri":for(u=1;3>u;u++)l=n(e),l.h=(l.h+120*u)%360,g.push(l);break;default:console.error("Color scheme not recognized.")}return o(h.format.toLowerCase(),g),g},F.make_color=function(n){var s=[],c=t(u),h=null;if(null!==n)for(var d in n)n.hasOwnProperty(d)&&(c[d]=n[d]);var g=null;"string"==typeof c.seed&&(g=new l(c.seed)),c.base_color.length>0&&(h=c.base_color.match(/^#?([0-9a-f]{3})([0-9a-f]{3})?$/i)?F.HEX_to_HSV(c.base_color):F.NAME_to_HSV(c.base_color));for(var m=0;m= 128 ) ? 'dark' : 'light'; 252 | } 253 | 254 | function copy_object( object ){ 255 | var copy = {}; 256 | for( var key in object ){ 257 | if( object.hasOwnProperty( key )){ 258 | copy[key] = object[key]; 259 | } 260 | } 261 | return copy; 262 | } 263 | 264 | function RC4Random( seed ) { 265 | var key_schedule = []; 266 | var key_schedule_i = 0; 267 | var key_schedule_j = 0; 268 | for ( var k = 0; k < 256; k++ ) key_schedule[k] = k; 269 | for ( var i = 0, j = 0; i < 256; i++ ) { 270 | j = ( j + key_schedule[i] + seed.charCodeAt( i % seed.length )) % 256; 271 | var t = key_schedule[i]; 272 | key_schedule[i] = key_schedule[j]; 273 | key_schedule[j] = t; 274 | } 275 | function get_random_byte() { 276 | key_schedule_i = ( key_schedule_i + 1 ) % 256; 277 | key_schedule_j = ( key_schedule_j + key_schedule[key_schedule_i] ) % 256; 278 | var t = key_schedule[key_schedule_i]; 279 | key_schedule[key_schedule_i] = key_schedule[key_schedule_j]; 280 | key_schedule[key_schedule_j] = t; 281 | return key_schedule[( key_schedule[key_schedule_i] + key_schedule[key_schedule_j] ) % 256]; 282 | } 283 | this.random = function() { 284 | for ( var i = 0, number = 0, multiplier = 1; i < 8; i++ ) { 285 | number += get_random_byte() * multiplier; 286 | multiplier *= 256; 287 | } 288 | return number / 18446744073709551616; 289 | }; 290 | } 291 | 292 | Please.NAME_to_HEX = function( name ){ 293 | name = name.toLowerCase(); 294 | if( name in color_data ){ 295 | return color_data[name]; 296 | } 297 | else{ 298 | console.error( 'Color name not recognized.' ); 299 | } 300 | }; 301 | 302 | Please.NAME_to_RGB = function( name ){ 303 | return Please.HEX_to_RGB( Please.NAME_to_HEX( name )); 304 | }; 305 | 306 | Please.NAME_to_HSV = function( name ){ 307 | return Please.HEX_to_HSV( Please.NAME_to_HEX( name )); 308 | }; 309 | 310 | //accepts hex string, produces RGB object 311 | Please.HEX_to_RGB = function( hex ){ 312 | var regex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 313 | hex = hex.replace( regex, function( m, r, g, b ) { 314 | return r + r + g + g + b + b; 315 | }); 316 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( hex ); 317 | return result ? { 318 | r: parseInt( result[1], 16 ), 319 | g: parseInt( result[2], 16 ), 320 | b: parseInt( result[3], 16 ) 321 | } : null; 322 | }; 323 | 324 | //accepts RGB object, produces hex string 325 | Please.RGB_to_HEX = function( RGB ){ 326 | return "#" + 327 | (( 1 << 24 ) + ( RGB.r << 16 ) + ( RGB.g << 8 ) + RGB.b ) 328 | .toString( 16 ).slice( 1 ); 329 | }; 330 | 331 | //accepts HSV object, returns RGB object 332 | Please.HSV_to_RGB = function( HSV ){ 333 | var h = HSV.h, 334 | s = HSV.s, 335 | v = HSV.v; 336 | 337 | var r, g, b; 338 | 339 | var i, f, p, q, t; 340 | 341 | if( s === 0 ){ 342 | return { 343 | r: v, 344 | g: v, 345 | b: v 346 | }; 347 | } 348 | h /= 60; 349 | i = Math.floor( h ); 350 | f = h - i; 351 | p = v * ( 1 - s ); 352 | q = v * ( 1 - s * f ); 353 | t = v * ( 1 - s * ( 1 - f ) ); 354 | 355 | switch(i) { 356 | case 0: 357 | r = v; 358 | g = t; 359 | b = p; 360 | break; 361 | case 1: 362 | r = q; 363 | g = v; 364 | b = p; 365 | break; 366 | case 2: 367 | r = p; 368 | g = v; 369 | b = t; 370 | break; 371 | case 3: 372 | r = p; 373 | g = q; 374 | b = v; 375 | break; 376 | case 4: 377 | r = t; 378 | g = p; 379 | b = v; 380 | break; 381 | case 5: 382 | r = v; 383 | g = p; 384 | b = q; 385 | break; 386 | } 387 | 388 | return { 389 | r: Math.floor(r * 255), 390 | g: Math.floor(g * 255), 391 | b: Math.floor(b * 255) 392 | }; 393 | }; 394 | 395 | //accepts RGB object, returns HSV object 396 | Please.RGB_to_HSV = function( RGB ){ 397 | var r = ( RGB.r / 255 ), 398 | g = ( RGB.g / 255 ), 399 | b = ( RGB.b / 255 ); 400 | var computed_H = 0, 401 | computed_S = 0, 402 | computed_V = 0; 403 | var min_RGB = Math.min( r, Math.min( g, b ) ), 404 | max_RGB = Math.max( r, Math.max( g, b ) ); 405 | // Black-gray-white 406 | if ( min_RGB === max_RGB ) { 407 | computed_V = min_RGB; 408 | return{ 409 | h: 0, 410 | s: 0, 411 | v: computed_V 412 | }; 413 | } 414 | // Colors other than black-gray-white: 415 | var d = ( r === min_RGB ) ? g - b : (( b === min_RGB ) ? r - g : b - r); 416 | var h = ( r === min_RGB ) ? 3 : (( b === min_RGB ) ? 1 : 5 ); 417 | computed_H = 60 * ( h - d / ( max_RGB - min_RGB )); 418 | computed_S = ( max_RGB - min_RGB ) / max_RGB; 419 | computed_V = max_RGB; 420 | return { 421 | h: computed_H, 422 | s: computed_S, 423 | v: computed_V 424 | }; 425 | }; 426 | 427 | //accepts HSV object, returns hex string 428 | Please.HSV_to_HEX = function( HSV ){ 429 | return Please.RGB_to_HEX( Please.HSV_to_RGB( HSV )); 430 | }; 431 | 432 | //accepts hex string, returns HSV object 433 | Please.HEX_to_HSV = function( hex ){ 434 | return Please.RGB_to_HSV( Please.HEX_to_RGB( hex )); 435 | }; 436 | 437 | //accepts HSV object and options object, returns list or single object depending on options 438 | Please.make_scheme = function( HSV, options ){ 439 | //clone base please options 440 | var scheme_options = copy_object( make_scheme_default ), 441 | adjusted, 442 | secondary, 443 | adjusted_h, 444 | adjusted_s, 445 | adjusted_v, 446 | i; 447 | 448 | if( options !== null ){ 449 | //override base Please options 450 | for( var key in options ){ 451 | if( options.hasOwnProperty( key )){ 452 | scheme_options[key] = options[key]; 453 | } 454 | } 455 | } 456 | 457 | var scheme = [HSV]; 458 | //DRY for repeated cloning 459 | function clone( HSV ){ 460 | return{ 461 | h: HSV.h, 462 | s: HSV.s, 463 | v: HSV.v 464 | }; 465 | } 466 | switch( scheme_options.scheme_type.toLowerCase() ){ 467 | case 'monochromatic': 468 | case 'mono': 469 | for ( i = 1; i <= 2; i++ ) { 470 | 471 | adjusted = clone( HSV ); 472 | 473 | adjusted_s = adjusted.s + ( 0.1 * i ); 474 | adjusted_s = clamp( adjusted_s, 0, 1 ); 475 | 476 | adjusted_v = adjusted.v + ( 0.1 * i ); 477 | adjusted_v = clamp( adjusted_v, 0, 1 ); 478 | 479 | adjusted.s = adjusted_s; 480 | adjusted.v = adjusted_v; 481 | 482 | scheme.push( adjusted ); 483 | } 484 | for ( i = 1; i <= 2; i++ ) { 485 | 486 | adjusted = clone( HSV ); 487 | 488 | adjusted_s = adjusted.s - ( 0.1 * i ); 489 | adjusted_s = clamp( adjusted_s, 0, 1 ); 490 | 491 | adjusted_v = adjusted.v - ( 0.1 * i ); 492 | adjusted_v = clamp( adjusted_v, 0, 1 ); 493 | 494 | adjusted.s = adjusted_s; 495 | adjusted.v = adjusted_v; 496 | 497 | scheme.push( adjusted ); 498 | } 499 | break; 500 | case 'complementary': 501 | case 'complement': 502 | case 'comp': 503 | adjusted = clone( HSV ); 504 | adjusted.h = ( adjusted.h + 180 ) % 360; 505 | scheme.push( adjusted ); 506 | break; 507 | //30 degree seperation 508 | case 'split-complementary': 509 | case 'split-complement': 510 | case 'split': 511 | adjusted = clone( HSV ); 512 | adjusted.h = ( adjusted.h + 165 ) % 360; 513 | scheme.push( adjusted ); 514 | adjusted = clone( HSV ); 515 | adjusted.h = Math.abs( ( adjusted.h - 165 ) % 360 ); 516 | scheme.push( adjusted ); 517 | break; 518 | case 'double-complementary': 519 | case 'double-complement': 520 | case 'double': 521 | //first basic complement 522 | adjusted = clone( HSV ); 523 | adjusted.h = ( adjusted.h + 180 ) % 360; 524 | scheme.push( adjusted ); 525 | //then offset 526 | adjusted.h = ( adjusted.h + 30 ) % 360; 527 | secondary = clone( adjusted ); 528 | scheme.push( adjusted ); 529 | //complement offset 530 | adjusted.h = ( adjusted.h + 180 ) % 360; 531 | scheme.push( secondary ); 532 | break; 533 | case 'analogous': 534 | case 'ana': 535 | for ( i = 1; i <= 5; i++ ) { 536 | adjusted = clone( HSV ); 537 | adjusted.h = ( adjusted.h + ( 20 * i ) ) % 360; 538 | scheme.push( adjusted ); 539 | } 540 | break; 541 | case 'triadic': 542 | case 'triad': 543 | case 'tri': 544 | for ( i = 1; i < 3; i++ ) { 545 | adjusted = clone( HSV ); 546 | adjusted.h = ( adjusted.h + ( 120 * i ) ) % 360; 547 | scheme.push( adjusted ); 548 | } 549 | break; 550 | default: 551 | console.error( 'Color scheme not recognized.' ); 552 | break; 553 | } 554 | convert_to_format( scheme_options.format.toLowerCase(), scheme ); 555 | return scheme; 556 | }; 557 | 558 | //accepts options object returns list or single color 559 | Please.make_color = function( options ){ 560 | var color = [], 561 | //clone base please options 562 | color_options = copy_object( make_color_default ), 563 | base_color = null; 564 | 565 | if( options !== null ){ 566 | //override base Please options 567 | for( var key in options ){ 568 | if( options.hasOwnProperty( key )){ 569 | color_options[key] = options[key]; 570 | } 571 | } 572 | } 573 | 574 | var randomiser = null; 575 | 576 | if (typeof color_options.seed === 'string') { 577 | randomiser = new RC4Random(color_options.seed); 578 | } 579 | 580 | //first, check for a base color 581 | if ( color_options.base_color.length > 0 ) { 582 | //then determine if its a hex string or a named color 583 | if( color_options.base_color.match( /^#?([0-9a-f]{3})([0-9a-f]{3})?$/i ) ){ 584 | base_color = Please.HEX_to_HSV( color_options.base_color ); 585 | } 586 | else{ 587 | base_color = Please.NAME_to_HSV( color_options.base_color ); 588 | } 589 | } 590 | for ( var i = 0; i < color_options.colors_returned; i++ ) { 591 | var random_hue = random_int( 0, 360, randomiser ), 592 | hue, 593 | saturation, 594 | value; 595 | if( base_color !== null ){ 596 | hue = clamp( random_int( ( base_color.h - 5 ), ( base_color.h + 5 ), randomiser), 0, 360); 597 | //fix for black/gray as a base color returning reds 598 | if( base_color.s === 0 ) { 599 | saturation = 0; 600 | } 601 | else{ 602 | saturation = random_float( 0.4, 0.85, randomiser ); 603 | } 604 | value = random_float( 0.4, 0.85, randomiser ); 605 | color.push({ 606 | h: hue, 607 | s: saturation, 608 | v: value 609 | }); 610 | } 611 | else{ 612 | if( color_options.greyscale === true || color_options.grayscale === true ){ 613 | hue = 0; 614 | } 615 | //make hue goldennnnnnnn 616 | else if( color_options.golden === true ){ 617 | hue = ( random_hue + ( random_hue / PHI )) % 360; 618 | } 619 | else if( color_options.hue === null || color_options.full_random === true ){ 620 | hue = random_hue; 621 | } 622 | else{ 623 | hue = clamp( color_options.hue, 0, 360 ); 624 | } 625 | //set saturation 626 | if ( color_options.greyscale === true || color_options.grayscale === true ) { 627 | saturation = 0; //if they want greyscale no saturation allowed 628 | } 629 | else if ( color_options.full_random === true ){ 630 | saturation = random_float( 0, 1, randomiser ); 631 | } 632 | else if ( color_options.saturation === null ){ 633 | saturation = 0.4; 634 | } 635 | else{ 636 | saturation = clamp( color_options.saturation, 0, 1 ); 637 | } 638 | //set value 639 | if( color_options.full_random === true ){ 640 | value = random_float( 0, 1, randomiser ); 641 | } 642 | else if( color_options.greyscale === true || color_options.grayscale === true ){ 643 | value = random_float( 0.15, 0.75, randomiser ); 644 | } 645 | else if( color_options.value === null ){ 646 | value = 0.75; 647 | } 648 | else{ 649 | value = clamp( color_options.value, 0 , 1 ); 650 | } 651 | color.push( {h: hue, s: saturation, v: value} ); 652 | } 653 | } 654 | //output options based on format 655 | convert_to_format( color_options.format.toLowerCase(), color ); 656 | 657 | return color; 658 | }; 659 | //accepts HSV object returns contrasting color 660 | Please.make_contrast = function( HSV, options ){ 661 | 662 | //clone base please options 663 | var contrast_options = copy_object( make_contrast_default ); 664 | 665 | if( options !== null ){ 666 | //override base Please options 667 | for( var key in options ){ 668 | if( options.hasOwnProperty( key )){ 669 | contrast_options[key] = options[key]; 670 | } 671 | } 672 | } 673 | 674 | var contrast, 675 | value_range = contrast_quotient( HSV ), 676 | adjusted_hue; 677 | 678 | if( contrast_options.golden === true ){ 679 | adjusted_hue = ( HSV.h * ( 1 + PHI ) ) % 360; 680 | } 681 | else{ 682 | var contrast_base = 683 | Please.make_scheme( HSV, 684 | { 685 | scheme_type: 'complementary', 686 | format: 'hsv' 687 | })[1]; 688 | adjusted_hue = clamp( ( contrast_base.h - 30 ), 0, 360 ); 689 | } 690 | var adjusted_value; 691 | if ( value_range === 'dark' ){ 692 | adjusted_value = clamp( ( HSV.v - 0.25 ), 0, 1 ); 693 | } 694 | else if ( value_range === 'light' ){ 695 | adjusted_value = clamp( ( HSV.v + 0.25 ), 0, 1 ); 696 | } 697 | contrast = [{ 698 | h: adjusted_hue, 699 | s: HSV.s, 700 | v: adjusted_value 701 | }]; 702 | 703 | convert_to_format( contrast_options.format.toLowerCase(), contrast ); 704 | return contrast[0]; 705 | }; 706 | 707 | return Please; 708 | } 709 | return define_Please(); 710 | })); 711 | --------------------------------------------------------------------------------