GIF89a;
Direktori : /home/serb/www/js/ |
Current File : /home/serb/www/js/bjqs-1.3.js |
/* * Basic jQuery Slider plug-in v.1.3 * * http://www.basic-slider.com * * Authored by John Cobb * http://www.johncobb.name * @john0514 * * Copyright 2011, John Cobb * License: GNU General Public License, version 3 (GPL-3.0) * http://www.opensource.org/licenses/gpl-3.0.html * */ ;(function($) { "use strict"; $.fn.bjqs = function(o) { // slider default settings var defaults = { // w + h to enforce consistency width : 700, height : 300, // transition valuess animtype : 'fade', animduration : 450, // length of transition animspeed : 4000, // delay between transitions automatic : true, // enable/disable automatic slide rotation // control and marker configuration showcontrols : false, // enable/disable next + previous UI elements centercontrols : true, // vertically center controls //nexttext : 'Next', // text/html inside next UI element // prevtext : 'Prev', // text/html inside previous UI element showmarkers : false, // enable/disable individual slide UI markers centermarkers : true, // horizontally center markers // interaction values keyboardnav : true, // enable/disable keyboard navigation hoverpause : true, // enable/disable pause slides on hover // presentational options usecaptions : true, // enable/disable captions using img title attribute randomstart : false, // start from a random slide responsive : false // enable responsive behaviour }; // create settings from defauls and user options var settings = $.extend({}, defaults, o); // slider elements var $wrapper = this, $slider = $wrapper.find('ul.bjqs'), $slides = $slider.children('li'), // control elements $c_wrapper = null, $c_fwd = null, $c_prev = null, // marker elements $m_wrapper = null, $m_markers = null, // elements for slide animation $canvas = null, $clone_first = null, $clone_last = null; // state management object var state = { slidecount : $slides.length, // total number of slides animating : false, // bool: is transition is progress paused : false, // bool: is the slider paused currentslide : 1, // current slide being viewed (not 0 based) nextslide : 0, // slide to view next (not 0 based) currentindex : 0, // current slide being viewed (0 based) nextindex : 0, // slide to view next (0 based) interval : null // interval for automatic rotation }; var responsive = { width : null, height : null, ratio : null }; // helpful variables var vars = { fwd : 'forward', prev : 'previous' }; // run through options and initialise settings var init = function() { // differentiate slider li from content li $slides.addClass('bjqs-slide'); // conf dimensions, responsive or static if( settings.responsive ){ conf_responsive(); } else{ conf_static(); } // configurations only avaliable if more than 1 slide if( state.slidecount > 1 ){ // enable random start if (settings.randomstart){ conf_random(); } // create and show controls if( settings.showcontrols ){ conf_controls(); } // create and show markers if( settings.showmarkers ){ conf_markers(); } // enable slidenumboard navigation if( settings.keyboardnav ){ conf_keynav(); } // enable pause on hover if (settings.hoverpause && settings.automatic){ conf_hoverpause(); } // conf slide animation if (settings.animtype === 'slide'){ conf_slide(); } } else { // Stop automatic animation, because we only have one slide! settings.automatic = false; } if(settings.usecaptions){ conf_captions(); } // TODO: need to accomodate random start for slide transition setting if(settings.animtype === 'slide' && !settings.randomstart){ state.currentindex = 1; state.currentslide = 2; } // slide components are hidden by default, show them now $slider.show(); $slides.eq(state.currentindex).show(); // Finally, if automatic is set to true, kick off the interval if(settings.automatic){ state.interval = setInterval(function () { go(vars.fwd, false); }, settings.animspeed); } }; var conf_responsive = function() { responsive.width = $wrapper.outerWidth(); responsive.ratio = responsive.width/settings.width, responsive.height = settings.height * responsive.ratio; if(settings.animtype === 'fade'){ // initial setup $slides.css({ 'height' : settings.height, 'width' : '100%' }); $slides.children('img').css({ 'height' : settings.height, 'width' : '100%' }); $slider.css({ 'height' : settings.height, 'width' : '100%' }); $wrapper.css({ 'height' : settings.height, 'max-width' : settings.width, 'position' : 'relative' }); if(responsive.width < settings.width){ $slides.css({ 'height' : responsive.height }); $slides.children('img').css({ 'height' : responsive.height }); $slider.css({ 'height' : responsive.height }); $wrapper.css({ 'height' : responsive.height }); } $(window).resize(function() { // calculate and update dimensions responsive.width = $wrapper.outerWidth(); responsive.ratio = responsive.width/settings.width, responsive.height = settings.height * responsive.ratio; $slides.css({ 'height' : responsive.height }); $slides.children('img').css({ 'height' : responsive.height }); $slider.css({ 'height' : responsive.height }); $wrapper.css({ 'height' : responsive.height }); }); } if(settings.animtype === 'slide'){ // initial setup $slides.css({ 'height' : settings.height, 'width' : settings.width }); $slides.children('img').css({ 'height' : settings.height, 'width' : settings.width }); $slider.css({ 'height' : settings.height, 'width' : settings.width * settings.slidecount }); $wrapper.css({ 'height' : settings.height, 'max-width' : settings.width, 'position' : 'relative' }); if(responsive.width < settings.width){ $slides.css({ 'height' : responsive.height }); $slides.children('img').css({ 'height' : responsive.height }); $slider.css({ 'height' : responsive.height }); $wrapper.css({ 'height' : responsive.height }); } $(window).resize(function() { // calculate and update dimensions responsive.width = $wrapper.outerWidth(), responsive.ratio = responsive.width/settings.width, responsive.height = settings.height * responsive.ratio; $slides.css({ 'height' : responsive.height, 'width' : responsive.width }); $slides.children('img').css({ 'height' : responsive.height, 'width' : responsive.width }); $slider.css({ 'height' : responsive.height, 'width' : responsive.width * settings.slidecount }); $wrapper.css({ 'height' : responsive.height }); $canvas.css({ 'height' : responsive.height, 'width' : responsive.width }); resize_complete(function(){ go(false,state.currentslide); }, 200, "some unique string"); }); } }; var resize_complete = (function () { var timers = {}; return function (callback, ms, uniqueId) { if (!uniqueId) { uniqueId = "Don't call this twice without a uniqueId"; } if (timers[uniqueId]) { clearTimeout (timers[uniqueId]); } timers[uniqueId] = setTimeout(callback, ms); }; })(); // enforce fixed sizing on slides, slider and wrapper var conf_static = function() { $slides.css({ 'height' : settings.height, 'width' : settings.width }); $slider.css({ 'height' : settings.height, 'width' : settings.width }); $wrapper.css({ 'height' : settings.height, 'width' : settings.width, 'position' : 'relative' }); }; var conf_slide = function() { // create two extra elements which are clones of the first and last slides $clone_first = $slides.eq(0).clone(); $clone_last = $slides.eq(state.slidecount-1).clone(); // add them to the DOM where we need them $clone_first.attr({'data-clone' : 'last', 'data-slide' : 0}).appendTo($slider).show(); $clone_last.attr({'data-clone' : 'first', 'data-slide' : 0}).prependTo($slider).show(); // update the elements object $slides = $slider.children('li'); state.slidecount = $slides.length; // create a 'canvas' element which is neccessary for the slide animation to work $canvas = $('<div class="bjqs-wrapper"></div>'); // if the slider is responsive && the calculated width is less than the max width if(settings.responsive && (responsive.width < settings.width)){ $canvas.css({ 'width' : responsive.width, 'height' : responsive.height, 'overflow' : 'hidden', 'position' : 'relative' }); // update the dimensions to the slider to accomodate all the slides side by side $slider.css({ 'width' : responsive.width * (state.slidecount + 2), 'left' : -responsive.width * state.currentslide }); } else { $canvas.css({ 'width' : settings.width, 'height' : settings.height, 'overflow' : 'hidden', 'position' : 'relative' }); // update the dimensions to the slider to accomodate all the slides side by side $slider.css({ 'width' : settings.width * (state.slidecount + 2), 'left' : -settings.width * state.currentslide }); } // add some inline styles which will align our slides for left-right sliding $slides.css({ 'float' : 'left', 'position' : 'relative', 'display' : 'list-item' }); // 'everything.. in it's right place' $canvas.prependTo($wrapper); $slider.appendTo($canvas); }; var conf_controls = function() { // create the elements for the controls $c_wrapper = $('<ul class="bjqs-controls"></ul>'); $c_fwd = $('<li class="bjqs-next"><a href="#" data-direction="'+ vars.fwd +'">' + settings.nexttext + '</a></li>'); $c_prev = $('<li class="bjqs-prev"><a href="#" data-direction="'+ vars.prev +'">' + settings.prevtext + '</a></li>'); // bind click events $c_wrapper.on('click','a',function(e){ e.preventDefault(); var direction = $(this).attr('data-direction'); if(!state.animating){ if(direction === vars.fwd){ go(vars.fwd,false); } if(direction === vars.prev){ go(vars.prev,false); } } }); // put 'em all together $c_prev.appendTo($c_wrapper); $c_fwd.appendTo($c_wrapper); $c_wrapper.appendTo($wrapper); // vertically center the controls if (settings.centercontrols) { $c_wrapper.addClass('v-centered'); // calculate offset % for vertical positioning var offset_px = ($wrapper.height() - $c_fwd.children('a').outerHeight()) / 2, ratio = (offset_px / settings.height) * 100, offset = ratio + '%'; $c_fwd.find('a').css('top', offset); $c_prev.find('a').css('top', offset); } }; var conf_markers = function() { // create a wrapper for our markers $m_wrapper = $('<ol class="bjqs-markers"></ol>'); // for every slide, create a marker $.each($slides, function(key, slide){ var slidenum = key + 1, gotoslide = key + 1; if(settings.animtype === 'slide'){ // + 2 to account for clones gotoslide = key + 2; } var marker = $('<li><a href="#">'+ slidenum +'</a></li>'); // set the first marker to be active if(slidenum === state.currentslide){ marker.addClass('active-marker'); } // bind the click event marker.on('click','a',function(e){ e.preventDefault(); if(!state.animating && state.currentslide !== gotoslide){ go(false,gotoslide); } }); // add the marker to the wrapper marker.appendTo($m_wrapper); }); $m_wrapper.appendTo($wrapper); $m_markers = $m_wrapper.find('li'); // center the markers if (settings.centermarkers) { $m_wrapper.addClass('h-centered'); var offset = (settings.width - $m_wrapper.width()) / 2; $m_wrapper.css('left', offset); } }; var conf_keynav = function() { $(document).keyup(function (event) { if (!state.paused) { clearInterval(state.interval); state.paused = true; } if (!state.animating) { if (event.keyCode === 39) { event.preventDefault(); go(vars.fwd, false); } else if (event.keyCode === 37) { event.preventDefault(); go(vars.prev, false); } } if (state.paused && settings.automatic) { state.interval = setInterval(function () { go(vars.fwd); }, settings.animspeed); state.paused = false; } }); }; var conf_hoverpause = function() { $wrapper.hover(function () { if (!state.paused) { clearInterval(state.interval); state.paused = true; } }, function () { if (state.paused) { state.interval = setInterval(function () { go(vars.fwd, false); }, settings.animspeed); state.paused = false; } }); }; var conf_captions = function() { $.each($slides, function (key, slide) { var caption = $(slide).children('img:first-child').attr('title'); // Account for images wrapped in links if(!caption){ caption = $(slide).children('a').find('img:first-child').attr('title'); } if (caption) { caption = $('<p class="bjqs-caption">' + caption + '</p>'); caption.appendTo($(slide)); } }); }; var conf_random = function() { var rand = Math.floor(Math.random() * state.slidecount) + 1; state.currentslide = rand; state.currentindex = rand-1; }; var set_next = function(direction) { if(direction === vars.fwd){ if($slides.eq(state.currentindex).next().length){ state.nextindex = state.currentindex + 1; state.nextslide = state.currentslide + 1; } else{ state.nextindex = 0; state.nextslide = 1; } } else{ if($slides.eq(state.currentindex).prev().length){ state.nextindex = state.currentindex - 1; state.nextslide = state.currentslide - 1; } else{ state.nextindex = state.slidecount - 1; state.nextslide = state.slidecount; } } }; var go = function(direction, position) { // only if we're not already doing things if(!state.animating){ // doing things state.animating = true; if(position){ state.nextslide = position; state.nextindex = position-1; } else{ set_next(direction); } // fade animation if(settings.animtype === 'fade'){ if(settings.showmarkers){ $m_markers.removeClass('active-marker'); $m_markers.eq(state.nextindex).addClass('active-marker'); } // fade out current $slides.eq(state.currentindex).fadeOut(settings.animduration); // fade in next $slides.eq(state.nextindex).fadeIn(settings.animduration, function(){ // update state variables state.animating = false; state.currentslide = state.nextslide; state.currentindex = state.nextindex; }); } // slide animation if(settings.animtype === 'slide'){ if(settings.showmarkers){ var markerindex = state.nextindex-1; if(markerindex === state.slidecount-2){ markerindex = 0; } else if(markerindex === -1){ markerindex = state.slidecount-3; } $m_markers.removeClass('active-marker'); $m_markers.eq(markerindex).addClass('active-marker'); } // if the slider is responsive && the calculated width is less than the max width if(settings.responsive && ( responsive.width < settings.width ) ){ state.slidewidth = responsive.width; } else{ state.slidewidth = settings.width; } $slider.animate({'left': -state.nextindex * state.slidewidth }, settings.animduration, function(){ state.currentslide = state.nextslide; state.currentindex = state.nextindex; // is the current slide a clone? if($slides.eq(state.currentindex).attr('data-clone') === 'last'){ // affirmative, at the last slide (clone of first) $slider.css({'left': -state.slidewidth }); state.currentslide = 2; state.currentindex = 1; } else if($slides.eq(state.currentindex).attr('data-clone') === 'first'){ // affirmative, at the fist slide (clone of last) $slider.css({'left': -state.slidewidth *(state.slidecount - 2)}); state.currentslide = state.slidecount - 1; state.currentindex = state.slidecount - 2; } state.animating = false; }); } } }; // lets get the party started :) init(); }; })(jQuery);