JavaScript,从起始颜色到结束颜色中随机选择一个十六进制颜色。

5
有没有快速完成这个任务的方法?
例如,起始颜色#EEEEEE和结束颜色#FFFFFF会生成类似于#FEFFEE的颜色。

将其转换为HSLA,然后独立地在两个范围内选择H、S、L和A,再转换回十六进制,这种方法可行吗? - Joe Frambach
你可以使用与PHP中hexdec函数等效的方法,实际上像计算数字一样计算十六进制颜色:http://phpjs.org/functions/hexdec/ - benomatis
5个回答

15

当然,十六进制编码成为数字,但要使其有任何意义,首先必须提取RGB组件:

function rgb(string){
    return string.match(/\w\w/g).map(function(b){ return parseInt(b,16) })
}
var rgb1 = rgb("#EEEEEE");
var rgb2 = rgb("#FFFFFF");

然后只需取所有组件的中间值:

var rgb3 = [];
for (var i=0; i<3; i++) rgb3[i] = rgb1[i]+Math.random()*(rgb2[i]-rgb1[i])|0;

最后,将颜色重建为标准的十六进制字符串:

var newColor = '#' + rgb3
    .map(function(n){ return n.toString(16) })
    .map(function(s){ return "00".slice(s.length)+s}).join(''); 

请注意,在追求更好的结果时,根据您的目标,例如如果您想保持亮度,则使用与RGB不同的颜色空间(例如HSL或HSV)可能会有用。


1

d3 通过创建颜色比例尺的方式非常出色地完成了这一点:

var color = d3.scale.linear()
    .domain([-1, 0, 1])
    .range(["red", "white", "green"]);

color(-1)   // "#ff0000" red
color(-0.5) // "#ff8080" pinkish
color(0)    // "#ffffff" white
color(0.5)  // "#80c080" getting greener
color(0.7)  // "#4da64d" almost there..
color(1)    // "#008000" totally green!

如何为条形图指定此内容。我可能有10个数据点或100个数据点...如何处理这种不同的数据范围。 - user5249203

0

如果我正确理解了问题,您想要每个数字都处于相同的范围内。您是指每个数字还是每个组件(颜色通道)?对于每个数字,请参见我的fiddle

关键在于:

for(var i = 0;i < 6; i++) {
    color += (Math.floor(Math.random() * (end-start+1)) + start).toString(16);
}

起始和结束都是从0到15

对于每个通道:

for(var i = 0;i < 3; i++) {
    color += (Math.floor(Math.random() * (end-start+1)) + start).toString(16);
}

起始和结束值应在0到255之间


2
你确定他不想要一个值在0xEE和0xFF之间的0xF0吗?那将会令人惊讶。 - John Dvorak
不确定,因为他的问题没有被问得非常明确,但根据他的例子,在进行了几次测试运行后(start = 13 end = 15),它给了我 #feefef #ffeeff #eeffff #fffeef #fffffe。 - SeDav
你指的是哪个例子?我在这个问题周围没有看到提问者发布任何链接。 - John Dvorak
我在我的fiddle中提供的示例生成了那些颜色,指的是他的问题“_...#EEEEEE和结束颜色#FFFFFF会产生类似#FEFFEE的效果。” - SeDav
我不认为您可以使用解释的结果作为证明该解释是正确的 :-) - John Dvorak
1
我点赞了@dystroy的答案,但是我还是试着回答了这个问题,根据我的理解。如果我错了,很抱歉,但是现在人们对问题的描述不够清晰,这让SO的新手很难在短时间内给出适当的答案。我只是尽力帮忙... - SeDav

0

Denys Séguret的版本在ES6中

const rgb = string => string.match(/\w\w/g).map(b => parseInt(b, 16))
const rgbrnd = (rgb1, rgb2) => {
  const rgb3 = [];
  for (let i = 0; i < 3; i++) rgb3[i] = rgb1[i] + Math.random() * (rgb2[i] - rgb1[i]) | 0;
  return '#' + rgb3
    .map(n => n.toString(16).padStart(2, '0'))
    .join('');
};


const rgb1 = rgb("#00FF00"); // green 
const rgb2 = rgb("#FF0000"); // red
console.log(rgbrnd(rgb1, rgb2))


-1

尝试:

function getRandomColor(start, end){
    var min=parseInt(start.replace("#",""), 16);
    var max=parseInt(end.replace("#",""), 16);
    return "#"+Math.floor((Math.random() * (max - min) + min)).toString(16).toUpperCase();
}    

这里有一个Fiddle,可以让你试一下。


每个组件不需要一个中间件。 - Denys Séguret
3
点赞的人不了解什么是色彩,这会导致出现像#F493F1这样的颜色。 - Denys Séguret
它做了TO想要的:一个随机颜色。没有多余的东西。 - Thomas Junk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接