问题描述
我目前在私人仪表板上工作。此仪表板应具有每分钟更改的变化的背景图像(如果我可以正常工作,则将其切换为一个小时或20秒应该没问题)。
为此,我注册了[Pixabay API] [1],并创建了以下API请求
通过该请求,我得到了一个由100个元素组成的数组,每个元素包含以下信息:
comments: 639
downloads: 785498
favorites: 3020
id: 736885
imageHeight: 1195
imageSize: 186303
imageWidth: 1920
largeImageURL: "https://pixabay.com/get/51e3d34b4257b108f5d0846096293076123ddee2504c704c7c2879d79048c05a_1280.jpg"
likes: 3966
pageURL: "https://pixabay.com/photos/tree-sunset-amazing-beautiful-736885/"
previewHeight: 93
previewURL: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_150.jpg"
previewWidth: 150
tags: "tree,sunset,amazing"
type: "photo"
user: "Bessi"
userImageURL: "https://cdn.pixabay.com/user/2019/04/11/22-45-05-994_250x250.jpg"
user_id: 909086
views: 2042402
webformatHeight: 398
webformatURL: "https://pixabay.com/get/51e3d34b4257b10ff3d8992cc62f3f79173fd9e64e507440722d78d39248c7_640.jpg"
webformatWidth: 640
然后从这100个元素中随机选择一个,将largeImageURL
设置为背景,再加上一个半透明的深色覆盖层,以便能够更好地阅读其顶部的文本。所有这些操作都是在setInterval
内完成的,因此每隔x毫秒就会发生一次。
这是它的代码:
setInterval(function(){
$.post('getBackgroundImages.php',{ },function(data) {
var imageCollection = JSON.parse(data);
var imageNumber = Math.floor(Math.random() * 100);
var imageLink = imageCollection.hits[imageNumber].largeImageURL;
$('body').css("background","linear-gradient(rgba(0,.3),rgba(0,.3)),url('"+imageLink+"')");
});
},60000);
`getBackgroundImages.php'除了打印API请求的内容外,什么也没做。
现在的问题是:在已实施的解决方案中,所有功能均正常运行,新照片显示为背景,并且切换正常。但是,在显示图像之前,背景始终设置为灰色背景约半秒钟,这看起来确实不好,尤其是在经常切换图像时。
我想得到的是在短时间内没有灰色背景的背景下切换,即使有过渡也很可能,所以变化不是那么突然...
我找到了一种解决方案,可以先显示图像的模糊预览,然后再显示完整分辨率。但是,我认为不需要这样做,因为基本上,图像有足够的加载时间,并且背景应在图像加载后改变。.我不在乎,即使更改每隔62秒发生一次,即使我将其设置为60秒,因为图像需要先加载。
有人可以给我提示如何使它更好地工作吗?
提前谢谢! [1]:https://pixabay.com/api/docs/
解决方法
也许最简单的方法是在两个类似于背景的容器之间切换:
HTML:
<body>
<div class='bg' id='firstBg'></div>
<div class='bg' id='secondBg'></div>
<...Your Stuff...>
</body>
CSS:
body {
background: transparent;
}
.bg {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background-position: center;
z-index: -1;
background-size: cover;
transition: 3s ease-in;
}
#secondBg {
display: none;
}
JS:
setInterval(function(){
$.post('getBackgroundImages.php',{ },function(data) {
var imageCollection = JSON.parse(data);
var imageNumber = Math.floor(Math.random() * 100);
var imageLink = imageCollection.hits[imageNumber].largeImageURL;
if ($('#firstBg').css('display') == 'none') {
$('#firstBg').css("background-image","url('"+imageLink+"')");
$('#firstBg').fadeIn();
$('#secondBg').fadeOut();
}
else {
$('#secondBg').css("background-image","url('"+imageLink+"')");
$('#secondBg').fadeIn();
$('#firstBg').fadeOut();
}
});
},60000);
,
由于@ zero298的提示,我现在做了以下解决方案。
<script>
function loadImages (images) {
// each image will be loaded by this function.
// it returns a Promise that will resolve once
// the image has finished loading
let loader = function (src) {
return new Promise(function (resolve,reject) {
let img = new Image();
img.onload = function () {
// resolve the promise with our url so it is
// returned in the result of Promise.all
resolve(src);
};
img.onerror = function (err) {
reject(err);
};
img.src = src;
});
};
// create an image loader for each url
let loaders = [];
images.forEach(function (image) {
loaders.push(loader(image));
});
// Promise.all will return a promise that will resolve once all of of our
// image loader promises resolve
return Promise.all(loaders);
}
function cycleImages (images) {
let index = 0;
setInterval(function() {
// since we need an array of the image names to preload them anyway,// just load them via JS instead of class switching so you can cut them
// out of the CSS and save some space by not being redundant
$('body').css("background","linear-gradient(rgba(0,.3),rgba(0,.3)),url('"+images[index]+"')");
// increment,roll over to 0 if at length after increment
index = (index + 1) % images.length;
},28800000);
}
$(function(){
$.post('getBackgroundImages.php',function(data) {
var imageCollection = JSON.parse(data);
var imageNumber = Math.floor(Math.random() * 100);
var imageLink = imageCollection.hits[imageNumber].largeImageURL;
$('body').css("background",url('"+imageLink+"')");
});
$.ajax('getBackgroundImages.php',{
success:function(data) {
var parsed = JSON.parse(data);
var images = parsed.hits;
var imageUrls = [];
images.forEach(function(item,index){
imageUrls.push(item.largeImageURL);
})
loadImages(imageUrls).then(cycleImages).catch(function (err) {
console.error(err);
});
}
});
});
</script>
这首先将所有imageUrl放入一个数组中,然后使用Promise
加载所有图像然后显示,然后又没有太大的延迟。.我实际上并没有设法在切换图像之间获得很好的过渡,因为{ {1}}的淡入淡出方法也可使页面内容淡出,而不是仅背景图片...
顺便说一句,添加更多的div /更改页面的结构并不是一件容易的事,因为有很多浮动规则和其他css规则可以使元素出现在页面的各个位置。在所有内容周围添加一个div,以使该div的背景图像破坏了孔的布局...
总而言之,我对这种解决方案充满信心,但是,如果有人有一个很好的想法来使开关更平滑,请随时告诉我:)