Search code examples
jquerycsscarouselrepeat

Moving inner div to repeat from beginning CSS Jquery Javascript


I am trying to implement a carousel-like component in angularJs where a div is placed in the second div as the image below.

Upon clicking on say number 3, using transition left I move the inner div to the left with the length of a block, so the smooth animation is in place fine.

Now I am trying to achieve this: as number 3 is the last block, I would want to show number 1 block again, to say make the div rotate infinitely.

I have tried chopping the block one and adding it to the end of the div, but that would eliminate the animation because the left of the div has changed.

So basically I am looking for a way to repeat the div inside another div.

enter image description here

Any idea is appreciated.


Solution

  • The below example will clone the next item and add it to the end, then when clicking previous, it will remove the item if it was cloned.

    This does not work in reverse - meaning clicking prev on the original first slide will not add any to the beginning

    NOTE: If the user decided to keep clicking next, the items would keep cloning

    $(document).ready(function(){
      var $wrap = $('.img-wrapper'),
          c_length = $wrap.children().length,
          n_index = 0;
      $('.prev').click(function(){
        var $a = $('.img.active'),
            $b = $a.prev();
        if($b.length === 0){
          return;
        }
        $a.removeClass('active');
        if($a.hasClass('cloned')){
          if(n_index === 0){n_index=c_length-1;}else{n_index--;}
          setTimeout(function(){$a.remove();},300);
        }
        $b.addClass('active');
        $wrap.css('left',-$b.position().left);
      });
      $('.next').click(function(){
        var $a = $('.img.active'),
            $b = $a.next();
        if($b.length === 0){
          $b = $wrap.find('[data-index="'+n_index+'"]').eq(0).clone();
          $b.addClass('cloned');
          $b.insertAfter($a);
          if(n_index+1 === c_length){
            n_index = 0;
          }else{
            n_index++;
          }
        }
        $a.removeClass('active');
        $b.addClass('active');
        $wrap.css('left',-$b.position().left);
      });
    });
    * {
      box-sizing:border-box;
    }
    
    .carousel {
      width: 400px;
      padding: 20px;
      overflow: hidden;
      height: 200px;
      margin:auto;
      position:relative;
    }
    
    .img-wrapper {
      white-space:nowrap;
      position:absolute;
      left:0;
      top:0;
      font-size:0;
      transition:left .3s, right .3s;
    }
    
    .img {
      width:400px;
      height:200px;
      padding:40px 80px;
      font-size:32px;
      color:#fff;
      background:grey;
      display:inline-block;
    }
    
    .img.static.active {
      position:absolute;
    }
    
    .carousel-button {
      position:absolute;
      top:20px;
      padding:5px 10px;
      z-index: 5;
      background:#eee;
    }
    
    .prev {
      left: 0;
    }
    .next {
      right: 0;
    }
    <div class="carousel">
      <div class="carousel-button prev">Prev</div>
      <div class="img-wrapper">
          <div class="img active" data-index="0">IMG 1</div>
          <div class="img" data-index="1">IMG 2</div>
          <div class="img" data-index="2">IMG 3</div>
      </div>
      <div class="carousel-button next">Next</div>
    </div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>