首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用过渡每分钟更改一次背景图像

使用过渡每分钟更改一次背景图像
EN

Stack Overflow用户
提问于 2020-08-12 21:15:25
回答 2查看 302关注 0票数 2

我现在正在做一个私人仪表盘。这个仪表板应该有不断变化的背景图像,每分钟变化一次(如果我当时让它工作,切换到一个小时或20秒应该没有问题)。

为此,我注册了Pixabay API并创建了以下API请求

https://pixabay.com/api/?key=[my_key]f&q=nature&image_type=photo&orientation=horizontal&min_width=1920&min_height=1080&page=1&per_page=100

通过这个请求,我得到了一个包含100个元素的数组,每个元素都包含以下信息:

代码语言:javascript
复制
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毫秒就会发生一次。

这是它的代码:

代码语言:javascript
复制
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,0,0,.3), rgba(0,0,0,.3)),url('"+imageLink+"')");
    });
},60000);

`getBackgroundImages.php‘除了打印API-request的内容之外,什么也不做。

现在的问题是:在实现的解决方案中,一切正常,新照片显示为背景,切换工作。然而,在显示图像之前,背景总是被设置为灰色背景大约半秒,这看起来真的不太好,特别是当经常切换图像时。

我想得到的是在短时间内没有灰色背景的背景切换,甚至可能是过渡,所以变化不是那么突然……

我找到了一个解决方案,首先显示图像的模糊预览,然后再显示全分辨率预览。然而,我认为这不应该是必要的,因为基本上,图像有足够的时间加载,并且在图像加载后背景应该会改变。我不关心更改是否每隔62秒发生一次,即使我将其设置为60秒,因为需要首先加载图像。

有没有人能给我一个提示,让它更好地工作?

提前感谢!1:https://pixabay.com/api/docs/

EN

回答 2

Stack Overflow用户

发布于 2020-08-12 21:53:07

也许最简单的方法是交替使用两个类似于背景的容器:

HTML:

代码语言:javascript
复制
<body>
    <div class='bg' id='firstBg'></div>
    <div class='bg' id='secondBg'></div>

    <...Your Stuff...>

</body>

CSS:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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);
票数 0
EN

Stack Overflow用户

发布于 2020-08-12 22:06:44

多亏了@zero298的提示,我现在执行了以下解决方案。

代码语言:javascript
复制
<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,0,0,.3), rgba(0,0,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","linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)),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>

这首先将所有imageUrls放入一个数组中,然后使用Promise加载所有图像,然后显示,然后不会有大的延迟。我真的没有设法在切换图像之间实现良好的过渡,因为jQuery的淡入淡出方法可以让页面的内容也淡出,而不仅仅是背景图片……

顺便说一句,添加更多的div/改变页面的结构并不太容易,因为有很多浮动和其他css规则来使元素出现在页面上的不同位置。在所有内容周围添加div,以便尝试为该div提供背景图像,从而破坏了孔布局……

总而言之,我对这个解决方案很有信心,但是,如果有人有一个好主意让切换更顺利,请随时告诉我:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63377334

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档