Team:BIOSINT Mexico/BSMex jquery.elastislide.js

From 2014.igem.org

(function( window, $, undefined ) {

// http://www.netcu.de/jquery-touchwipe-iphone-ipad-library $.fn.touchwipe = function(settings) {

var config = { min_move_x: 20, min_move_y: 20, wipeLeft: function() { }, wipeRight: function() { }, wipeUp: function() { }, wipeDown: function() { }, preventDefaultEvents: true };

if (settings) $.extend(config, settings);

this.each(function() { var startX; var startY; var isMoving = false;

function cancelTouch() { this.removeEventListener('touchmove', onTouchMove); startX = null; isMoving = false; }

function onTouchMove(e) { if(config.preventDefaultEvents) { e.preventDefault(); } if(isMoving) { var x = e.touches[0].pageX; var y = e.touches[0].pageY; var dx = startX - x; var dy = startY - y; if(Math.abs(dx) >= config.min_move_x) { cancelTouch(); if(dx > 0) { config.wipeLeft(); } else { config.wipeRight(); } } else if(Math.abs(dy) >= config.min_move_y) { cancelTouch(); if(dy > 0) { config.wipeDown(); } else { config.wipeUp(); } } } }

function onTouchStart(e) { if (e.touches.length == 1) { startX = e.touches[0].pageX; startY = e.touches[0].pageY; isMoving = true; this.addEventListener('touchmove', onTouchMove, false); } } if ('ontouchstart' in document.documentElement) { this.addEventListener('touchstart', onTouchStart, false); } });

return this; };

$.elastislide = function( options, element ) { this.$el = $( element ); this._init( options ); };

$.elastislide.defaults = { speed : 450, // animation speed easing : , // animation easing effect imageW : 190, // the images width margin : 3, // image margin right border : 2, // image border minItems : 1, // the minimum number of items to show. // when we resize the window, this will make sure minItems are always shown // (unless of course minItems is higher than the total number of elements) current : 0, // index of the current item // when we resize the window, the carousel will make sure this item is visible onClick : function() { return false; } // click item callback

   };

$.elastislide.prototype = { _init : function( options ) {

this.options = $.extend( true, {}, $.elastislide.defaults, options );

//
    this.$slider = this.$el.find('ul'); //
  • this.$items = this.$slider.children('li'); // total number of elements / images this.itemsCount = this.$items.length; // cache the
      's parent, since we will eventually need to recalculate its width on window resize this.$esCarousel = this.$slider.parent(); // validate options this._validateOptions(); // set sizes and initialize some vars... this._configure(); // add navigation buttons this._addControls(); // initialize the events this._initEvents(); // show the
        this.$slider.show(); // slide to current's position this._slideToCurrent( false ); }, _validateOptions : function() { if( this.options.speed < 0 ) this.options.speed = 450; if( this.options.margin < 0 ) this.options.margin = 4; if( this.options.border < 0 ) this.options.border = 1; if( this.options.minItems < 1 || this.options.minItems > this.itemsCount ) this.options.minItems = 1; if( this.options.current > this.itemsCount - 1 ) this.options.current = 0; }, _configure : function() { // current item's index this.current = this.options.current; // the ul's parent's (div.es-carousel) width is the "visible" width this.visibleWidth = this.$esCarousel.width(); // test to see if we need to initially resize the items if( this.visibleWidth < this.options.minItems * ( this.options.imageW + 2 * this.options.border ) + ( this.options.minItems - 1 ) * this.options.margin ) { this._setDim( ( this.visibleWidth - ( this.options.minItems - 1 ) * this.options.margin ) / this.options.minItems ); this._setCurrentValues(); // how many items fit with the current width this.fitCount = this.options.minItems; } else { this._setDim(); this._setCurrentValues(); } // set the
          width this.$slider.css({ width : this.sliderW }); }, _setDim : function( elW ) { //
        • style this.$items.css({ marginRight : this.options.margin, width : ( elW ) ? elW : this.options.imageW + 2 * this.options.border }).children('a').css({ // <a> style borderWidth : this.options.border }); }, _setCurrentValues : function() { // the total space occupied by one item this.itemW = this.$items.outerWidth(true); // total width of the slider /
            // this will eventually change on window resize this.sliderW = this.itemW * this.itemsCount; // the ul parent's (div.es-carousel) width is the "visible" width this.visibleWidth = this.$esCarousel.width(); // how many items fit with the current width this.fitCount = Math.floor( this.visibleWidth / this.itemW ); }, _addControls : function() { this.$navNext = $('Next'); this.$navPrev = $('Previous'); $('<div class="es-nav"/>') .append( this.$navPrev ) .append( this.$navNext ) .appendTo( this.$el ); //this._toggleControls(); }, _toggleControls : function( dir, status ) { // show / hide navigation buttons if( dir && status ) { if( status === 1 ) ( dir === 'right' ) ? this.$navNext.show() : this.$navPrev.show(); else ( dir === 'right' ) ? this.$navNext.hide() : this.$navPrev.hide(); } else if( this.current === this.itemsCount - 1 || this.fitCount >= this.itemsCount ) this.$navNext.hide(); }, _initEvents : function() { var instance = this; // window resize $(window).on('resize.elastislide', function( event ) { instance._reload(); // slide to the current element clearTimeout( instance.resetTimeout ); instance.resetTimeout = setTimeout(function() { instance._slideToCurrent(); }, 200); }); // navigation buttons events this.$navNext.on('click.elastislide', function( event ) { instance._slide('right'); }); this.$navPrev.on('click.elastislide', function( event ) { instance._slide('left'); }); // item click event this.$slider.on('click.elastislide', 'li', function( event ) { instance.options.onClick( $(this) ); return false; }); // touch events instance.$slider.touchwipe({ wipeLeft : function() { instance._slide('right'); }, wipeRight : function() { instance._slide('left'); } }); }, reload : function( callback ) { this._reload(); if ( callback ) callback.call(); }, _reload : function() { var instance = this; // set values again instance._setCurrentValues(); // need to resize items if( instance.visibleWidth < instance.options.minItems * ( instance.options.imageW + 2 * instance.options.border ) + ( instance.options.minItems - 1 ) * instance.options.margin ) { instance._setDim( ( instance.visibleWidth - ( instance.options.minItems - 1 ) * instance.options.margin ) / instance.options.minItems ); instance._setCurrentValues(); instance.fitCount = instance.options.minItems; } else{ instance._setDim(); instance._setCurrentValues(); } instance.$slider.css({ width : instance.sliderW + 10 // TODO: +10px seems to solve a firefox "bug" :S }); }, _slide : function( dir, val, anim, callback ) { // if animating return //if( this.$slider.is(':animated') ) //return false; // current margin left var ml = parseFloat( this.$slider.css('margin-left') ); // val is just passed when we want an exact value for the margin left (used in the _slideToCurrent function) if( val === undefined ) { // how much to slide? var amount = this.fitCount * this.itemW, val; if( amount < 0 ) return false; // make sure not to leave a space between the last item / first item and the end / beggining of the slider available width if( dir === 'right' && this.sliderW - ( Math.abs( ml ) + amount ) < this.visibleWidth ) { amount = this.sliderW - ( Math.abs( ml ) + this.visibleWidth ) - this.options.margin; // decrease the margin left // show / hide navigation buttons this._toggleControls( 'right', -1 ); this._toggleControls( 'left', 1 ); } else if( dir === 'left' && Math.abs( ml ) - amount < 0 ) { amount = Math.abs( ml ); // show / hide navigation buttons this._toggleControls( 'left', -1 ); this._toggleControls( 'right', 1 ); } else { var fml; // future margin left ( dir === 'right' ) ? fml = Math.abs( ml ) + this.options.margin + Math.abs( amount ) : fml = Math.abs( ml ) - this.options.margin - Math.abs( amount ); // show / hide navigation buttons if( fml > 0 ) this._toggleControls( 'left', 1 ); else this._toggleControls( 'left', -1 ); if( fml < this.sliderW - this.visibleWidth ) this._toggleControls( 'right', 1 ); else this._toggleControls( 'right', -1 ); } ( dir === 'right' ) ? val = '-=' + amount : val = '+=' + amount } else { var fml = Math.abs( val ); // future margin left if( Math.max( this.sliderW, this.visibleWidth ) - fml < this.visibleWidth ) { val = - ( Math.max( this.sliderW, this.visibleWidth ) - this.visibleWidth ); if( val !== 0 ) val += this.options.margin; // decrease the margin left if not on the first position // show / hide navigation buttons this._toggleControls( 'right', -1 ); fml = Math.abs( val ); } // show / hide navigation buttons if( fml > 0 ) this._toggleControls( 'left', 1 ); else this._toggleControls( 'left', -1 ); if( Math.max( this.sliderW, this.visibleWidth ) - this.visibleWidth > fml + this.options.margin ) this._toggleControls( 'right', 1 ); else this._toggleControls( 'right', -1 ); } $.fn.applyStyle = ( anim === undefined ) ? $.fn.animate : $.fn.css; var sliderCSS = { marginLeft : val }; var instance = this; this.$slider.stop().applyStyle( sliderCSS, $.extend( true, [], { duration : this.options.speed, easing : this.options.easing, complete : function() { if( callback ) callback.call(); } } ) ); }, _slideToCurrent : function( anim ) { // how much to slide? var amount = this.current * this.itemW; this._slide(, -amount, anim ); }, add : function( $newelems, callback ) { // adds new items to the carousel this.$items = this.$items.add( $newelems ); this.itemsCount = this.$items.length; this._setDim(); this._setCurrentValues(); this.$slider.css({ width : this.sliderW }); this._slideToCurrent(); if ( callback ) callback.call( $newelems ); }, setCurrent : function( idx, callback ) { this.current = idx; var ml = Math.abs( parseFloat( this.$slider.css('margin-left') ) ), posR = ml + this.visibleWidth, fml = Math.abs( this.current * this.itemW ); if( fml + this.itemW > posR || fml < ml ) { this._slideToCurrent(); } if ( callback ) callback.call(); }, destroy : function( callback ) { this._destroy( callback ); }, _destroy : function( callback ) { this.$el.off('.elastislide').removeData('elastislide'); $(window).off('.elastislide'); if ( callback ) callback.call(); } }; var logError = function( message ) { if ( this.console ) { console.error( message ); } }; $.fn.elastislide = function( options ) { if ( typeof options === 'string' ) { var args = Array.prototype.slice.call( arguments, 1 ); this.each(function() { var instance = $.data( this, 'elastislide' ); if ( !instance ) { logError( "cannot call methods on elastislide prior to initialization; " + "attempted to call method '" + options + "'" ); return; } if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) { logError( "no such method '" + options + "' for elastislide instance" ); return; } instance[ options ].apply( instance, args ); }); } else { this.each(function() { var instance = $.data( this, 'elastislide' ); if ( !instance ) { $.data( this, 'elastislide', new $.elastislide( options, this ) ); } }); } return this; }; })( window, jQuery );