我使用这个生成随机颜色代码:
var color = Math.floor(Math.random()*16777215).toString(16);
if( color.length === 5 )
{
color.concat('0');
}
但我想从中排除所有灰色阴影。我怎样才能做到这一点?
提前感谢您的帮助。
答案 0 :(得分:4)
一种方法是将一个颜色部分的范围限制为仅100个不同的值,而不是三个颜色部分中的2个,然后为它添加一些常量(即移位)。
要拍摄三个颜色部分的3个范围:
********************
************************************************
********************
| | | |
0 100 156 256
然后你会将这三个数字中的每一个分配给RGB组件,也可以随机分配,这样第一个值就可以用于R,G,B组件,第二个值用于剩下的两个组件,第三个用于剩下的那个。
最接近的颜色可以达到灰度级是第一个颜色部分最大化(99),最后一个最小化(156),中间颜色是这些值的一半(128)。如果你的颜色不是灰色,那么这个方案就可以了。否则,您可以根据需要减小两个较短范围的大小。
这导致以下代码:
function randomColor() {
const rangeSize = 100; // adapt as needed
const parts = [
Math.floor(Math.random()*256),
Math.floor(Math.random()*rangeSize),
Math.floor(Math.random()*rangeSize) + 256-rangeSize
].sort( (a, b) => Math.random() < 0.5 );
return parts.map( p => ('0' + p.toString(16)).substr(-2) ).join('');
}
// Sample
const divs = document.querySelectorAll('div');
for (const div of divs) {
div.style.background = '#' + randomColor();
}
&#13;
div {
height: 20px; width: 60px;
margin: 1px;
display: inline-block
}
&#13;
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div>
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div>
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div>
&#13;
您可以尝试两个较短范围的大小:它们现在的大小为100,但您可以将它们缩小以排除更多您仍可以找到的颜色&#34;灰色&#34;。您需要相应地调整常量rangeSize
。
以上将排除您可能仍然感兴趣的一些颜色,例如R,G和B的值都高于100的颜色,但不会产生(浅色)灰色的颜色。如果你真的希望能够得到任何颜色不是太灰,那么你可以:
颜色部分太靠近的情况可以描述如下:
* * *
|-------------|
| |
0 255
连字符显示最外层值必须具有的最小距离,因此将重新定位中间值。它必须放在以下两个范围之外:
* *
|-------------| (forbidden)
|-------------| (forbidden)
| |
0 255
所以必须进入以下任一范围:
* *
|--| |----------| (allowed)
| |
0 255
这种重定位可以通过从两个范围一起取一个范围内的随机值,然后检查该随机值是否落在第一个范围内来完成。如果没有,两者之间的差距就会增加。
以下是如何编码:
function randomColor() {
// Threshold can be between 0 and 127:
// the higher it is, the more colors are considered to be too grey-like.
const threshold = 50;
// Generate three color parts randomly
const parts = Array.from(Array(3), _ =>
Math.floor(Math.random()*256)
).sort( (a, b) => a-b );
// Check whether they are too close to the same value:
if (parts[2] - parts[0] < threshold) { // color is too greyish
// Replace the middle one with a random value outside of the "too close" range
const exclude = Math.min(255, parts[0] + threshold)
- Math.max(0, parts[2] - threshold);
parts[1] = Math.floor(Math.random()*(256-exclude));
if (parts[1] >= parts[2] - threshold) parts[1] += exclude;
}
// Shuffle and format the color parts and return the resulting string
return parts
.sort( (a, b) => Math.random() < 0.5 )
.map( p => ('0' + p.toString(16)).substr(-2) )
.join('');
}
// Sample
const divs = document.querySelectorAll('div');
for (const div of divs) {
div.style.background = '#' + randomColor();
console.log(div.style.background);
}
&#13;
div {
height: 20px; width: 60px;
margin: 1px;
display: inline-block
}
&#13;
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div>
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div>
<div></div> <div></div> <div></div> <div></div> <div></div> <div></div>
&#13;
与第一种解决方案一样,您可以更改一个值以影响灵敏度。它越高,重新定位的颜色部分必须离其他两个部分越远。
答案 1 :(得分:0)
最明显的方法(保持一致性)就是简单地拒绝它们
do
{
color = ...;
}
while( color[0]==color[2] && color[0]==color[4] &&
color[1]==color[3] && color[1]==color[5] );
请注意,找到灰色的概率(在形式为#RRR的意义上)是1/65536
,这将平均只循环约1次......
基于拒绝的抽样具有一般优势:如果您稍后改变主意,则只需更改拒绝标准。此外,只要拒绝概率足够小(但不 小,即使循环的一半的概率平均只评估两次),它也很快。
答案 2 :(得分:0)
灰色色谱为:R
= G
= B
编辑代码:
var color = Math.floor(Math.random() * 255).toString(16);
if (color.length === 1)
{
color.concat('0');
}
console.log('#'+color+color+color);
答案 3 :(得分:0)
想法是创建一个包含所有灰色阴影的数组。
创建十六进制代码,检查它是否在数组中并执行操作。
整个灰色阴影列表here
let allGreyShades = ['#000000','#080808','#101010']
// actually there is lot more .. 3 just for demo purposes;
let colorGenerated = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
if(allGreyShades.indexOf(colorGenerated) == -1) {
// your logic comes here
}
&#13;
答案 4 :(得分:0)
我会提取并比较三个八位字节,看看它们是否相同。当随机给出灰色阴影时,我只是将绿色部分反转以避免多次随机调用,但根据您的需要,您的策略可能会有所不同:
for (let i = 0; i < 20; i++) {
var div = document.createElement("div");
paint(div, randomColorExceptGray());
document.body.appendChild(div);
}
function paint (el, color) {
var rgb = colorToRgb(color);
el.style.backgroundColor = (
"rgb(" + rgb.join(",") + ")"
);
}
function randomColorExceptGray () {
var white = 0xFFFFFF;
var random = Math.random();
var color = Math.ceil(random * white);
var rgb = colorToRgb(color);
if (rgb[0] === rgb[1] === rgb[2]) {
return color ^ 0x00FF00;
} else {
return color;
}
}
function colorToRgb (color) {
var R = (color & 0xFF0000) >> 16;
var G = (color & 0x00FF00) >> 8;
var B = (color & 0x0000FF);
return [R, G, B];
}
div{height:50px;width:50px;float:left;margin:0 10px 10px 0}
这个解决方案真的很笨拙,但它并不关心0x000001
例如......这是一个更好的解决方案:https://stackoverflow.com/a/47616597/1636522。