<div id="app"></div>
@import url('https://fonts.googleapis.com/css?family=Lobster');

body {
    background-color: #89FAD0;
    font-family: 'Lobster';
}

#carousel {
    position: absolute;
    height: 200px;
    width: 810px;
    margin: auto;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}

.arrow {
    position: absolute;
    width: 30px;
    height: 30px;
    background-color: white;
    text-align: center;
    font-size: 25px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 20px;
    color: #228291;
    line-height: 30px;
    margin-top: 85px;
    z-index: 1000;
}

.arrow-right {
    left: 780px;
}

.item {
    text-align: center;
    color: white;
    font-size: 40px;
    position: absolute;
    transition: height 1s, width 1s, left 1s, margin-top 1s, line-height 1s, background-color 1s;
}

$level2-height: 150px;
$level2-width: 110px;
$level1-height: 180px;
$level1-width: 130px;
$level0-height: 200px;
$level0-width: 150px;

$level-2-left: 650px;
$level-1-left: 500px;
$level0-left: 330px;
$level1-left: 180px;
$level2-left: 50px;


.level-2 {
    height: $level2-height;
    width: $level2-width;
    line-height: $level2-height;
    background-color: #228291;
    left: $level-2-left;
    margin-top: 25px;
}

.level-1 {
    height: $level1-height;
    width: $level1-width;
    line-height: $level1-height;
    background-color: #6796E5;
    left: $level-1-left;
    margin-top: 10px;
}

.level0 {
    height: $level0-height;
    width: $level0-width;
    line-height: $level0-height;
    background-color: #4EC9E1;
    left: $level0-left;
}

.level1 {
    height: $level1-height;
    width: $level1-width;
    line-height: $level1-height;
    background-color: #6796E5;
    margin-top: 10px;
    left: $level1-left;
}

.level2 {
    height: $level2-height;
    width: $level2-width;
    line-height: $level2-height;
    background-color: #228291;
    margin-top: 25px;
    left: $level2-left;
}

.left-enter {
    opacity: 0;
    left: $level2-left - $level2-width;
    height: $level2-height - 30;
    width: $level2-width - 20;
    line-height: $level2-height - 30;
    margin-top: 40px;
}

.left-enter.left-enter-active {
    opacity: 1;
    left: $level2-left;
    height: $level2-height;
    width: $level2-width;
    line-height: $level2-height;
    margin-top: 25px;
    transition: left 1s, opacity 1s, height 1s, width 1s, margin-top 1s, line-height 1s;
}

.left-leave {
    opacity: 1;
    left: $level-2-left;
    height: $level2-height;
    width: $level2-width;
    line-height: $level2-height;
    margin-top: 25px;
}

.left-leave.left-leave-active {
    left: $level-2-left + $level2-width + 20;
    opacity: 0;
    height: $level2-height - 30;
    line-height: 120px;
    margin-top: 40px;
    width: $level2-width - 20;
    transition: left 1s, opacity 1s, height 1s, width 1s, margin-top 1s, line-height 1s;
}

.right-enter {
    opacity: 0;
    left: $level-2-left + $level2-width;
    height: $level2-height - 30;
    width: $level2-width - 20;
    line-height: $level2-height - 30;
    margin-top: 40px;
}

.right-enter.right-enter-active {
    left: $level-2-left;
    opacity: 1;
    height: $level2-height;
    margin-top: 25px;
    line-height: $level2-height;
    width: $level2-width;
    transition: left 1s, opacity 1s, height 1s, width 1s, margin-top 1s, line-height 1s;
}

.right-leave {
    left: $level2-left;
    height: $level2-height;
    opacity: 1;
    margin-top: 25px;
    line-height: $level2-height;
    width: $level2-width;
}

.right-leave.right-leave-active {
    left: $level2-left - $level2-width;
    opacity: 0;
    height: $level2-height - 30;
    width: $level2-width - 20;
    line-height: $level2-height - 30;
    margin-top: 40px;
    transition: left 1s, opacity 1s, height 1s, width 1s, margin-top 1s, line-height 1s;
}

.noselect {
    -webkit-user-select: none; 
     -khtml-user-select: none; 
       -moz-user-select: none; 
        -ms-user-select: none;  
            user-select: none;
}
View Compiled
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;

class Carousel extends React.Component {
    
    constructor(props) {
        super(props)
        this.state = {
            items: this.props.items,
            active: this.props.active,
            direction: ''
        }
        this.rightClick = this.moveRight.bind(this)
        this.leftClick = this.moveLeft.bind(this)
    }

    generateItems() {
        var items = []
        var level
        console.log(this.state.active)
        for (var i = this.state.active - 2; i < this.state.active + 3; i++) {
            var index = i
            if (i < 0) {
                index = this.state.items.length + i
            } else if (i >= this.state.items.length) {
                index = i % this.state.items.length
            }
            level = this.state.active - i
            items.push(<Item key={index} id={this.state.items[index]} level={level} />)
        }
        return items
    }
    
    moveLeft() {
        var newActive = this.state.active
        newActive--
        this.setState({
            active: newActive < 0 ? this.state.items.length - 1 : newActive,
            direction: 'left'
        })
    }
    
    moveRight() {
        var newActive = this.state.active
        this.setState({
            active: (newActive + 1) % this.state.items.length,
            direction: 'right'
        })
    }
    
    render() {
        return(
            <div id="carousel" className="noselect">
                <div className="arrow arrow-left" onClick={this.leftClick}><i className="fi-arrow-left"></i></div>
                <ReactCSSTransitionGroup 
                    transitionName={this.state.direction}>
                    {this.generateItems()}
                </ReactCSSTransitionGroup>
                <div className="arrow arrow-right" onClick={this.rightClick}><i className="fi-arrow-right"></i></div>
            </div>
        )
    }
}

class Item extends React.Component {
    
    constructor(props) {
        super(props)
        this.state = {
            level: this.props.level
        }
    }
    
    render() {
        const className = 'item level' + this.props.level
        return(
            <div className={className}>
                {this.props.id}
            </div>
        )
    }
}

var items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ReactDOM.render(<Carousel items={items} active={0}/>, document.getElementById('app'))
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.css
  2. https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/svgs/fi-list.svg

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-with-addons.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js