Julio Rodríguez
Julio Rodríguez

Reputation: 477

Issue creating a carousel with html CSS and javascript

I'm trying to create a carousel using just HTML, CSS and JS.

It works, but not as well as I was hoping for.

When it finishes one round of images, it takes roughly 8 seconds to start showing the images from the first to the last one, and then it stops again for several seconds and so on...

Additionally, the div containing the background-images is 100% width and 100vh height. I've tried to set the background properties like bg-repeat, bg-size, bg-position, but I can't manage to get the images to display well on the screen - They images become cropped when set background-size: cover, and become too small if I set background-size: contain; or another property.

Can you please check this "working" demo? Thanks.

var divi = document.querySelector(".divi");
srcArr = ["https://picsum.photos/id/237/200/300", "https://picsum.photos/id/238/200/300", "https://picsum.photos/id/239/200/300", "https://picsum.photos/id/240/200/300"];
var iter = 0;

setInterval(function() {
  if (iter == (srcArr.length)) {
    iter = 0;
  } else {
    divi.style.backgroundImage = "url('" + srcArr[iter] + "')";
    iter++;
  }
}, 4000);
* {
  padding: 0;
  margin: 0
}

.divi {
  width: 100%;
  height: 100vh;
  background-image: url("https://picsum.photos/id/240/200/300");
  background-repeat: no-repeat;
  -webkit-background-size: cover;
  background-size: cover;
}
<div class="divi"></div>

Upvotes: 0

Views: 84

Answers (2)

Tyler Roper
Tyler Roper

Reputation: 21672

Every four seconds, you run an if statement, and only if it evaluates to false do you change the image. That means that each time it evaluates to true (when it gets to the end of the array), it has to run through two iterations to continue (which in this case takes 8 seconds).

Personally, I prefer to put things like this in functions, and using a recurring setTimeout over a setInterval. I've also returned that timeout in the event you want to stop the slideshow at some point.

In regards to your background, that's a pretty broad question. For starters, I've just applied background-position: center;.

const divi = document.querySelector(".divi");
const srcArr = ["https://picsum.photos/id/237/200/300","https://picsum.photos/id/238/200/300","https://picsum.photos/id/239/200/300", "https://picsum.photos/id/240/200/300"];
const timer = 1000;

const nextImg = (imageArray, index) => {
  divi.style.backgroundImage = `url('${imageArray[index]}')`;
  index = ++index % imageArray.length;
  return setTimeout(()=>nextImg(imageArray, index), timer);
};

const startSlideshow = imageArray => nextImg(imageArray,0); 

//Start slideshow
const slideshow = startSlideshow(srcArr);

//Stop slideshow
//clearTimeout(slideshow);
* {
  padding: 0;
  margin: 0
}

.divi {
  width: 100%;
  height: 100vh;
  background-repeat: no-repeat;
  -webkit-background-size: cover;
  background-size: cover;
  background-position: center;
}
<div class="divi"></div>

Upvotes: 0

Mister Jojo
Mister Jojo

Reputation: 22431

As Tyler Roper says, when (iter == srcArr.length) iter go on zero value but didn't change the image, so for the next one they wait 4 seconds more.

const
  divi   = document.querySelector(".divi"),
  srcArr = ["https://picsum.photos/id/237/200/300", "https://picsum.photos/id/238/200/300", "https://picsum.photos/id/239/200/300", "https://picsum.photos/id/240/200/300"];
var iter = -1;

setInterval(function() {
  iter = (iter + 1) % srcArr.length;
  divi.style.backgroundImage = "url('" + srcArr[iter] + "')";
}, 4000);
* {
  padding: 0;
  margin: 0
}

.divi {
  width: 100%;
  height: 100vh;
  background-image: url("https://picsum.photos/id/240/200/300");
  background-repeat: no-repeat;
  -webkit-background-size: cover;
  background-size: cover;
}
<div class="divi"></div>

Upvotes: 1

Related Questions