Widget Type Carousel

by AntonLapshin

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.0/jquery.mCustomScrollbar.concat.min.js"></script>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/malihu-custom-scrollbar-plugin/3.1.0/jquery.mCustomScrollbar.min.css">
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Open+Sans:400,700">

<div id="modal">
    <div class="ground">
    </div>
    <div class="c9carousel">
        <ul>
        </ul>
    </div>
    <div class="preview">
        <h2></h2>
        <img />
    </div>
</div>

CSS

body {
    font-family: Open Sans;
}

#modal {
    background: url(http://i.snag.gy/HYxfV.jpg) no-repeat;
    margin: 10px;
    height: 583px;
    width: 533px;
    position: absolute;
    padding: 110px 100px 0 20px;
}

.ground {
    position: absolute;
    background-color: black;
    opacity: 0.5;
    width: 575px;
    height: 100%;
    left: 0;
    top: 0;
    display: none;
}

.preview {
    
    position: absolute;
    text-align: center;
    left: 80px;
    
    h2 {
        font-size: 2em;
        color: white;
    }
}

.c9carousel {
  
    ul {
        overflow-y: auto;
        overflow-x:  auto;
        height: 60px;
        white-space:nowrap;

        li {
            overflow: hidden;
            display: inline-block;
            margin-right: 2px;
            cursor: pointer;
            
            .thumbnail {
                width: 60px;
                height: 45px;
                opacity: 0.3;
                
                &:hover {
                    opacity: 1;              
                }

                &.selected {
                    opacity: 1;
                }                
            }
        }        
    }
}

JavaScript

$('head style[type="text/css"]').attr('type','text/less');
less.env = 'development';
less.refreshStyles();

;(function(){

    Function.prototype.debounce = function (milliseconds) {
        var baseFunction = this,
            timer = null,
            wait = milliseconds;

        return function () {
            var self = this,
                args = arguments;

            function complete() {
                baseFunction.apply(self, args);
                timer = null;
            }

            if (timer) {
                clearTimeout(timer);
            }

            timer = setTimeout(complete, wait);
        };
    };

    String.prototype.f = function() {
        var s = this, i = arguments.length;
        while (i--) { s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]); }
        return s;
    };

	var itemTemplate = '<li><img class="thumbnail" src="{0}" data-id="{1}" /></li>';
    var $preview = $('.preview');
    var $header = $preview.find('h2');
    var $img = $preview.find('img');
    var $ground = $('.ground');
    var items;

	function buildCarousel(){
    	var html = $.map(items, function(item){
        	return itemTemplate.f(item.src, item.id);
        }).join('');
        var $ul = $('.c9carousel > ul');
        $ul.html(html);
        $ul.find('.thumbnail').eq(3).addClass('selected');
        $ul.mCustomScrollbar({
        	autoHideScrollbar: true,
        	axis: 'x',
            theme:"dark-3",
            scrollInertia: 0
        });
        $ul.on('click', '.thumbnail', function(){
        	var $thumbnail = $(this);
            $ul.find('.thumbnail').removeClass('selected');
            $thumbnail.addClass('selected');
        });
        $ul.on('mouseover', '.thumbnail', function(){
        	var $thumbnail = $(this);
            var id = $thumbnail.data('id');
            var item = $.grep(items, function(item){
            	return item.id == id;
            })[0];
            $header.html(item.type);
           ...