Javascript 使用RGBaster.js控制多幅图像的颜色
我有这段代码,找到图像的主导颜色(使用),然后将其转换为平面颜色,并给图像旁边的信息框颜色。同时,它使文字颜色在YIQ scala之后变为白色或黑色Javascript 使用RGBaster.js控制多幅图像的颜色,javascript,jquery,foreach,Javascript,Jquery,Foreach,我有这段代码,找到图像的主导颜色(使用),然后将其转换为平面颜色,并给图像旁边的信息框颜色。同时,它使文字颜色在YIQ scala之后变为白色或黑色 function getContrastYIQ(hexcolor){ var r = parseInt(hexcolor.substr(1,2),16); var g = parseInt(hexcolor.substr(3,2),16); var b = parseInt(hexcolor.substr(4,2),16);
function getContrastYIQ(hexcolor){
var r = parseInt(hexcolor.substr(1,2),16);
var g = parseInt(hexcolor.substr(3,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
return (yiq >= 128) ? 'black' : 'white';
}
var img = $('.category').attr('data-background');
var colors = RGBaster.colors(img, {
paletteSize: 5,
success: function(colors){
console.log("-----------------------------------------------");
console.log("Dominant color:", colors.dominant);
console.log("-----------------------------------------------");
var rgb = colors.dominant;
rgb = rgb.substring(4, rgb.length-1).replace(/ /g, '').split(',');
var flatColors = FlatColors(rgb);
var flatColor = flatColors[3];
var textColor = getContrastYIQ(flatColor);
console.log(textColor);
$(".category").css('background-image', 'url(' + img + ')');
$(".category .info").css('background-color', flatColor);
$(".text").css('color', textColor);
$(".text").text(flatColors[4]);
}
});
问题来了
我有多个div,名称如下:
<div class="category" data-background="images/7.jpg">
<div class="info">
<p class="text">Hello World</p>
</div>
</div>
但那没用。所以现在我需要一些帮助。你需要承诺 您有一个回调操作—比代码的其余部分触发得晚:
function colorPick(img) {
RGBaster.colors(img, {
paletteSize: 5,
success: function(colors){
var rgb = colors.secondary;
rgb = rgb.substring(4, rgb.length-1).replace(/ /g, '').split(',');
var flatColors = FlatColors(rgb);
console.log("Return:", flatColors[3]);
return flatColors[3]; // returns the parent function, success
}
});
// colorPick itself doesn't return at all, which is why you get undefined
}
您需要返回一个承诺
——一个保存异步操作并在其完成时解析的对象:
function colorPick(img) {
// Now colorPick returns the promise
return new Promise(function(resolve, reject) {
RGBaster.colors(img, {
paletteSize: 5,
success: function(colors){
var rgb = colors.secondary;
rgb = rgb.substring(4, rgb.length-1).replace(/ /g, '').split(',');
// Check this shouldn't be "new FlatColors", as CapitalCase usually means it needs "new"
var flatColors = FlatColors(rgb);
console.log("Return:", flatColors[3]);
// Resolve the promise
// I've passed it the FlatColors object so the callback can access all of it
resolve(flatColors);
}
});
});
}
然后,您可以使用。然后使用:
$('.category').each(function(){
var $this = $(this); // avoid calling multiple times
var img = $this.attr('data-background');
$this.css('background-image', 'url(' + img + ')');
// .then fires the function when the promise completes.
colorPick(img).then(function(colors) {
var flatColor = colors[3];
// Set the background colour
$this.find('.info').css('background-color', flatColor);
var textColor = getContrastYIQ(flatColor);
var $text = $this.find('.text');
$text.css('color', textColor);
$text.text(colors[4]);
return colors;
}).then(console.log); // You can chain promises
});
或者使用async
/await
语法:
$('.category').each(async function(){
const $this = $(this); // avoid calling multiple times
const img = $this.attr('data-background');
// If we can use async/await we can also use const and iterpolated strings
$this.css('background-image', `url(${img})`);
// await continues this function after the promise completes
const color = await colorPick(img);
const flatColor = colors[3];
// Set the background colour
$this.find('.info').css('background-color', flatColor);
const textColor = getContrastYIQ(flatColor);
const $text = $this.find('.text');
$text.css('color', textColor);
$text.text(colors[4]);
console.log(colors);
});
我建议您等待
,但如果您支持较旧的浏览器,您可能需要传输您的JS,因为它是相当新的
该方法一次解析一种颜色,但您可能需要比较多种颜色的结果。方法是使用Promise.all
,它等待承诺集合完成,然后返回其结果数组:
// Get the dominant colours in all the images on one array
const colors = await Promise.all(
images.map(i => colorPick(i)));
它将所有图像映射到一个承诺数组,所有图像都等待colorPick
函数完成,然后等待所有图像完成
最后,您的问题已标记为的副本。这个问题的首要答案是关于使用Promissions和async/await的详细信息,比我这里介绍的要详细得多。仔细想想,返回值会到哪里去?@Teemu I用其余的更新代码;)因此,您可以查看函数colorPick
也必须return@MasterYoda1.很棒的昵称。2.你是什么意思?@TheCrazyProfessor编辑之前我知道它要去哪里,但我想让你回答这个问题。我同意,原因并不总是很明显(只看一些问题评论(现在已删除)),这个问题每天被问10次。问题是相同的,解决方案是相同的,因此重复。副本提供了大量信息,包括使用Promissions和Wait的版本,每次询问此问题时(以任何形式)复制部分信息是没有意义的。问题完全相同。这里的问题是,为什么回调中的返回不能像OP所期望的那样工作。他们不知道异步回调是如何工作的,因此无法提出正确的问题,但这正是他们需要问的问题。@Keith这个网站不是这样工作的。OP需要转到链接副本并阅读问题。代码示例实际上与他们的完全相同,即使他们问的问题不完全相同。一旦他们阅读了这个问题,他们应该更好地理解为什么答案是正确的。@Keith你应该按照这个规则关闭这个网站上80%的问题。像这样的问题一天会被问十几次,而我们的问题中没有“承诺”或“异步”这两个词。它们都应作为链接问题的副本关闭。这个网站的重点是提供规范的答案,而不是为人们能想到的同一个问题的每一个变体提供唯一的答案。你提供的答案比那些非常全面的答案更糟糕,这并没有帮助OP,你也没有帮助网站。你似乎只对展示你的知识感兴趣,否则你会更乐意将人们与现有的更好的答案联系起来。欢迎您继续回答问题,而不是链接到现有的重复问题,但是当您的答案与重复问题一起被删除时,请不要感到惊讶。
// Get the dominant colours in all the images on one array
const colors = await Promise.all(
images.map(i => colorPick(i)));