├── README.md ├── bower.json ├── package.json ├── please.min.js └── Please.js /README.md: -------------------------------------------------------------------------------- 1 | #PleaseJS 2 | ======== 3 | 4 | JavaScript Library for creating random pleasing colors and color schemes. 5 | 6 | ```javascript 7 | Please.make_color(); 8 | 9 | Please.make_scheme( 10 | { 11 | h: 145, 12 | s: .7, 13 | v: .6 14 | }, 15 | { 16 | scheme_type: 'triadic', 17 | format: 'rgb-string' 18 | }); 19 | ``` -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pleasejs", 3 | "version": "0.0.0", 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": "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.0.0", 4 | "description": "JS library to generate random pleasing colors/color schemes", 5 | "main": "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 | } 25 | -------------------------------------------------------------------------------- /please.min.js: -------------------------------------------------------------------------------- 1 | /*Please JS, Jordan Checkman 2014, Checkman.io, MIT Liscense, Have fun.*/ 2 | (function(e){"use strict";function t(){function i(e,t){return Math.floor(Math.random()*(t-e+1))+e}function s(e,t){return Math.random()*(t-e)+e}function o(e,t,n){if(en){e=n}return e}function u(t,n){switch(t){case"hex":for(var r=0;r360){c.h-=360}s.push(c);break;case"split-complementary":case"split-complement":case"split":var c=f(e);c.h+=165;if(c.h>360){c.h-=360}s.push(c);var c=f(e);c.h-=165;if(c.h<0){c.h+=360}s.push(c);break;case"double-complementary":case"double-complement":case"double":var c=f(e);c.h+=180;if(c.h>360){c.h-=360}s.push(c);var c=f(e);c.h+=30;if(c.h>360){c.h-=360}var d=f(c);s.push(c);d.h+=180;if(d.h>360){d.h-=360}s.push(d);break;case"analogous":case"ana":for(var l=1;l<=5;l++){var c=f(e);c.h+=20*l;if(c.h>360){c.h-=360}s.push(c)}break;case"triadic":case"triad":case"tri":for(var l=1;l<3;l++){var c=f(e);c.h+=120*l;if(c.h>360){c.h-=360}s.push(c)}break;default:console.log("Color scheme not recognized.");break}u(n.format.toLowerCase(),s);return s};e.make_color=function(r){var a=[];var f={};for(var l in n){if(n.hasOwnProperty(l)){f[l]=n[l]}}if(r!=null){for(var l in r){if(r.hasOwnProperty(l)){f[l]=r[l]}}}var c;if(f.base_color.length>0){c=t[f.base_color.toLowerCase()];c=e.HEX_to_HSV(c)}for(var h=0;h max){ 182 | num = max; 183 | } 184 | return num; 185 | } 186 | function convert_to_format(format_string, array){ 187 | switch(format_string){ 188 | case 'hex': 189 | for (var i = 0; i < array.length; i++) { 190 | array[i] = Please.HSV_to_HEX(array[i]); 191 | } 192 | break; 193 | case 'rgb': 194 | for (var i = 0; i < array.length; i++) { 195 | array[i] = Please.HSV_to_RGB(array[i]); 196 | } 197 | break; 198 | case 'rgb-string': 199 | for (var i = 0; i < array.length; i++) { 200 | var raw_rgb = Please.HSV_to_RGB(array[i]); 201 | array[i] = 202 | "rgb(" + 203 | raw_rgb.r + "," + 204 | raw_rgb.g + "," + 205 | raw_rgb.b + ")"; 206 | } 207 | break; 208 | case 'hsv': 209 | break; 210 | default: 211 | console.log('Format not recognized.'); 212 | break; 213 | } 214 | return array; 215 | } 216 | function copy_object(object){ 217 | var copy = {}; 218 | for(var key in object){ 219 | if(object.hasOwnProperty(key)){ 220 | copy[key] = object[key]; 221 | } 222 | } 223 | return copy; 224 | } 225 | Please.NAME_to_HEX = function(name){ 226 | if(name in color_data){ 227 | return color_data[name]; 228 | } 229 | else{ 230 | console.log('Color name not recognized.'); 231 | } 232 | } 233 | Please.NAME_to_HSV = function(name){ 234 | return Please.HEX_to_RGB(Please.NAME_to_HEX(name)); 235 | } 236 | Please.NAME_to_HSV = function(name){ 237 | return Please.HEX_to_HSV(Please.NAME_to_HEX(name)); 238 | } 239 | //accepts hex string, produces RGB object 240 | Please.HEX_to_RGB = function(hex){ 241 | var regex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 242 | hex = hex.replace( regex, function( m, r, g, b ) { 243 | return r + r + g + g + b + b; 244 | }); 245 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec( hex ); 246 | return result ? { 247 | r: parseInt(result[1], 16), 248 | g: parseInt(result[2], 16), 249 | b: parseInt(result[3], 16) 250 | } : null; 251 | } 252 | //accepts RGB object, produces hex string 253 | Please.RGB_to_HEX = function(RGB){ 254 | return "#" + 255 | (( 1 << 24 ) + ( RGB.r << 16 ) + ( RGB.g << 8 ) + RGB.b ) 256 | .toString( 16 ).slice( 1 ); 257 | } 258 | //accepts HSV object, returns RGB object 259 | Please.HSV_to_RGB = function(HSV){ 260 | var r, g, b; 261 | var h = ( HSV.h / 360 ); 262 | var s = HSV.s; 263 | var v = HSV.v; 264 | var i = Math.floor( h * 6 ); 265 | var f = h * 6 - i; 266 | var p = v * ( 1 - s ); 267 | var q = v * ( 1 - f * s ); 268 | var t = v * ( 1 - ( 1 - f ) * s ); 269 | switch( i % 6 ){ 270 | case 0: r = v, g = t, b = p; 271 | break; 272 | case 1: r = q, g = v, b = p; 273 | break; 274 | case 2: r = p, g = v, b = t; 275 | break; 276 | case 3: r = p, g = q, b = v; 277 | break; 278 | case 4: r = t, g = p, b = v; 279 | break; 280 | case 5: r = v, g = p, b = q; 281 | break; 282 | } 283 | return{ 284 | r:Math.floor( r * 255 ), 285 | g:Math.floor( g * 255 ), 286 | b:Math.floor( b * 255 ) 287 | } 288 | } 289 | //accepts RGB object, returns HSV object 290 | Please.RGB_to_HSV = function(RGB){ 291 | var r, g, b; 292 | var computed_H = 0; 293 | var computed_S = 0; 294 | var computed_V = 0; 295 | r = ( RGB.r / 255 ); 296 | g = ( RGB.g / 255 ); 297 | b = ( RGB.b / 255 ); 298 | var min_RGB = Math.min( r, Math.min( g, b ) ); 299 | var max_RGB = Math.max( r, Math.max( g, b ) ); 300 | // Black-gray-white 301 | if ( min_RGB == max_RGB ) { 302 | computed_V = min_RGB; 303 | return{ 304 | h: 0, 305 | s: 0, 306 | v: computed_V 307 | } 308 | } 309 | // Colors other than black-gray-white: 310 | var d = ( r == min_RGB ) ? g - b : (( b == min_RGB ) ? r - g : b - r); 311 | var h = ( r == min_RGB ) ? 3 : (( b == min_RGB ) ? 1 : 5); 312 | computed_H = 60 * ( h - d / ( max_RGB - min_RGB )); 313 | computed_S = ( max_RGB - min_RGB ) / max_RGB; 314 | computed_V = max_RGB; 315 | return { 316 | h: computed_H, 317 | s: computed_S, 318 | v: computed_V 319 | } 320 | } 321 | //accepts HSV object, returns hex string 322 | Please.HSV_to_HEX = function(HSV){ 323 | return Please.RGB_to_HEX(Please.HSV_to_RGB(HSV)); 324 | } 325 | //accepts hex string, returns HSV object 326 | Please.HEX_to_HSV = function(hex){ 327 | return Please.RGB_to_HSV(Please.HEX_to_RGB(hex)); 328 | } 329 | //accepts HSV object and options object, returns list or single object depending on options 330 | Please.make_scheme = function(HSV, options){ 331 | //clone base please options 332 | var scheme_options = copy_object(Scheme_options); 333 | 334 | if(options != null){ 335 | //override base Please options 336 | for(var key in options){ 337 | if(options.hasOwnProperty(key)){ 338 | scheme_options[key] = options[key]; 339 | } 340 | } 341 | } 342 | 343 | var scheme = [HSV]; 344 | //DRY for repeated cloning 345 | function clone(HSV){ 346 | return{ 347 | h: HSV.h, 348 | s: HSV.s, 349 | v: HSV.v 350 | } 351 | } 352 | switch(scheme_options.scheme_type.toLowerCase()){ 353 | case 'monochromatic': 354 | case 'mono': 355 | for (var i = 1; i <= 2; i++) { 356 | var adjusted = clone(HSV); 357 | 358 | var adjusted_s = adjusted.s + (.1 * i); 359 | adjusted_s = constrain(adjusted_s,0,1); 360 | 361 | var adjusted_v = adjusted.v + (.1 * i); 362 | adjusted_v = constrain(adjusted_v,0,1); 363 | 364 | adjusted.s = adjusted_s; 365 | adjusted.v = adjusted_v; 366 | 367 | scheme.push(adjusted); 368 | } 369 | for (var i = 1; i < 2; i++) { 370 | var adjusted = clone(HSV); 371 | 372 | var adjusted_s = adjusted.s - (.1 * i); 373 | adjusted_s = constrain(adjusted_s,0,1); 374 | 375 | var adjusted_v = adjusted.v - (.1 * i); 376 | adjusted_v = constrain(adjusted_v,0,1); 377 | 378 | adjusted.s = adjusted_s; 379 | adjusted.v = adjusted_v; 380 | 381 | scheme.push(adjusted); 382 | } 383 | break; 384 | case 'complementary': 385 | case 'complement': 386 | var adjusted = clone(HSV); 387 | adjusted.h += 180; 388 | if( adjusted.h > 360 ){ 389 | adjusted.h -= 360; 390 | } 391 | scheme.push(adjusted); 392 | break; 393 | //30 degree seperation 394 | case 'split-complementary': 395 | case 'split-complement': 396 | case 'split': 397 | var adjusted = clone(HSV); 398 | adjusted.h += 165; 399 | if( adjusted.h > 360 ){ 400 | adjusted.h -= 360; 401 | } 402 | scheme.push(adjusted); 403 | var adjusted = clone(HSV); 404 | adjusted.h -= 165; 405 | if( adjusted.h < 0 ){ 406 | adjusted.h += 360; 407 | } 408 | scheme.push(adjusted); 409 | break; 410 | case 'double-complementary': 411 | case 'double-complement': 412 | case 'double': 413 | //first basic complement 414 | var adjusted = clone(HSV); 415 | adjusted.h += 180; 416 | if( adjusted.h > 360 ){ 417 | adjusted.h -= 360; 418 | } 419 | scheme.push(adjusted); 420 | //then offset 421 | var adjusted = clone(HSV); 422 | adjusted.h += 30; 423 | if( adjusted.h > 360 ){ 424 | adjusted.h -= 360; 425 | } 426 | var secondary = clone(adjusted); 427 | scheme.push(adjusted); 428 | //complement offset 429 | secondary.h += 180; 430 | if( secondary.h > 360 ){ 431 | secondary.h -= 360; 432 | } 433 | scheme.push(secondary); 434 | break; 435 | case 'analogous': 436 | case 'ana': 437 | for (var i = 1; i <= 5; i++) { 438 | var adjusted = clone(HSV); 439 | adjusted.h += (20 * i); 440 | if (adjusted.h > 360) { 441 | adjusted.h -= 360; 442 | } 443 | scheme.push(adjusted); 444 | } 445 | break; 446 | case 'triadic': 447 | case 'triad': 448 | case 'tri': 449 | for (var i = 1; i < 3; i++) { 450 | var adjusted = clone(HSV); 451 | adjusted.h += (120 * i); 452 | if( adjusted.h > 360 ){ 453 | adjusted.h -= 360; 454 | } 455 | scheme.push(adjusted); 456 | }; 457 | break; 458 | default: 459 | console.log('Color scheme not recognized.') 460 | break; 461 | } 462 | convert_to_format(scheme_options.format.toLowerCase(),scheme); 463 | return scheme; 464 | } 465 | //accepts options object returns list or single color 466 | Please.make_color = function(options){ 467 | var color = []; 468 | //clone base please options 469 | var color_options = {}; 470 | for(var key in Color_options){ 471 | if(Color_options.hasOwnProperty(key)){ 472 | color_options[key] = Color_options[key]; 473 | } 474 | } 475 | if(options != null){ 476 | //override base Please options 477 | for(var key in options){ 478 | if(options.hasOwnProperty(key)){ 479 | color_options[key] = options[key]; 480 | } 481 | } 482 | } 483 | //first, check for a base color 484 | var base_color; 485 | if ( color_options.base_color.length > 0 ) { 486 | base_color = color_data[color_options.base_color.toLowerCase()]; 487 | base_color = Please.HEX_to_HSV(base_color); 488 | } 489 | for ( var i = 0; i < color_options.colors_returned; i++ ) { 490 | var random_hue = random_int( 0, 360 ); 491 | var hue,saturation,value; 492 | if( base_color != null ){ 493 | hue = random_int( (base_color.h - 5), (base_color.h + 5) ); 494 | saturation = random_float(.4, .85); 495 | value = random_float(.4, .85); 496 | color.push({h: hue, s: saturation, v: value}); 497 | } 498 | else{ 499 | //make hue goldennnnnnnn 500 | if(color_options.greyscale == true || color_options.grayscale == true){ 501 | hue = 0; 502 | } 503 | else if(color_options.golden == true){ 504 | hue = (random_hue+(random_hue/0.618033988749895)); 505 | } 506 | else if(color_options.hue == null || color_options.full_random == true){ 507 | hue = random_hue; 508 | } 509 | else{ 510 | hue = constrain(color_options.hue, 0, 360); 511 | } 512 | //set saturation 513 | if (color_options.greyscale == true || color_options.grayscale == true) { 514 | saturation = 0; //if they want greyscale no saturation allowed 515 | } 516 | else if (color_options.full_random == true){ 517 | saturation = random_float(0,1); 518 | } 519 | else if (color_options.saturation == null){ 520 | saturation = .4; 521 | } 522 | else{ 523 | saturation = constrain(color_options.saturation, 0, 1); 524 | } 525 | //set value 526 | if(color_options.full_random == true){ 527 | value = random_float(0,1); 528 | } 529 | else if(color_options.greyscale == true || color_options.grayscale == true){ 530 | value = random_float(.15,.75) 531 | } 532 | else if(color_options.value == null){ 533 | value = .75; 534 | } 535 | else{ 536 | value = constrain(color_options.value, 0 , 1); 537 | } 538 | color.push({h: hue, s: saturation, v: value}); 539 | } 540 | } 541 | //output options based on format 542 | convert_to_format(color_options.format.toLowerCase(),color); 543 | if (color.length === 1) {return color[0];} 544 | else{return color;} 545 | } 546 | 547 | return Please; 548 | } 549 | //globalize it 3/60 550 | if (typeof(Please) == 'undefined') { 551 | window.Please = define_Please(); 552 | } 553 | })(window); --------------------------------------------------------------------------------