<div id="app"></div>
.slider {
  width: 320px;
  height: 480px;
  perspective: 1000px;
}

  .slider__viewport {
    position: relative;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    transition: transform 1.2s cubic-bezier(0.68, 0.08, 0.27, 0.96);    
  }

  .slider__image {
    display: inline-block;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    font: 300 48px/1 Menlo, monospace;
    border-radius: 4px;
    background: #333;
    color: #fff;
    opacity: 0.3;
    transition: opacity 1.4s ease-in-out;
  }

    .slider__image_active {
      box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.4);
      opacity: 1;
    }

#app {
  height: 100%;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  transform: scale(0.75);
  display: flex;
  align-items: center;
  justify-content: center;
}
class Slider extends React.PureComponent {
  constructor() {
    super();
    this.state = {
      currentIndex: 0
    };
  }
  
  componentDidMount() {
    setInterval(() => {
      this.setState({
        currentIndex: (this.state.currentIndex + 1) % this.props.images.length
      })
    }, 2500)
  }
  
  render() {
    const { images, radius = 180 } = this.props;
    const { currentIndex } = this.state;
    const len = images.length || 0;
    const angle = 2 * Math.PI / len;

    return (
      <div className="slider">
        <div className="slider__viewport"
             style={{
              transform: `translateZ(${-radius}px) rotateY(${-currentIndex * angle}rad)`
             }}>
          {images.map((image, index) => {
            const indexAngle = index * angle;
            const z = Math.cos(indexAngle) * radius;
            const x = Math.sin(indexAngle) * radius;

            return (
              <div
                key={image}
                className={classNames(
                  'slider__image',
                  {'slider__image_active': index === currentIndex }
                )}
                style={{
                  transform: `translateZ(${z}px) translateX(${x}px) rotateY(${indexAngle}rad)`
                }}
                src={image}
              >{image}</div>
            )
          })  
        }                  
        </div>
      </div>
    )
  }
}

class App extends React.PureComponent {
  render() {
    return (
      <Slider
        images={['1', '2', '3',]}
        radius={210}
      />
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/classnames/2.2.5/index.min.js