Update the background image every minute with a smooth transition effect

I am currently in the process of developing a personal dashboard that requires dynamic background images to change every minute. To achieve this functionality, I have integrated the [Pixabay API][1] and formulated the following API request:

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

This API request returns an array of 100 elements, each containing various information such as image details, likes, views, and user information.

From this array, I randomly select one element, retrieve the largeImageURL, and set it as the background image of the dashboard with a semi-transparent overlay for better readability. This process is initiated within a setInterval function that runs every x milliseconds.

The code snippet for implementing this feature is:

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);

The 'getBackgroundImages.php' file simply outputs the content of the API request.

While the existing solution works, there is a brief period where the background turns grey before the new image is displayed, which is not visually appealing especially during frequent image changes. I am seeking advice on how to seamlessly transition between background images without the grey background flash.

One proposed solution involves displaying a blurred preview of the image before loading the full resolution version. However, I believe this workaround should not be necessary as the image has ample time to load before the background change occurs. I am open to adjusting the timing of the image change as long as it ensures a smooth transition without interruptions.

If anyone has suggestions on how to enhance this implementation, I would greatly appreciate your input. Thank you in advance! [1]:

Answer №1

One way to create an interesting visual effect is to switch between two background containers in your HTML code:

Markup:

<body>
    <div class='bg' id='firstBg'></div>
    <div class='bg' id='secondBg'></div>

    <...Your Content...>

</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;
}

JavaScript:

setInterval(function(){
    $.post('updateBackgroundImages.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);

Answer №2

With the help of @zero298's hint, I implemented the following solution:

<script>
function loadImages (images) {
  let loader = function (src) {
    return new Promise(function (resolve, reject) {
      let img = new Image();
      img.onload = function () {
        resolve(src);
      };
      img.onerror = function (err) {
        reject(err);
      };
      img.src = src;
    });
  };

  let loaders = [];
  images.forEach(function (image) {
    loaders.push(loader(image));
  });

  return Promise.all(loaders);
}

 function cycleImages (images) {
    let index = 0;
    setInterval(function() {
      $('body').css("background","linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)),url('"+images[index]+"')");
      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>

This solution efficiently loads all images using Promises and displays them without delays. However, the transition between images is not as smooth as desired. Implementing transitions using jQuery's fade-to method resulted in fading out the page content along with the background image.

Modifying the page structure by adding more divs was challenging due to existing CSS rules like floating and positioning. Attempting to wrap all content in a div to apply a background image disrupted the layout.

In conclusion, while I am satisfied with this solution, any suggestions for achieving smoother image transitions are welcome!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Encountering issues with createReadStream function when handling large files, performance is significantly

Currently, I am utilizing the DropBox API for file uploads. The process involves several steps: Begin by uploading the file from a form to a local directory on the server. Read the file from the local directory using fs.createReadStream. Transfer the fil ...

Prevent clicking during transitions with Jquery Cycle

Is there a way to prevent multiple transitions by restricting the clicking of the next button? Thank you! ...

JQuery If Statement always outputs a consistent number regardless of the input provided

I'm facing an issue with my HTML form and JQuery code that is supposed to calculate a figure. The problem I am encountering is that the if statement always returns the same number, regardless of the input: $(document).ready(function() { ...

Prevent the utilization of <span> tags for line breaks to

When resizing my window to a smaller size, I encountered some unsightly spans that cut into new lines. To demonstrate this issue, I intentionally set the width:20px;. Can this problem be avoided? <link href="https://maxcdn.bootstrapcdn.com/bootstrap/ ...

Shifting an image to the corner using HTML and CSS

As I work on designing a coming soon page, my goal is to have the voter's hand extend all the way to the edge of the screen by cutting off parts of the sleeve. Can you provide some guidance on what modifications are needed in the css/html code for thi ...

Sending properties within components using #createElement in React-Router is a convenient way to pass data locally

Have you ever wondered where the parameters Component and props are coming from in the React-Router documentation? // Here is the default behavior function createElement(Component, props) { // ensure all props are passed in! return <Component {... ...

What is the functionality of the save callback in Mongoose?

Currently in the process of learning about Mongoose's save() function for the MEAN stack. This particular function requires a callback as outlined in its API documentation: Model#save([options], [fn]) Saves this document. Parameters: [options] < ...

Is there a way to pull information from a string and organize it into a two-dimensional array?

Utilizing the axios library, I am pulling data from a website. Unfortunately, the data being fetched is in HTML format. The extracted data looks like this: 1 Agartala VEAT 120830Z 23004KT 5000 HZ SCT018 SCT025 34/27 Q1004 NOSIG= 2 Ahmedabad VAAH 120830Z 23 ...

Is there a syntax problem with the jQuery (this).next() statement that is causing it to not

Struggling with the implementation of a .next() selector. It seemed straightforward, but I must be missing something. Here's the current script that is not functioning as expected: $('.ITEM').hover(function (){ $(this).next('.ITEM ...

Ajax is failing to produce any source code at the moment

After implementing a script on my website to create a chained selection system, I encountered an issue when trying to incorporate the generated data into my search script. Unfortunately, it seems that the source code produced is not usable for this purpose ...

Having trouble with Angular 2's Output/emit() function not functioning properly

Struggling to understand why I am unable to send or receive some data. The toggleNavigation() function is triggering, but unsure if the .emit() method is actually functioning as intended. My end goal is to collapse and expand the navigation menu, but for ...

Struggling to align an element in HTML when used in columns?

<div class="row"> <div class="col-lg-3 " style="border: groove;"> <p class="circle col-xs-1 center-block">01</p> <h3>trending courses</h3> ...

Broken links detected in the Full Page Navigation menu on a one-page website

The hyperlinks on this particular page seem to be malfunctioning despite the fact that the li.a tags are correctly targeting specific section IDs. Markup: <header> <a href="#0" class="nav_icon"><i></i></a> </header> ...

Learning how to replace the alert function with Bootbox

I am currently working on a form that posts to a MySQL database. I want to replace the alert function triggered by the Malsup jQuery Form Plugin with the one created by the Bootbox plugin. Even though both plugins are functional, I struggle to integrate th ...

Tips for sending form data from ReactJS to controller in ASP.NET MVC:

Seeking help with React and ASP.NET integration. I am attempting to create a form in ASP.NET using React, but encountering issues when trying to pass form data from ReactJS to an MVC ASP.NET controller. Below is the code that I have been working on. Any su ...

What steps can be taken to prevent a "Flash of Unstyled Content" when using fixed-width cells in CSS Tables?

My website's design is heavily influenced by CSS tables. This decision was made to ensure consistent cell heights regardless of the content, making alignment easier. Overall, this method has been quite effective. However, there is an issue where the ...

Callback function not being triggered in Jquery's getJson method

I am currently faced with a javascript conundrum. Below is the snippet of code that I have been working on: $.get("categories/json_get_cities/" + stateId, function(result) { //code here }, 'json' ); ...

Using a button click to toggle the vue-ctk-date-time-picker in VueJS

Currently, I am utilizing the Vue component - https://github.com/chronotruck/vue-ctk-date-time-picker within my own component. However, I am encountering an issue where I would like to maintain the component's original functionality while having a but ...

What is the proper syntax for using an external JavaScript data source with jQuery UI autocomplete?

Thank you for taking the time to read this. I am working on customizing the jQuery UI autocomplete search feature to display clickable link results, and so far, I have been successful in my efforts by referencing code from another query on this forum. My ...

Is it possible to spread an empty array in JavaScript?

Whenever I run the code below, I encounter the error message Uncaught SyntaxError: expected expression, got '...': [1,2,3, (true ? 4 : ...[])] I'm wondering if spreading an empty array in that manner is allowed? ...