<div class='wrapper' id='wrapper'>
  <div class='wrapper-3d'>
    <div class='carousel-wrapper center-3d'>
      <div class='carousel-container' id='center'>
        <div class='slide first'></div>
        <div class='slide second'></div>
        <div class='slide third'></div>
      </div>
      <div class='first image' id='img'></div>
    </div>
    <div class='carousel-wrapper left-3d center-3d'>
      <div class='carousel-container' id='left'>
        <div class='slide first'></div>
        <div class='slide second'></div>
        <div class='slide third'></div>
      </div>
    </div>
    <div class='carousel-wrapper right-3d center-3d'>
      <div class='carousel-container' id='right'>
        <div class='slide first'></div>
        <div class='slide second'></div>
        <div class='slide third'></div>
      </div>
    </div>
  </div>
</div>

<p class='debug debug-top' id='t'>0</p>
<p class='debug debug-bot'>
  <br/>
   Move your mouse horizontally
</p>
body, html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  background: #2e2d31;
  overflow: hidden;
}
.wrapper {
  position: absolute;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.wrapper-3d {
  position: relative;
  perspective: 250px;
  transform-style: preserve-3d;
}
.image {
  height: 175px;
  width: 300px;
}
.carousel-wrapper {
  overflow: hidden;
  width: 60vw;
  height: 80vh;
}
.carousel-container {
  display: flex;
  flex-direction: row;
  width: 100%;
  height:100%;
  transition: all 0.5s ease-out;
}
.slide {
  flex-shrink: 0;
  width: 100%;
  height: 100%;
}
/* The trick is to position them on their respective side
   Then set transform-origin to that siede
   And put desired angle 
*/
$angle: 100deg;
$initialSlide: 2;
$translateCenter: 100% - 100% * $initialSlide;
.left-3d {
  position: absolute;
  transform-origin: right center;
  transform: rotateY($angle);
  top: 0;
  bottom: 0;
  right: calc(100%);
}
#left {
  transform: translateX(#{$translateCenter + 100});
}
.center-3d {}
#center {
  transform: translateX(#{$translateCenter});
}
.right-3d {
  position: absolute;
  transform-origin: left center;
  transform: rotateY(-$angle);
  top: 0;
  bottom: 0;
  left: calc(100%);
}
#right {
  transform: translateX(#{$translateCenter - 100});
}
.first, .second, .third {
  background-size: cover;
}
.first{
  background-image: url("https://images.unsplash.com/photo-1492970471430-bc6bd7eb2b13?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=9893bc89e46e2b77a5d8c091fbba04e9&auto=format&fit=crop&w=1355&q=80");
}
.second{
  background-image: url("https://images.unsplash.com/photo-1501707305551-9b2adda5e527?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=0cf5887247e17503ce4e542d00d86b9d&auto=format&fit=crop&w=1335&q=80");
  background-position-y: 50%;
}
.third {
  background-image: url("https://images.unsplash.com/photo-1496749843252-699a989877a1?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=fe5da9650707e5a93c8c3cf164c2e74b&auto=format&fit=crop&w=1375&q=80");
  background-position-y: 50%;
}

.debug {
  position: absolute;
  text-align: center;
  width: 100%;
  font-size: 1.10em;
  font-family: sans-serif;
  letter-spacing: 0.1em;
  font-weight: 200;
  margin: 0;
  margin-top: 10px;
  color: #fafafaee;
  &-top {
    top: 2vh;
  }
  &-bot {
    bottom: 2vh;
  }
}
.fa {
  font-size: 15rem;
  color: #fafafa99;
  line-height: 20px;
}
@media only screen and (min-width: 1600px) {
  $angle: 120deg;
.right-3d {
  transform: none;
  transform: rotateY(-$angle);
  }  
.left-3d {
  transform: none;
  transform: rotateY($angle);
  }
}
View Compiled
/*
  3d Carousel with set-width carousel.
 It's just 3 different views of the carousel.
 The side items have rotation with transition-origin on their respective edge
 And everything is wrapped by a perspective wrapper
  For set-width images with auto-width carousel check:
  **link**
*/
// width - padding = min
// padding = max
const padding = 200;
const slidesCount = 3 - 1;
function map(x, in_min, in_max, out_min, out_max)
    {
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
document.addEventListener('mousemove', (e)=>{
  // Change to bodywidth
  const wrapper = document.getElementById('wrapper')
  const rect = wrapper.getBoundingClientRect();
  // Mouse position in between padding
  const mouseX = Math.min(Math.max(e.clientX - padding,0),rect.width - padding * 2);
  const rawPercent = map(mouseX, 0, rect.width - padding * 2, 100 - 100 * slidesCount, 100);
  const percent = Math.round(rawPercent)
  const left = document.getElementById('left');
  const center = document.getElementById('center');
  const right = document.getElementById('right');
  left.style.transform = `translateX(${percent}%)`;
  center.style.transform = `translateX(${percent - 100}%)`;
  right.style.transform = `translateX(${percent - 200}%)`;
  //debug
  const paragraph = document.getElementById('t');
  paragraph.innerHTML = percent;
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.