Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS 3D Carousel Item Rotation

The following CodePen demonstrates half of what I want to do: http://codepen.io/nopr/pen/rfBJx

As this carousel spins, the individual, inactive items spin to face towards the back - facing away from the viewer. I cannot seem to figure out how I can keep each of the frames facing the viewer as they spin, performing a do-si-do motion instead of a turning motion (see image).

forward facing carousel

Notice how the letters are always facing you? This is unlike the CodePen above.

I've tried adding an additional carousel with these transforms below to take the place of each plane, but I cannot achieve the effect I am aiming for. Any thoughts?

carousel.css({
   "-webkit-transform": "rotateY("+currdeg+"deg)",
   "-moz-transform": "rotateY("+currdeg+"deg)",
   "-o-transform": "rotateY("+currdeg+"deg)",
   "transform": "rotateY("+currdeg+"deg)"
});
like image 835
JLF Avatar asked Jan 23 '15 20:01

JLF


1 Answers

I have created a wrapper for every element, that keeps the element unrotated, but in the wheel position.

And then, in the javascript, I counter rotate the elements, to keep then facing to the viewer

var carousel = $(".carousel"),
    items = $(".item"),
    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)"
  });
    items.css({
    "-webkit-transform": "rotateY("+(-currdeg)+"deg)",
    "-moz-transform": "rotateY("+(-currdeg)+"deg)",
    "-o-transform": "rotateY("+(-currdeg)+"deg)",
    "transform": "rotateY("+(-currdeg)+"deg)"
  });
}
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;
}
.carousel div {
  transform-style: preserve-3d;
  
}

.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;
  transition: transform 1s;
}

.a {
  transform: rotateY(0deg) translateZ(250px);
}
.a .item {
  background: #ed1c24;
}
.b {
  transform: rotateY(60deg) translateZ(250px) rotateY(-60deg);
}
.b .item {
  background: #0072bc;
}
.c {
  transform: rotateY(120deg) translateZ(250px)  rotateY(-120deg);
}
.c .item {
  background: #39b54a;
}
.d {
  transform: rotateY(180deg) translateZ(250px) rotateY(-180deg);
}
.d .item {
  background: #f26522;
}
.e {
  transform: rotateY(240deg) translateZ(250px) rotateY(-240deg);
} 
.e .item {
  background: #630460;
}
.f {
  transform: rotateY(300deg) translateZ(250px) rotateY(-300deg);
}
.f .item {
  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; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="carousel">
    <div class="a">
      <div class="item">A</div>
    </div>
    <div class="b">
      <div class="item">B</div>
    </div>
    <div class="c">
      <div class="item">C</div>
    </div>
    <div class="d">
      <div class="item">D</div>
    </div>
    <div class="e">
      <div class="item">E</div>
    </div>
    <div class="f">
      <div class="item">F</div>
    </div>
  </div>
</div>
<div class="next">Next</div>
<div class="prev">Prev</div>
like image 182
vals Avatar answered Oct 02 '22 21:10

vals