﻿/**
* jquery.scrollable 0.13. Put your HTML scroll.
* 
* http://flowplayer.org/tools/scrollable.html
*
* Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
*
* Released under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
* 
* >> Basically you can do anything you want but leave this header as is <<
*
* Since  : 0.10 - 03/01/2008
* Version: 0.13 - Fri Nov 07 2008 16:50:33 GMT-0000 (GMT+00:00)
*/
(function($) {
    function Scrollable(el, config) {
        var self = this; 
        if (!Scrollable.current) { Scrollable.current = this; } 
        
        var opts = { size: 5, vertical: false, activeClass: 'active', speed: 300, onSeek: null, clickable: true, items: '.items', prev: '.prev', next: '.next', navi: '.navi', naviItem: 'span', loop: false };
        this.opts = $.extend(opts, config); 
        this.opts.horizontal = !opts.vertical;
        this.root = $(el);
        var root = this.root; 
        var itemRoot = $(opts.items, root);

        if (!itemRoot.length) { itemRoot = root; } 
            itemRoot.css({ position: 'relative', overflow: 'hidden', visibility: 'visible' }); itemRoot.children().wrapAll('<div class="__scrollable" style="position:absolute"/>'); this.wrap = itemRoot.find(":first"); this.wrap.css(opts.horizontal ? "width" : "height", "200000em").after('<br clear="all" />'); this.items = this.wrap.children(); this.index = 0;

            if (opts.horizontal) {
        try{
            itemRoot.width(opts.size * (this.items.eq(1).offset().left - this.items.eq(0).offset().left) - 2);
            }catch(err){}
        }
        else {
        try{
            itemRoot.height(opts.size * (this.items.eq(1).offset().top - this.items.eq(0).offset().top) - 2);
            }catch(err){}
        }

        if ($.isFunction($.fn.mousewheel)) { 
        root.bind("mousewheel.scrollable", function(e, delta) { self.move(-delta, 50); return false; }); } if (opts.clickable) { this.items.each(function(index, arg) { $(this).bind("click.scrollable", function() { self.click(index); }); }); } this.activeIndex = 0; $(opts.prev, root).click(function() { self.prev(); }); $(opts.next, root).click(function() { self.next(); }); $(opts.navi, root).each(function() { var navi = $(this); var status = self.getStatus(); if (navi.is(":empty")) { for (var i = 0; i < status.pages; i++) { var item = $("<" + opts.naviItem + "/>").attr("page", i).click(function(e) { var el = $(this); el.parent().children().removeClass(opts.activeClass); el.addClass(opts.activeClass); self.setPage(el.attr("page")); e.preventDefault(); }); if (i === 0) { item.addClass(opts.activeClass); } navi.append(item); } } else { var els = navi.find("a"); if (!els.length) { els = navi.children(); } els.each(function(i) { var item = $(this); item.attr("page", i); if (i === 0) { item.addClass(opts.activeClass); } item.click(function() { navi.find("." + opts.activeClass).removeClass(opts.activeClass); item.addClass(opts.activeClass); self.setPage(item.attr("page")); }); }); } }); } $.extend(Scrollable.prototype, { getVersion: function() { return '@VERSION'; }, click: function(index) { var item = this.items.eq(index); var klass = this.opts.activeClass; if (!item.hasClass(klass) && (index >= 0 || index < this.items.size())) { this.items.removeClass(klass); item.addClass(klass); var delta = Math.floor(this.opts.size / 2); var to = index - delta; if (to !== this.activeIndex) { this.seekTo(to); } } }, getStatus: function() { var len = this.items.size(); return { size: this.opts.size, total: len, index: this.index, pages: Math.ceil(len / this.opts.size), page: Math.ceil(this.index / this.opts.size) }; }, seekTo: function(index, time) { if (index < 0) { index = 0; } var max = Math.min(index, this.items.length - this.opts.size); if (index <= max) { var item = this.items.eq(index); this.index = index; if (this.opts.horizontal) { var left = this.wrap.offset().left - item.offset().left; this.wrap.animate({ left: left }, time || this.opts.speed); } else { var top = this.wrap.offset().top - item.offset().top; this.wrap.animate({ top: top }, time || this.opts.speed); } Scrollable.current = this; } if ($.isFunction(this.opts.onSeek)) { this.opts.onSeek.call(this); } var navi = $(this.opts.navi, this.root); if (navi.length) { var klass = this.opts.activeClass; var page = Math.ceil(index / this.opts.size); page = Math.min(page, navi.children().length - 1); navi.children().removeClass(klass).eq(page).addClass(klass); } this.activeIndex = index; return true; }, move: function(offset, time) { var to = this.index + offset; if (this.opts.loop && to > (this.items.length - this.opts.size)) { to = 0; } this.seekTo(to, time); }, next: function(time) { this.move(1, time); }, prev: function(time) { this.move(-1, time); }, movePage: function(offset, time) { this.move(this.opts.size * offset, time); }, setPage: function(page, time) { var size = this.opts.size; var index = size * page; var lastPage = index + size >= this.items.size(); if (lastPage) { index = this.items.size() - this.opts.size; } this.seekTo(index, time); }, prevPage: function(time) { this.setPage(this.getStatus().page - 1, time); }, nextPage: function(time) { this.setPage(this.getStatus().page + 1, time); }, begin: function(time) { this.seekTo(0, time); }, end: function(time) { this.seekTo(this.items.size() - this.opts.size, time); } }); $(window).bind("keypress.scrollable", function(evt) { var el = Scrollable.current; if (!el) { return; } if (el.opts.horizontal && (evt.keyCode == 37 || evt.keyCode == 39)) { el.move(evt.keyCode == 37 ? -1 : 1); return evt.preventDefault(); } if (!el.opts.horizontal && (evt.keyCode == 38 || evt.keyCode == 40)) { el.move(evt.keyCode == 38 ? -1 : 1); return evt.preventDefault(); } return true; }); jQuery.prototype.scrollable = function(opts, arg0, arg1) { if (!opts || typeof opts == 'number') { var index = opts || 0; var el = $.data(this.get()[index], "scrollable"); if (el) { return el; } } this.each(function() { if (typeof opts == "string") { var el = $.data(this, "scrollable"); el[opts].apply(el, [arg0, arg1]); } else { var instance = new Scrollable(this, opts); $.data(this, "scrollable", instance); } }); return this; }; })(jQuery);
