3D CSS Carousel

by Sam Fereday

HTML

<section class="container">
  <div id="carousel"></div>
</section>

<section id="options">
  <p id="navigation">
    <button id="previous" data-increment="-1">Previous</button>
    <button id="next" data-increment="1">Next</button>
  </p>

</section>

CSS

.container {
  width: 186px;
  height: 140px;
  position: relative;
  margin: 0 auto;
  border: 1px solid #CCC;
  /* -webkit-perspective: 1100px;
  -moz-perspective: 1100px;
  -o-perspective: 1100px;
  perspective: 1100px; */
}

#carousel {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transform: translateZ( -288px);
  -moz-transform: translateZ( -288px);
  -o-transform: translateZ( -288px);
  transform: translateZ( -288px);
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-transition: -webkit-transform 1s;
  -moz-transition: -moz-transform 1s;
  -o-transition: -o-transform 1s;
  transition: transform 1s;
}

#carousel figure {
  display: block;
  position: absolute;
  width: 186px;
  height: 116px;
  left: 0;
  top: 10px;
  border: 2px solid black;
  line-height: 116px;
  font-size: 80px;
  font-weight: bold;
  color: white;
  text-align: center;
  
  transform: translate3d(222px, -85px, -129px) rotateX(0deg) rotateY(0deg) rotateZ(0deg) scale3d(1, 1, 1);
  
}

JavaScript

var slideCount = 9; // Dynamic later please

// Slide item
var Item = function() {
  this.rY = 0;
  this.tZ = 0;
  this.hsla = 0;
  return this;
};

Item.prototype.setHSLA = function(n) {
  this.hsla = n;
  this.el.style.background = "hsla(" + n + ", 100%, 50%, 0.8)";
}

Item.prototype.setProperties = function(rY, tZ) {
  this.rY = rY;
  this.tZ = tZ;
  this.el.style.transform = "rotateY(" + this.rY + "deg) translateZ(" + this.tZ + "px)";
  this.el.style.left = -360 / slideCount + "px";
}

Item.prototype.createEl = function() {
  this.el = document.createElement("figure");
  this.el.innerHTML = ":)";
  return this.el;
}

// Get Z value
function getZ(panelSize, numberOfPanels)
{
	return Math.round( ( panelSize / 2 ) / 
  Math.tan( Math.PI / numberOfPanels ) );
}

// Controller
var init = function() {

	var rotationalSpacing = 360 / slideCount;
  var zValue = getZ(186, slideCount);

  var carousel = document.getElementById('carousel'),
    navButtons = document.querySelectorAll('#navigation button'),
    theta = 0,
    onNavButtonClick = function(event) {
      theta += rotationalSpacing * -1;
      //carousel.style['transform'] = 'translateZ( -'+ zValue +'px ) rotateY(' + theta + 'deg)';
    };
    
  for (var i = 0; i < 2; i++) {
    navButtons[i].addEventListener('click', onNavButtonClick, false);
  }

  for (var j = 0; j < slideCount; j++) {
    var item = new Item()
    var el = item.createEl();
    carousel.appendChild(el);
    item.setHSLA(rotationalSpacing * j);
    item.setProperties(rotationalSpacing * j, zValue);
  }

};

init();