File indexing completed on 2024-05-19 06:00:31

0001 /**
0002  *   Unslider by @idiot
0003  */
0004  
0005 (function($, f) {
0006         //  If there's no jQuery, Unslider can't work, so kill the operation.
0007         if(!$) return f;
0008         
0009         var Unslider = function() {
0010                 //  Set up our elements
0011                 this.el = f;
0012                 this.items = f;
0013                 
0014                 //  Dimensions
0015                 this.sizes = [];
0016                 this.max = [0,0];
0017                 
0018                 //  Current inded
0019                 this.current = 0;
0020                 
0021                 //  Start/stop timer
0022                 this.interval = f;
0023                                 
0024                 //  Set some options
0025                 this.opts = {
0026                         speed: 500,
0027                         delay: 3000, // f for no autoplay
0028                         complete: f, // when a slide's finished
0029                         keys: !f, // keyboard shortcuts - disable if it breaks things
0030                         dots: f, // display ••••o• pagination
0031                         fluid: f // is it a percentage width?,
0032                 };
0033                 
0034                 //  Create a deep clone for methods where context changes
0035                 var _ = this;
0036 
0037                 this.init = function(el, opts) {
0038                         this.el = el;
0039                         this.ul = el.children('ul');
0040                         this.max = [el.outerWidth(), el.outerHeight()];                 
0041                         this.items = this.ul.children('li').each(this.calculate);
0042                         
0043                         //  Check whether we're passing any options in to Unslider
0044                         this.opts = $.extend(this.opts, opts);
0045                         
0046                         //  Set up the Unslider
0047                         this.setup();
0048                         
0049                         return this;
0050                 };
0051                 
0052                 //  Get the width for an element
0053                 //  Pass a jQuery element as the context with .call(), and the index as a parameter: Unslider.calculate.call($('li:first'), 0)
0054                 this.calculate = function(index) {
0055                         var me = $(this),
0056                                 width = me.outerWidth(), height = me.outerHeight();
0057                         
0058                         //  Add it to the sizes list
0059                         _.sizes[index] = [width, height];
0060                         
0061                         //  Set the max values
0062                         if(width > _.max[0]) _.max[0] = width;
0063                         if(height > _.max[1]) _.max[1] = height;
0064                 };
0065                 
0066                 //  Work out what methods need calling
0067                 this.setup = function() {
0068                         //  Set the main element
0069                         this.el.css({
0070                                 overflow: 'hidden',
0071                                 width: _.max[0],
0072                                 height: this.items.first().outerHeight()
0073                         });
0074                         
0075                         //  Set the relative widths
0076                         this.ul.css({width: (this.items.length * 100) + '%', position: 'relative'});
0077                         this.items.css('width', (100 / this.items.length) + '%');
0078                         
0079                         if(this.opts.delay !== f) {
0080                                 this.start();
0081                                 this.el.hover(this.stop, this.start);
0082                         }
0083                         
0084                         //  Custom keyboard support
0085                         this.opts.keys && $(document).keydown(this.keys);
0086                         
0087                         //  Dot pagination
0088                         this.opts.dots && this.dots();
0089                         
0090                         //  Little patch for fluid-width sliders. Screw those guys.
0091                         if(this.opts.fluid) {
0092                                 var resize = function() {
0093                                         _.el.css('width', Math.min(Math.round((_.el.outerWidth() / _.el.parent().outerWidth()) * 100), 100) + '%');
0094                                 };
0095                                 
0096                                 resize();
0097                                 $(window).resize(resize);
0098                         }
0099                         
0100                         if(this.opts.arrows) {
0101                                 this.el.parent().append('<p class="arrows"><span class="prev">←</span><span class="next">→</span></p>')
0102                                         .find('.arrows span').click(function() {
0103                                                 $.isFunction(_[this.className]) && _[this.className]();
0104                                         });
0105                         };
0106                         
0107                         //  Swipe support
0108                         if($.event.swipe) {
0109                                 this.el.on('swipeleft', _.prev).on('swiperight', _.next);
0110                         }
0111                 };
0112                 
0113                 //  Move Unslider to a slide index
0114                 this.move = function(index, cb) {
0115                         //  If it's out of bounds, go to the first slide
0116                         if(!this.items.eq(index).length) index = 0;
0117                         if(index < 0) index = (this.items.length - 1);
0118                         
0119                         var target = this.items.eq(index);
0120                         var obj = {height: target.outerHeight()};
0121                         var speed = cb ? 5 : this.opts.speed;
0122                         
0123                         if(!this.ul.is(':animated')) {                  
0124                                 //  Handle those pesky dots
0125                                 _.el.find('.dot:eq(' + index + ')').addClass('active').siblings().removeClass('active');
0126 
0127                                 this.el.animate(obj, speed) && this.ul.animate($.extend({left: '-' + index + '00%'}, obj), speed, function(data) {
0128                                         _.current = index;
0129                                         $.isFunction(_.opts.complete) && !cb && _.opts.complete(_.el);
0130                                 });
0131                         }
0132                 };
0133                 
0134                 //  Autoplay functionality
0135                 this.start = function() {
0136                         _.interval = setInterval(function() {
0137                                 _.move(_.current + 1);
0138                         }, _.opts.delay);
0139                 };
0140                 
0141                 //  Stop autoplay
0142                 this.stop = function() {
0143                         _.interval = clearInterval(_.interval);
0144                         return _;
0145                 };
0146                 
0147                 //  Keypresses
0148                 this.keys = function(e) {
0149                         var key = e.which;
0150                         var map = {
0151                                 //  Prev/next
0152                                 37: _.prev,
0153                                 39: _.next,
0154                                 
0155                                 //  Esc
0156                                 27: _.stop
0157                         };
0158                         
0159                         if($.isFunction(map[key])) {
0160                                 map[key]();
0161                         }
0162                 };
0163                 
0164                 //  Arrow navigation
0165                 this.next = function() { return _.stop().move(_.current + 1) };
0166                 this.prev = function() { return _.stop().move(_.current - 1) };
0167                 
0168                 this.dots = function() {
0169                         //  Create the HTML
0170                         var html = '<ol class="dots">';
0171                                 $.each(this.items, function(index) { html += '<li class="dot' + (index < 1 ? ' active' : '') + '">' + (index + 1) + '</li>'; });
0172                                 html += '</ol>';
0173                         
0174                         //  Add it to the Unslider
0175                         this.el.addClass('has-dots').append(html).find('.dot').click(function() {
0176                                 _.move($(this).index());
0177                         });
0178                 };
0179         };
0180         
0181         //  Create a jQuery plugin
0182         $.fn.unslider = function(o) {
0183                 var len = this.length;
0184                 
0185                 //  Enable multiple-slider support
0186                 return this.each(function(index) {
0187                         //  Cache a copy of $(this), so it 
0188                         var me = $(this);
0189                         var instance = (new Unslider).init(me, o);
0190                         
0191                         //  Invoke an Unslider instance
0192                         me.data('unslider' + (len > 1 ? '-' + (index + 1) : ''), instance);
0193                 });
0194         };
0195 })(window.jQuery, false);