2012-01-25 152 views
3

我想採用顏色並使用JavaScript生成隨機偏離該顏色的顏色。例如,假設我的顏色爲#33CCFF,我想將該數字輸入到腳本中,並獲取像#8AE2FF#00AAE2#7BDEFF這樣的數字。基本上,色調應該保持不變,但飽和度/亮度應該會有所波動。生成隨機顏色偏差

什麼是最快和最簡單的方法來產生這些數字?

+3

如果您使用的是現代瀏覽器,實際上可以使用HSL而不是使用十六進制指定顏色。這應該讓你的任務變得非常簡單。 HTTP://www.css3。info/preview/hsl/ –

+0

@BrianGlaz:這是一個精巧的小技巧,但不幸的是,我試圖保持瀏覽器兼容性,即使使用IE。 –

回答

0

老實說,我不知道的十六進制代碼是如何制定出飽和度/亮度,所以我會轉換爲HSL:

http://serennu.com/colour/rgbtohsl.php

改變你想要的,然後改回來。我看到唯一的一個主要缺點就是HSL在Hex字段中不存在的可能性。

如,

HSL色彩空間具有唯一的360×100×100 = 3600000 在它的顏色,而RGB顏色空間具有256×256×256 = 16,77,216顏色在裏面,這是四倍半。

0

我知道這個問題是一歲,但我四處尋找解決方案,找不到它。

但基於這裏和那裏的建議(主要是在SO)我創建了準備好使用腳本。

通知1:colorToRGB功能不可靠。我在SO中發現它(來源附件)。我改變了一些顏色的十六進制值,但我不想檢查它們全部。爲獲得最佳效果,請使用十六進制值

通知2:deviationgenerateSimilarColor函數是爲我的目的而設置的。你可以改變它以獲得更好的結果。

通知3:許多功能都在SO上找到。我剛剛將它們聚集在一起,並提供了相應問題的鏈接。下面

JavaScript代碼(在文章底部的測試環境下):

/** 
* Generates similar color based on passed one 
* 
* @param color accepts few formats, e.g. white, #ffffff or [255, 255, 255] 
* @return hex value, e.g. #ffffff 
* 
* @author Carlos (StackOverflow) 
*/ 
function generateSimilarColor(color) { 

    var rand = generateRandomInt(-5, 5); 
    if(rand < 0) rand -= 5; 
    else rand += 5; 
    var deviation = rand/100; 

    if(!isArray(color) || color.length != 3) { // this is not [r, g, b] array 

     var hexNotation = colorToRGB(color); 

     if(!hexNotation) { // we couldn't find HEX value of this string based on color name 
      if(!isString(color) || color.length != 7 || color[0] != '#') { // this is not string in this format: #ffffff 
       return false; 
      } 
      else { 
       hexNotation = color; 
      } 
     } 

     color = hexToRgb(hexNotation); 

     if(!color) { 
      return false; 
     } 
    } 

    var hsl = rgbToHsl(color[0], color[1], color[2]); 

    // saturation 
    hsl[1] += deviation; 
    if(hsl[1] > 1) hsl[1] = 1 - Math.abs(deviation); 
    else if(hsl[1] < 0) hsl[1] = Math.abs(deviation); 

    // lightness 
    hsl[2] += deviation; 
    if(hsl[2] > 1) hsl[2] = 1 - Math.abs(deviation); 
    else if(hsl[2] < 0) hsl[2] = Math.abs(deviation); 

    color = hslToRgb(hsl[0], hsl[1], hsl[2]); 
    var hex = rgbToHex(color[0], color[1], color[2]); 

    return hex; 
} 

/** 
* Returns a random integer between min and max 
* Using Math.round() will give you a non-uniform distribution! 
* 
* @source http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range 
*/ 
function generateRandomInt(min, max) { 
    return Math.floor(Math.random() * (max - min + 1)) + min; 
} 

/** 
* @source: [slightly changed] http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb 
*/ 
function componentToHex(c) { 
    var hex = c.toString(16); 
    return hex.length == 1 ? "0" + hex : hex; 
} 

/** 
* @source: [slightly changed] http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb 
*/ 
function rgbToHex(r, g, b) { 
    r = parseInt(r); 
    g = parseInt(g); 
    b = parseInt(b); 
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b); 
} 

/** 
* @source http://stackoverflow.com/questions/1058427/how-to-detect-if-a-variable-is-an-array 
*/ 
function isArray(obj) { 
    return Object.prototype.toString.call(obj) === '[object Array]'; 
} 

/** 
* @source http://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string 
*/ 
function isString(str) { 
    return (typeof str == 'string' || str instanceof String); 
} 

/** 
* @source: http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb slightly change 
*/ 
function hexToRgb(hex) { 

    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") 
    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 
    hex = hex.replace(shorthandRegex, function(m, r, g, b) { 
     return r + r + g + g + b + b; 
    }); 

    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 
    return result ? [ 
     parseInt(result[1], 16), 
     parseInt(result[2], 16), 
     parseInt(result[3], 16) 
    ] : false; 
} 

/** 
* Converts an RGB color value to HSL. Conversion formula 
* adapted from http://en.wikipedia.org/wiki/HSL_color_space. 
* Assumes r, g, and b are contained in the set [0, 255] and 
* returns h, s, and l in the set [0, 1]. 
* 
* @param Number r  The red color value 
* @param Number g  The green color value 
* @param Number b  The blue color value 
* @return Array   The HSL representation 
* 
* @source http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript 
*/ 
function rgbToHsl(r, g, b) { 
    r /= 255, g /= 255, b /= 255; 
    var max = Math.max(r, g, b), min = Math.min(r, g, b); 
    var h, s, l = (max + min)/2; 

    if(max == min){ 
     h = s = 0; // achromatic 
    }else{ 
     var d = max - min; 
     s = l > 0.5 ? d/(2 - max - min) : d/(max + min); 
     switch(max){ 
      case r: h = (g - b)/d + (g < b ? 6 : 0); break; 
      case g: h = (b - r)/d + 2; break; 
      case b: h = (r - g)/d + 4; break; 
     } 
     h /= 6; 
    } 

    return [h, s, l]; 
} 

/** 
* Converts an HSL color value to RGB. Conversion formula 
* adapted from http://en.wikipedia.org/wiki/HSL_color_space. 
* Assumes h, s, and l are contained in the set [0, 1] and 
* returns r, g, and b in the set [0, 255]. 
* 
* @param Number h  The hue 
* @param Number s  The saturation 
* @param Number l  The lightness 
* @return Array   The RGB representation 
*/ 
function hslToRgb(h, s, l) { 
    var r, g, b; 

    if(s == 0){ 
     r = g = b = l; // achromatic 
    }else{ 
     function hue2rgb(p, q, t){ 
      if(t < 0) t += 1; 
      if(t > 1) t -= 1; 
      if(t < 1/6) return p + (q - p) * 6 * t; 
      if(t < 1/2) return q; 
      if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; 
      return p; 
     } 

     var q = l < 0.5 ? l * (1 + s) : l + s - l * s; 
     var p = 2 * l - q; 
     r = hue2rgb(p, q, h + 1/3); 
     g = hue2rgb(p, q, h); 
     b = hue2rgb(p, q, h - 1/3); 
    } 

    return [r * 255, g * 255, b * 255]; 
} 

/** 
* @source [slightly changed] http://stackoverflow.com/questions/1573053/javascript-function-to-convert-color-names-to-hex-codes 
*/ 
function colorToRGB(color) { 

    var colors = {"aliceblue":"#f0f8ff","antiquewhite":"#faebd7","aqua":"#00ffff","aquamarine":"#7fffd4","azure":"#f0ffff", 
    "beige":"#f5f5dc","bisque":"#ffe4c4","black":"#000000","blanchedalmond":"#ffebcd","blue":"#0000ff","blueviolet":"#8a2be2","brown":"#603311","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","darkgreen":"#006400","darkkhaki":"#bdb76b","darkmagenta":"#8b008b","darkolivegreen":"#556b2f", 
    "darkorange":"#ff8c00","darkorchid":"#9932cc","darkred":"#8b0000","darksalmon":"#e9967a","darkseagreen":"#8fbc8f","darkslateblue":"#483d8b","darkslategray":"#2f4f4f","darkturquoise":"#00ced1", 
    "darkviolet":"#9400d3","deeppink":"#ff1493","deepskyblue":"#00bfff","dimgray":"#696969","dodgerblue":"#1e90ff", 
    "firebrick":"#b22222","floralwhite":"#fffaf0","forestgreen":"#228b22","fuchsia":"#ff00ff", 
    "gainsboro":"#dcdcdc","ghostwhite":"#f8f8ff","gold":"#ffd700","goldenrod":"#daa520","gray":"#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", 
    "lightgrey":"#d3d3d3","lightgreen":"#90ee90","lightpink":"#ffb6c1","lightsalmon":"#ffa07a","lightseagreen":"#20b2aa","lightskyblue":"#87cefa","lightslategray":"#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", 
    "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","snow":"#fffafa","springgreen":"#00ff7f","steelblue":"#4682b4", 
    "tan":"#d2b48c","teal":"#008080","thistle":"#d8bfd8","tomato":"#ff6347","turquoise":"#40e0d0", 
    "violet":"#8F00FF", 
    "wheat":"#f5deb3","white":"#ffffff","whitesmoke":"#f5f5f5", 
    "yellow":"#ffff00","yellowgreen":"#9acd32"}; 

    if (typeof colors[color.toLowerCase()] != 'undefined') 
     return colors[color.toLowerCase()]; 

    return false; 
} 

測試環境(需要的jQuery):

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
     <meta charset="utf-8"> 
     <title>Color Test</title> 
     <script type="text/javascript" src="js/libs/jquery.js"></script> 
     <script type="text/javascript" src="js/color.js"></script> 
     <script type="text/javascript"> 
      $(document).ready(function() { 
       var i, j, colors = ['blue', 'orange', 'green', 'red', 'yellow', 'brown', 'violet']; 
       for(i = 0; i < colors.length; i++) { 
        for(j = 0; j < 3; j++) { 
         $("body").append('<div style="height: 20px; background-color: ' + generateSimilarColor(colors[i]) + ';"></div>'); 
        } 
        $("body").append('<div style="height: 20px;"></div>'); 
       } 
      }); 
     </script> 
    </head> 
    <body></body> 
</html> 

任何錯誤或建議 - 請寫。