3D Carousel Slider in JavaScript

3d Carousel Slider In JavaScript
Project: 3D Rotating Carousel with CSS and JavaScript
Author: SitePoint
Edit Online: View on CodePen
License: MIT

A 3D carousel is one of the attractive elements on a webpage. It allows users to slide the images with a three-dimensional transition effect.

How to Create a 3D Carousel Slider in JavaScript

First of all, load the following assets into the head tag of your HTML document.

 <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto'>

Create the HTML structure as follows:

<h1>3D Rotating Carousel Examples</h1>

<h2>Three images</h2>
<div class="carousel">
	<figure>
		<img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
		<img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
		<img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
	</figure>
	<nav>
		<button class="nav prev">Prev</button>
		<button class="nav next">Next</button>
	</nav>
</div>

<h2>Four images</h2>
<div class="carousel">
	<figure>
    <img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
		<img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
		<img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
		<img src="https://source.unsplash.com/mCg0ZgD7BgU/800x533" alt="">
	</figure>
	<nav>
		<button class="nav prev">Prev</button>
		<button class="nav next">Next</button>
	</nav>
</div>

<h2>Eight images</h2>
<div class="carousel">
	<figure>
    <img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
		<img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
		<img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
		<img src="https://source.unsplash.com/mCg0ZgD7BgU/800x533" alt="">
		<img src="https://source.unsplash.com/VkwRmha1_tI/800x533" alt="">
		<img src="https://source.unsplash.com/1FWICvPQdkY/800x533" alt="">
		<img src="https://source.unsplash.com/bjhrzvzZeq4/800x533" alt="">
		<img src="https://source.unsplash.com/7mUXaBBrhoA/800x533" alt="">
	</figure>
	<nav>
		<button class="nav prev">Prev</button>
		<button class="nav next">Next</button>
	</nav>
</div>

<h2>Eight images, with 20px gap</h2>
<div class="carousel" data-gap="20">
	<figure>
    <img src="https://source.unsplash.com/mCg0ZgD7BgU/800x533" alt="">
		<img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
		<img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
		<img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
		<img src="https://source.unsplash.com/VkwRmha1_tI/800x533" alt="">
		<img src="https://source.unsplash.com/1FWICvPQdkY/800x533" alt="">
		<img src="https://source.unsplash.com/bjhrzvzZeq4/800x533" alt="">
		<img src="https://source.unsplash.com/7mUXaBBrhoA/800x533" alt="">
	</figure>
	<nav>
		<button class="nav prev">Prev</button>
		<button class="nav next">Next</button>
	</nav>
</div>

<h2>Eight images, with 80px gap</h2>
<div class="carousel" data-gap="80">
	<figure>
    <img src="https://source.unsplash.com/VkwRmha1_tI/800x533" alt="">
		<img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
		<img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
		<img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
		<img src="https://source.unsplash.com/mCg0ZgD7BgU/800x533" alt="">
		<img src="https://source.unsplash.com/1FWICvPQdkY/800x533" alt="">
		<img src="https://source.unsplash.com/bjhrzvzZeq4/800x533" alt="">
		<img src="https://source.unsplash.com/7mUXaBBrhoA/800x533" alt="">
	</figure>
	<nav>
		<button class="nav prev">Prev</button>
		<button class="nav next">Next</button>
	</nav>
</div>

<h2>Hidden backfaces</h2>
<div class="carousel" data-gap="20" data-bfc>
	<figure>
    <img src="https://source.unsplash.com/bjhrzvzZeq4/800x533" alt="">
		<img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
		<img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
		<img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
		<img src="https://source.unsplash.com/mCg0ZgD7BgU/800x533" alt="">
		<img src="https://source.unsplash.com/VkwRmha1_tI/800x533" alt="">
		<img src="https://source.unsplash.com/1FWICvPQdkY/800x533" alt="">
		<img src="https://source.unsplash.com/7mUXaBBrhoA/800x533" alt="">
	</figure>
	<nav>
		<button class="nav prev">Prev</button>
		<button class="nav next">Next</button>
	</nav>
</div>

Style using the following CSS styles:

body {
  margin: 0;
  font-family: "Roboto", sans-serif;
  font-size: 16px;
}
.cd__main{
   display: block !important;
  background: #4AC29A;  /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #BDFFF3, #4AC29A);  /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #BDFFF3, #4AC29A) !important; /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */

}

h1 {
  text-align: center;
  margin-bottom: 1.5em;
}

h2 {
  text-align: center;
  color: #555;
  margin-bottom: 0;
}

.carousel {
  padding: 20px;
  perspective: 500px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.carousel > * {
  flex: 0 0 auto;
}
.carousel figure {
  margin: 0;
  width: 40%;
  transform-style: preserve-3d;
  transition: transform 0.5s;
}
.carousel figure img {
  width: 100%;
  box-sizing: border-box;
  padding: 0 0px;
}
.carousel figure img:not(:first-of-type) {
  position: absolute;
  left: 0;
  top: 0;
}
.carousel nav {
  display: flex;
  justify-content: center;
  margin: 20px 0 0;
}
.carousel nav button {
  flex: 0 0 auto;
  margin: 0 5px;
  cursor: pointer;
  color: #333;
  background: none;
  border: 1px solid;
  letter-spacing: 1px;
  padding: 5px 10px;
}

Add the following JavaScript function:

window.addEventListener('load', () => {
  var
  carousels = document.querySelectorAll('.carousel');


  for (var i = 0; i < carousels.length; i++) {
    carousel(carousels[i]);
  }
});

function carousel(root) {
  var
  figure = root.querySelector('figure'),
  nav = root.querySelector('nav'),
  images = figure.children,
  n = images.length,
  gap = root.dataset.gap || 0,
  bfc = ('bfc' in root.dataset),

  theta = 2 * Math.PI / n,
  currImage = 0;


  setupCarousel(n, parseFloat(getComputedStyle(images[0]).width));
  window.addEventListener('resize', () => {
    setupCarousel(n, parseFloat(getComputedStyle(images[0]).width));
  });

  setupNavigation();

  function setupCarousel(n, s) {
    var
    apothem = s / (2 * Math.tan(Math.PI / n));


    figure.style.transformOrigin = `50% 50% ${-apothem}px`;

    for (var i = 0; i < n; i++)
    images[i].style.padding = `${gap}px`;
    for (i = 1; i < n; i++) {
      images[i].style.transformOrigin = `50% 50% ${-apothem}px`;
      images[i].style.transform = `rotateY(${i * theta}rad)`;
    }
    if (bfc)
    for (i = 0; i < n; i++)
    images[i].style.backfaceVisibility = 'hidden';

    rotateCarousel(currImage);
  }

  function setupNavigation() {
    nav.addEventListener('click', onClick, true);

    function onClick(e) {
      e.stopPropagation();

      var t = e.target;
      if (t.tagName.toUpperCase() != 'BUTTON')
      return;

      if (t.classList.contains('next')) {
        currImage++;
      } else
      {
        currImage--;
      }

      rotateCarousel(currImage);
    }

  }

  function rotateCarousel(imageIndex) {
    figure.style.transform = `rotateY(${imageIndex * -theta}rad)`;
  }

}

That’s all! hopefully, you have successfully created 3d Carousel Slider In Javascript. If you have any questions or suggestions, feel free to comment below.

Show 1 Comment

1 Comment

  1. Hi, thanks for this, I’m trying to use cards instead of images for the carousel and am having trouble doing this. It’s like the figure only accepts images as elements for the carousel? Any advice? Thanks

Leave a Reply