Search code examples
javascriptslideshowtransitionfade

Adding fade transition effect and automatic image change


Hi I'm new to JavaScript and having difficulty creating the solution for this code I am developing.
I need to add a fade transition effect to my slideshow (an image changing into another one). The images should change automatically in addition to the already existing buttons. Here is the full code:
EDIT: I (@albert) put the code into the snippets and just grabbed the first two images I came across...

    var slideIndex = 1;
    showDivs(slideIndex);
    function plusDivs(n) {
    showDivs(slideIndex += n);
    }

    function currentDiv(n) {
    showDivs(slideIndex = n);
    }
    function showDivs(n) {
    var i;
    var x = document.getElementsByClassName("slides");
    var dots = document.getElementsByClassName("active");
    if (n > x.length) {slideIndex = 1}    
    if (n < 1) {slideIndex = x.length}
    for (i = 0; i < x.length; i++) {
    x[i].style.display = "none";  
    }
    for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace(" white", "");
    }
    x[slideIndex-1].style.display = "block";  
    dots[slideIndex-1].className += " white";
    }
    .circle{
     height:9px;
     width:9px;
     padding:0;
     background-color:#000;
     }
    .container{
             position:relative;
               max-width:800px;
               max-height:350px;
               overflow:hidden;
    }
    .centered{
             text-align:center;
               margin-bottom:16px;
               font-size:18px;
               color:white;   
           position:absolute;
               left:0;
               bottom:0;               
     }
    .left-arrow{
             float:left;
               padding-left:16px;
               cursor:pointer
     }
    .right-arrow{
             float:right;
               padding-right:16px;
               cursor:pointer
    }
    .arrow:hover{
               color:#b4aa50;
    }
    .arrow{
            -webkit-transition:background-color .3s,color .15s,box-shadow 
    .3s,opacity 0.3s;
             transition:background-color .3s,color .15s,box-shadow 
    .3s,opacity   0.3s;
    }
    .circle-b{
               border:1px solid #fff;
             background-color:transparent;
                   -webkit-transition:background-color .3s,color .15s,box-shadow 
    .3s,opacity 0.3s;
                   transition:background-color .3s,color .15s,box-shadow 
    .3s,opacity 0.3s;
    }
    .circle-b:hover{
               color:#000;
               background-color:#fff;                  
    }

    .white{
               color:#000;background-color:#fff}
    }
    <div class="container">
  
    <img class="slides" src="https://i.sstatic.net/b9ukx.png" style="width:100%">
    <img class="slides" src="https://i.sstatic.net/wx8jF.png" style="width:100%">
    
      <div class="centered" style="width:100%">
            <div class="left-arrow arrow" onclick="plusDivs(-1)">&#10094</div>
            <div class="right-arrow arrow" onclick="plusDivs(1)">&#10095</div>
            <span class="circle active circle-b " onclick="currentDiv(1)"> </span>
            <span class="circle active circle-b " onclick="currentDiv(2)"> </span>
    </div>
    </div>


Solution

  • I wrote this from scratch and made a fiddle for you: https://jsfiddle.net/bartlomiej/kdg581sL/ (You need to set load type to no wrap - in <body> in javascript settings to see it working)

    I hope that's exactly what you wanted to achieve.

    Firstly I set initial value of slideIndex to 0.

    var slideIndex = 0;
    

    And I save array of images elements to slides variable and set length of that array to length.

    var slides = document.getElementById('slides').children
    var length = slides.length
    

    Next line set class active to image element defined in stateIndex.

    setActiveSlide(slideIndex);
    

    Then we need three functions:

    showPrevSlide() which set class active to previous slide ONLY if the slide isn't first.

    function showPrevSlide() {
      if (slideIndex - 1 != -1) {
        slideIndex -= 1;
      }
    
      setActiveSlide(slideIndex);
    }
    

    showNextSlide() which set class active to next slide ONLY if slide isn't the last one.

    function showNextSlide() {
      if (slideIndex + 1 < length) {
        slideIndex += 1;
      }
    
      setActiveSlide(slideIndex);
    }
    

    And finally setActiveSlide() which iterate over all images elements and add active class to image element defined in index.

    function setActiveSlide(index) {
      for (var i = 0; i < length; i++) {
        if (index == i) {
          slides[i].className += ' active';
        } else {
          slides[i].className = 'slide';
        }
      }
    }
    

    To reach fade transition effect on slides you should use transition and opacity CSS properties. You also need to set position to absolute so the images will be placed one on another.

    .slide {
     position: absolute;
     opacity: 0;
     transition: 1s;
    }
    

    And active class styles.

    .slide.active {
      opacity: 1;
    }
    

    I hope my answer helped you.

    EDIT: If you want to change slides in infinite way you have to edit showPrevSlide() and showNextSlide() a bit.

    function showPrevSlide() {
      if (slideIndex - 1 == -1) { 
        slideIndex = length - 1; 
      } else {
        slideIndex -= 1;
      }
    
      setActiveSlide(slideIndex);
    }
    
    function showNextSlide() {
      if (slideIndex + 1 < length) {
        slideIndex += 1;
      } else {
        slideIndex = 0;
      }
    
      setActiveSlide(slideIndex);
    }
    

    And if you want images to change automatically just use setInterval. For example: setInterval(function() { showNextSlide() }, 1000); where 1000 is time in ms.