Search code examples
javascripthtmlcssbootstrap-4carousel

How to make 3D carousel rotate automatically, no clicks required and stop at mouse hover


I found this 3D carousel online and wondering how to make it rotate infinitely without clicking buttons and stops at mouse hover, then continues to rotate again when there is no hover.

var carousel = $(".carousel"),
    currdeg  = 0;

$(".next").on("click", { d: "n" }, rotate);
$(".prev").on("click", { d: "p" }, rotate);

function rotate(e){
  if(e.data.d=="n"){
    currdeg = currdeg - 60;
  }
  if(e.data.d=="p"){
    currdeg = currdeg + 60;
  }
  carousel.css({
    "-webkit-transform": "rotateY("+currdeg+"deg)",
    "-moz-transform": "rotateY("+currdeg+"deg)",
    "-o-transform": "rotateY("+currdeg+"deg)",
    "transform": "rotateY("+currdeg+"deg)"
  });
}

enter image description here

Here is a codepen


Solution

  • @mamoun othman did a great job here! I added the hover pause/restart functionality below:

    var carousel = $(".carousel"), currdeg  = 0;
    
    function rotate(e){
      currdeg = currdeg - 60
      carousel.css({
        "-webkit-transform": "rotateY("+currdeg+"deg)",
        "-moz-transform": "rotateY("+currdeg+"deg)",
        "-o-transform": "rotateY("+currdeg+"deg)",
        "transform": "rotateY("+currdeg+"deg)"
      });
    }
    
    // storing state in window.carouselPause
    const startCarousel = (e) => window.carouselPause = setInterval(rotate, 1000);
    const stopCarousel = (e) => clearInterval(window.carouselPause);
    
    carousel.on({
      // pause carousel when mouse is over
      'mouseenter': stopCarousel,
      // resume when mouse is off
      'mouseleave': startCarousel
    });
    
    // start the carousel when the page is loaded
    startCarousel();
    body {
      background: #333;
      padding: 70px 0;
      font: 15px/20px Arial, sans-serif;
    }
    
    .container {
      margin: 0 auto;
      width: 250px;
      height: 200px;
      position: relative;
      perspective: 1000px;
    }
    
    .carousel {
      height: 100%;
      width: 100%;
      position: absolute;
      transform-style: preserve-3d;
      transition: transform 1s;
    }
    
    .item {
      display: block;
      position: absolute;
      background: #000;
      width: 250px;
      height: 200px;
      line-height: 200px;
      font-size: 5em;
      text-align: center;
      color: #FFF;
      opacity: 0.95;
      border-radius: 10px;
    }
    
    .a {
      transform: rotateY(0deg) translateZ(250px);
      background: #ed1c24;
    }
    .b {
      transform: rotateY(60deg) translateZ(250px);
      background: #0072bc;
    }
    .c {
      transform: rotateY(120deg) translateZ(250px);
      background: #39b54a;
    }
    .d {
      transform: rotateY(180deg) translateZ(250px);
      background: #f26522;
    }
    .e {
      transform: rotateY(240deg) translateZ(250px);
      background: #630460;
    } 
    .f {
      transform: rotateY(300deg) translateZ(250px);
      background: #8c6239;
    }
    
    .next, .prev {
      color: #444;
      position: absolute;
      top: 100px;
      padding: 1em 2em;
      cursor: pointer;
      background: #CCC;
      border-radius: 5px;
      border-top: 1px solid #FFF;
      box-shadow: 0 5px 0 #999;
      transition: box-shadow 0.1s, top 0.1s;
    }
    .next:hover, .prev:hover { color: #000; }
    .next:active, .prev:active {
      top: 104px;
      box-shadow: 0 1px 0 #999;
    }
    .next { right: 5em; }
    .prev { left: 5em; }
    <div class="container">
      <div class="carousel">
        <div class="item a">A</div>
        <div class="item b">B</div>
        <div class="item c">C</div>
        <div class="item d">D</div>
        <div class="item e">E</div>
        <div class="item f">F</div>
      </div>
    </div>
    <!--<div class="next">Next</div>
    <div class="prev">Prev</div>-->
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>