Home > database >  Cycled animation for a series of images stack on top of eachother with transitions
Cycled animation for a series of images stack on top of eachother with transitions

Time:11-23

As per the title, I am trying to create a JS script that cycles through a series of images in the same <div>. The images will be cycled through to create a smooth animation. So far, I have this. The images cycle through but without a smooth transition.

var slideIndex = 0;

showSlides();

function showSlides() {
  var i;
  var slides = document.getElementsByClassName("mySlides");
  
  for (i = 0; i < slides.length; i  ) {
    slides[i].style.display = "none";
    slides[i].style.opacity = "0";
  }
  
  slideIndex  ;
  
  if (slideIndex > slides.length) {
    slideIndex = 1
  }
  
  slides[slideIndex - 1].style.display = "block";
  slides[slideIndex - 1].style.opacity = "1";
  setTimeout(showSlides, 2500);
  // Add a transition to the images.
  slides[slideIndex - 1].style.transition = "all 2.50s";
  // Add a delay to the images.
  slides[slideIndex - 1].style.transitionDelay = "2.50s";
}
<div >
  <img src="https://picsum.photos/200?1"  alt="">
  <img src="https://picsum.photos/200?2"  alt="">
  <img src="https://picsum.photos/200?3"  alt="">
  <img src="https://picsum.photos/200?4"  alt="">
  <img src="https://picsum.photos/200?5"  alt="">
</div>

CodePudding user response:

I think the standard way to solve this problem is to keep all images display: block, and just change opacity so that you can fade it continuously. (Alternatively, you could set display: none to images once they are completed faded out.)

For this to work, you need the images to render on top of each other. This is possible via position: absolute, provided you can size your containing element (your p-centered div) manually. For example:

let slideIndex = 0;

function showSlides() {
  const slides = document.getElementsByClassName("slide");
  // Hide existing shown slides
  for (let i = 0; i < slides.length; i  ) {
    slides[i].classList.remove('show');
  }
  // Show current slide
  slides[slideIndex % slides.length].classList.add('show');
  slideIndex  ;
}

window.addEventListener('load', () =>
  setInterval(showSlides, 2500));
.container {
  height: 274px; /* maximum image height */
}

.slide {
  position: absolute;
  opacity: 0; /* hide until `show` class */
  transition: opacity 0.5s;
}
.slide.show {
  opacity: 1;
}
<h1>Before Container</h1>

<div >
  <img  src="https://www.wikipedia.org/portal/wikipedia.org/assets/img/[email protected]">
  <img  src="https://www.wikiversity.org/portal/wikiversity.org/assets/img/Wikiversity-logo-tiles_1.5x.png">
</div>

<h1>After Container</h1>

CodePudding user response:

You just need one class which uses the Opacity & Transition.

Activate the Class using JavaScript.

I also updated your JS code a bit so, now you don't have to iterate through all the images every time to hide them.

var slides = document.getElementsByClassName("mySlides");
var slideIndex = 0;

// Sow the First Image Initially
slides[0].classList.add("show");

setInterval(showSlides, 2500);

function showSlides() {
  // Hide Current
  slides[slideIndex].classList.remove("show");

  // Change Index
  slideIndex  ;
  if (slideIndex >= slides.length) {
    slideIndex = 0
  }
  
  // Show New Current
  slides[slideIndex].classList.add("show");
}
.p-centered {
  position: relative;
}

.mySlides {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0;
  transition: all 2000ms;
}

.mySlides.show {
  opacity: 1;
}
<div >
  <img src="https://picsum.photos/200?1"  alt="">
  <img src="https://picsum.photos/200?2"  alt="">
  <img src="https://picsum.photos/200?3"  alt="">
  <img src="https://picsum.photos/200?4"  alt="">
  <img src="https://picsum.photos/200?5"  alt="">
</div>

CodePudding user response:

Here is an example uses display: grid to place the images in stack.

It keeps the basic structure of the original code, but moves some static styling to CSS to keep the JavaScript code more focused.

Hope it will help!

Example:

var slideIndex = 0;
var slides = document.getElementsByClassName("mySlides");

// Moved some static styles to CSS to keep it clean here
showSlides();

function showSlides() {
  // Show the current image
  slides[slideIndex].style.opacity = "1";      
  // Hide the previous image
  slides[slideIndex === 0 ? slides.length - 1 : slideIndex - 1].style.opacity =
    "0";
  // Add index for next cycle
  slideIndex === slides.length - 1 ? (slideIndex = 0) : slideIndex  ;
  // Set delay for next cycle
  setTimeout(showSlides, 2500);
}
.p-centered {
  display: grid;
  width: fit-content;
}

.mySlides {
  grid-area: 1/ 1/ 1 /1;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.50s linear;
}
<div >
  <img src="https://picsum.photos/200?1"  alt="">
  <img src="https://picsum.photos/200?2"  alt="">
  <img src="https://picsum.photos/200?3"  alt="">
  <img src="https://picsum.photos/200?4"  alt="">
  <img src="https://picsum.photos/200?5"  alt="">
</div>

  • Related