-1

I'm trying to get the background image of a certain div, to change/cycle through an array of images using the following code.

It works as supposed, only thing I have no idea is how to implement a fade in/fade out transition effect when it comes to JS. I tried it in CSS, but it only affects the very first load of the first image, when the whole page is loaded.

Can you please help me implement a fade transition between images?

function displayNextImage() {
    x = (x === images.length - 1) ? 0 : x + 1;
    document.getElementById("slider-background").src = images[x];
}
function changeImage() {
    setInterval(displayNextImage, 5000);
}

var images = [], x = -1;
images[0] = "https://www.example.com/1.jpg";
images[1] = "https://www.example.com/2.jpg";
images[2] = "https://www.example.com/3.jpg";
Md. Rakibul Islam
  • 2,140
  • 1
  • 7
  • 14
emiliano85
  • 129
  • 10
  • usually you would have separate images and absolutely position them on top of each other and cycle through them and add a class to the active one to trigger a transition to fade it in whilst removing the class from the previous active which would fade it out at the same time. The way you are doing it, you would have to fade the image out first, once the animation completes, then you would need to change the src, after that you would need to fade it back in - but this way you wouldn't have a transition between images, your image would completely disappear before the next image shows – Pete Aug 09 '23 at 08:54
  • 2
    This is also possible with [CSS background images](https://stackoverflow.com/questions/7318462/changing-background-image-with-css3-animations) – DBS Aug 09 '23 at 09:01
  • This tutorial helps you : https://www.tutorialspoint.com/how-to-add-fade-out-effect-using-pure-javascript – kjain Aug 09 '23 at 09:11
  • `Tried in CSS, but it only affects the very first load of the first image` you probably did it wrong – Jaromanda X Aug 09 '23 at 09:19

2 Answers2

2

Okay so first you'll need to update your css with this id:

#slider-background {
  transition: opacity 1s ease-in-out;
  opacity: 1;
}

Next, you'll need to add quite some stuff in ur javascript file. I commented everything so I hope it's understandable.

function displayNextImage() {
  var element = document.getElementById("slider-background");
  // Fade out the current image
  element.style.opacity = 0;
  // Wait for the fade out transition, then change the image and fade it back in
  setTimeout(function() {
    x = (x === images.length - 1) ? 0 : x + 1;
    element.style.backgroundImage = "url('" + images[x] + "')";
    element.style.opacity = 1;
  }, 1000); // This duration should match the transition duration in your CSS
}

function changeImage() {
  setInterval(displayNextImage, 5000); // Change this time to control the speed of the slide
}

var images = [], x = -1;
images[0] = "https://www.example.com/1.jpg";
images[1] = "https://www.example.com/2.jpg";
images[2] = "https://www.example.com/3.jpg";

// Don't forget to call the changeImage function somewhere to start the slideshow
changeImage();

The code makes a picture slowly vanish, then waits a bit, switches to a new picture, and makes that picture slowly appear. It makes sure the timing matches up so it looks smooth.

MaikeruDev
  • 1,075
  • 1
  • 19
  • Nice thank you MaikeruDev. I was hoping for a transition without the white background showing in between images fading in/out, but i guess i need to layer the images on top of each other, and amend the code accordingly to make it work that way. – emiliano85 Aug 09 '23 at 12:13
  • Certainly! You would need to layer two images and fade one out while fading the other in. This way, you avoid any gaps in the transition and create a smooth effect. Not quite sure bit this may work. https://pastebin.com/Xn05BCs1 – MaikeruDev Aug 09 '23 at 12:40
0

Other solution (include using opacity and preloading images):

let images = [], x = 0;
images[0] = "https://via.placeholder.com/100/FF0000/FFFFFF/?text=Image_1:.*";
images[1] = "https://via.placeholder.com/100/0000FF/FFFFFF/?text=Image_2:.*";
images[2] = "https://via.placeholder.com/100/00FF00/000000/?text=Image_3:.*";
    
function displayNextImage() {
    const image = document.getElementById("slider-background");
    x = (x === images.length - 1) ? 0 : x + 1;
    
    if (!image.classList.contains('show') || !image.classList.contains('showhide')) {
        image.classList.add('hide');
    }
    
    image.classList.replace('show', 'hide');
    setTimeout(() => {
        image.src = images[x];
        setTimeout(() => {
            image.classList.replace('hide', 'show');
        }, 400);
    }, 400);
}
    
function changeImage() {
    setInterval(displayNextImage, 5000);
}
    
changeImage();
.show {
    transition: opacity 400ms;
    opacity: 1;
}
.hide {
    opacity: 0;
    transition: opacity 400ms;
}
<link rel="preload" as="image" href="https://via.placeholder.com/100/FF0000/FFFFFF/?text=Image_1:.*">
<link rel="preload" as="image" href="https://via.placeholder.com/100/0000FF/FFFFFF/?text=Image_2:.*">
<link rel="preload" as="image" href="https://via.placeholder.com/100/00FF00/000000/?text=Image_3:.*">
    
<img src="https://via.placeholder.com/100/FF0000/FFFFFF/?text=Image_1:.*" alt="" id="slider-background" />
Oleh Kosarenko
  • 436
  • 2
  • 7