Source: components/scroller.js

(function () {
    "use strict";

    /**
    * Scroller
    * @namespace
    */
    db.libs.scroller = (function ($) {
        function handleClick(e) {
            e.preventDefault();

            // Get the outmost element
            var parent = $(e.target).closest('.horizontal-scroller');

            // Get the list to animate
            var list = $(parent).find('.inner ul.list');

            // Get button
            var startBtn = $(parent).find('.nav-item.start');

            // If start was clicked, translate to start
            if($(e.target).hasClass('start')) {
                $(list).css({transform: 'translate(0px)'});
                $(list).attr('data-translate', 0);

                $(startBtn).addClass('hide');

                return;
            }

            // Get the right offset of parent in relation to the document
            var parentRightOffset = $(parent).offset().left + $(parent).outerWidth();

            // Get the previously translated value, if any
            var translate = parseFloat($(list).attr('data-translate')) || 0;

            // Get all the items in the the list
            var items = $(list).find('li');

            // Loop over each item to check if any item's right offset is larger than the parent's right offset,
            // meaning the whole item isn't visible in the list. Then scroll to that item.
            for(var i = 0; i < items.length; i++) {
                var item = items[i];
                var rightOffset = $(item).offset().left + $(item).outerWidth();

                if (rightOffset > parentRightOffset) {
                    var pos = rightOffset - $(item).outerWidth() - $(parent).offset().left;
                    if(pos === 0) {
                        translate = translate + $(item).outerWidth();
                    } else {
                        translate = translate + pos;
                    }

                    // Add some spacing to account for width of scrollbar and prevent nav-item overlaying the first item in the list.
                    translate = translate - 22;

                    $(list).css({transform: 'translate(-'+ translate +'px)'});
                    $(list).attr('data-translate', translate);
                    $(startBtn).removeClass('hide');

                    break;
                }
            }
        }

        function init() {
            var scrollers = $('.horizontal-scroller');

            if(!scrollers || !scrollers.length) return;

            scrollers.each(function(i, scroller) {
                $(scroller).find('.nav-item').off('click', handleClick);
                $(scroller).find('.nav-item').on('click', handleClick);
            });
        }
        return {
            init: init,
            reflow: init
        };
    })(jQuery);
})();