我想採用顏色並使用JavaScript生成隨機偏離該顏色的顏色。例如,假設我的顏色爲#33CCFF
,我想將該數字輸入到腳本中,並獲取像#8AE2FF
,#00AAE2
和#7BDEFF
這樣的數字。基本上,色調應該保持不變,但飽和度/亮度應該會有所波動。生成隨機顏色偏差
什麼是最快和最簡單的方法來產生這些數字?
我想採用顏色並使用JavaScript生成隨機偏離該顏色的顏色。例如,假設我的顏色爲#33CCFF
,我想將該數字輸入到腳本中,並獲取像#8AE2FF
,#00AAE2
和#7BDEFF
這樣的數字。基本上,色調應該保持不變,但飽和度/亮度應該會有所波動。生成隨機顏色偏差
什麼是最快和最簡單的方法來產生這些數字?
將RGB顏色轉換爲HSL,保持色相,例如用小的隨機數導出飽和度和亮度(亮度),然後轉換回RGB。
老實說,我不知道的十六進制代碼是如何制定出飽和度/亮度,所以我會轉換爲HSL:
http://serennu.com/colour/rgbtohsl.php
改變你想要的,然後改回來。我看到唯一的一個主要缺點就是HSL在Hex字段中不存在的可能性。
如,
HSL色彩空間具有唯一的360×100×100 = 3600000 在它的顏色,而RGB顏色空間具有256×256×256 = 16,77,216顏色在裏面,這是四倍半。
我知道這個問題是一歲,但我四處尋找解決方案,找不到它。
但基於這裏和那裏的建議(主要是在SO)我創建了準備好使用腳本。
通知1:colorToRGB
功能不可靠。我在SO中發現它(來源附件)。我改變了一些顏色的十六進制值,但我不想檢查它們全部。爲獲得最佳效果,請使用十六進制值
通知2:deviation
在generateSimilarColor
函數是爲我的目的而設置的。你可以改變它以獲得更好的結果。
通知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>
任何錯誤或建議 - 請寫。
如果您使用的是現代瀏覽器,實際上可以使用HSL而不是使用十六進制指定顏色。這應該讓你的任務變得非常簡單。 HTTP://www.css3。info/preview/hsl/ –
@BrianGlaz:這是一個精巧的小技巧,但不幸的是,我試圖保持瀏覽器兼容性,即使使用IE。 –