/*
* slides, a slideshow plugin for jquery
* intructions: http://slidesjs.com
* by: nathan searles, http://nathansearles.com
* version: 1.0
* updated: november 21st, 2010
*
* licensed under the apache license, version 2.0 (the "license");
* you may not use this file except in compliance with the license.
* you may obtain a copy of the license at
*
* http://www.apache.org/licenses/license-2.0
*
* unless required by applicable law or agreed to in writing, software
* distributed under the license is distributed on an "as is" basis,
* without warranties or conditions of any kind, either express or implied.
* see the license for the specific language governing permissions and
* limitations under the license.
*/
(function($){
$.fn.slides = function( option ) {
// override defaults with specified option
option = $.extend( {}, $.fn.slides.option, option );
return this.each(function(){
// wrap slides in control container, make sure slides are block level
$('.' + option.container, $(this)).children().wrapall('
').children().css({
display:'block'
});
var elem = $(this),
control = $('.slides_control',elem),
total = control.children().size(),
width = control.children().outerwidth(),
height = control.children().outerheight(),
start = option.start - 1,
effect = option.effect.indexof(',') < 0 ? option.effect : option.effect.replace(' ', '').split(',')[0],
paginationeffect = option.effect.indexof(',') < 0 ? effect : option.effect.replace(' ', '').split(',')[1],
next = 0, prev = 0, number = 0, current = 0, loaded, active, clicked, position, direction;
// 2 or more slides required
if (total < 2) {
return;
}
// change current based on start option number
if (option.start) {
current = start;
};
// randomizes slide order
if (option.randomize) {
control.randomize();
}
// set width based on slide width
elem.css({
width: width
});
$(this).find('li').css({
width: '100%'
});
// make sure overflow is hidden
$('.' + option.container, elem).css({
overflow: 'hidden',
// fix for ie
position: 'relative'
});
control.css({
position: 'relative',
// size of control 3 x slide width
width: ('100%' * 3),
// set height to slide height
height: height,
// center control to slide
left: '-100%'
});
// set css for slides
control.children().css({
position: 'absolute',
top: 0,
left: '100%',
zindex: 0,
display: 'none'
});
// if autoheight true, get and set height of first slide
if (option.autoheight) {
control.animate({
height: control.children(':eq('+ start +')').outerheight()
},o.autoheightspeed);
}
// checks if image is loaded
if (option.preload && control.children()[0].tagname=='img') {
// adds preload image
elem.css({
background: 'url(' + option.preloadimage + ') no-repeat 50% 50%'
});
// gets image src, with cache buster
var img = $('img:eq(' + start + ')', elem).attr('src') + '?' + (new date()).gettime();
// checks if image is loaded
$('img:eq(' + start + ')', elem).attr('src', img).load(function() {
// once image is fully loaded, fade in
$(this).fadein(option.fadespeed,function(){
$(this).css({
zindex: 5
});
// removes preload image
elem.css({
background: ''
});
// let the script know everything is loaded
loaded = true;
});
});
} else {
// if no preloader fade in start slide
control.find(':eq(' + start + ')').fadein(option.fadespeed,function(){
// let the script know everything is loaded
loaded = true;
});
}
// click slide for next
if (option.bigtarget) {
// set cursor to pointer
control.children().css({
cursor: 'pointer'
});
// click handler
control.children().click(function(){
// animate to next on slide click
animate('next', effect);
return false;
});
}
// pause on mouseover
if (option.hoverpause && option.play) {
control.children().bind('mouseover',function(){
// on mouse over stop
stop();
});
control.children().bind('mouseleave',function(){
// on mouse leave start pause timeout
pause();
});
}
// next button
$('.' + option.next ,elem).click(function(e){
e.preventdefault();
if (option.play) {
pause();
};
animate('next', effect);
});
// previous button
$('.' + option.prev, elem).click(function(e){
e.preventdefault();
if (option.play) {
pause();
};
animate('prev', effect);
});
// pause button
$('.pause').bind('click',function(){
// on click stop
stop();
});
// generate pagination
/* if (option.generatepagination) {
// create unordered list
elem.append('');
// for each slide create a list item and link
control.children().each(function(){
$('.' + option.paginationclass, elem).append(''+ (number+1) +'');
number++;
});
} */
// add current class to start slide pagination
$('.' + option.paginationclass + ' li a:eq('+ start +')', elem).parent().addclass('current');
// click handling
$('.' + option.paginationclass + ' li a', elem ).click(function(){
// pause slideshow
if (option.play) {
pause();
};
// get clicked, pass to animate function
clicked = $(this).attr('rel');
// if current slide equals clicked, don't do anything
if (current != clicked) {
animate('pagination', paginationeffect, clicked);
}
return false;
});
if (option.play) {
// set interval
playinterval = setinterval(function() {
animate('next', effect);
}, option.play);
// store interval id
elem.data('interval',playinterval);
};
function stop() {
// clear interval from stored id
clearinterval(elem.data('interval'));
};
function pause() {
if (option.pause) {
// clear timeout and interval
cleartimeout(elem.data('pause'));
clearinterval(elem.data('interval'));
// pause slide show for option.pause amount
pausetimeout = settimeout(function() {
// clear pause timeout
cleartimeout(elem.data('pause'));
// start play interval after pause
playinterval = setinterval( function(){
animate("next", effect);
},option.play);
// store play interval
elem.data('interval',playinterval);
},option.pause);
// store pause interval
elem.data('pause',pausetimeout);
} else {
// if no pause, just stop
stop();
}
};
// animate slides
function animate(direction, effect, clicked) {
width = control.children().outerwidth();
if (!active && loaded) {
active = true;
switch(direction) {
case 'next':
// change current slide to previous
prev = current;
// get next from current + 1
next = current + 1;
// if last slide, set next to first slide
next = total === next ? 0 : next;
// set position of next slide to right of previous
position = width*2;
// distance to slide based on width of slides
direction = -width*2;
// store new current slide
current = next;
break;
case 'prev':
// change current slide to previous
prev = current;
// get next from current - 1
next = current - 1;
// if first slide, set next to last slide
next = next === -1 ? total-1 : next;
// set position of next slide to left of previous
position = 0;
// distance to slide based on width of slides
direction = 0;
// store new current slide
current = next;
break;
case 'pagination':
// get next from pagination item clicked, convert to number
next = parseint(clicked,10);
// get previous from pagination item with class of current
prev = $('.' + option.paginationclass + ' li.current a', elem).attr('rel');
// if next is greater then previous set position of next slide to right of previous
if (next > prev) {
position = width*2;
direction = -width*2;
} else {
// if next is less then previous set position of next slide to left of previous
position = 0;
direction = 0;
}
// store new current slide
current = next;
break;
}
// fade animation
if (effect === 'fade') {
// fade animation with crossfade
if (option.crossfade) {
// put hidden next above current
control.children(':eq('+ next +')', elem).css({
zindex: 10
// fade in next
}).fadein(option.fadespeed, function(){
// hide previous
control.children(':eq('+ prev +')', elem).css({
display: 'none',
zindex: 0
});
// reset z index
$(this).css({
zindex: 0
});
// end of animation
active = false;
});
} else {
// fade animation with no crossfade
control.children(':eq('+ prev +')', elem).fadeout(option.fadespeed,function(){
// animate to new height
if (option.autoheight) {
control.animate({
// animate container to height of next
height: control.children(':eq('+ next +')', elem).outerheight()
}, option.autoheightspeed,
// fade in next slide
function(){
control.children(':eq('+ next +')', elem).fadein(elem.data('slides').fadespeed);
});
} else {
// if fixed height
control.children(':eq('+ next +')', elem).fadein(option.fadespeed,function(){
// fix font rendering in ie, lame
if($.browser.msie) {
$(this).get(0).style.removeattribute('filter');
}
});
}
// end of animation
active = false;
});
}
// slide animation
} else {
// move next slide to right of previous
control.children(':eq('+ next +')').css({
left: position,
display: 'block'
});
// animate to new height
if (option.autoheight) {
control.animate({
left: direction,
height: control.children(':eq('+ next +')').outerheight()
},option.slidespeed,function(){
control.css({
left: '-100%'
});
control.children(':eq('+ next +')').css({
left: '100%',
zindex: 5
});
// reset previous slide
control.children(':eq('+ prev +')').css({
left: '100%',
display: 'none',
zindex: 0
});
// end of animation
active = false;
});
// if fixed height
} else {
// animate control
control.animate({
left: direction
},option.slidespeed,function(){
// after animation reset control position
control.css({
left: '-100%'
});
// reset and show next
control.children(':eq('+ next +')').css({
left: '100%',
zindex: 5
});
// reset previous slide
control.children(':eq('+ prev +')').css({
left: '100%',
display: 'none',
zindex: 0
});
// end of animation
active = false;
});
}
}
// set current state for pagination
if (option.pagination) {
// remove current class from all
$('.'+ option.paginationclass +' li.current', elem).removeclass('current');
// add current class to next
$('.'+ option.paginationclass +' li a:eq('+ next +')', elem).parent().addclass('current');
}
}
}; // end animate function
});
};
// default options
$.fn.slides.option = {
preload: true, // boolean, set true to preload images in an image based slideshow
preloadimage: '/img/loading.gif', // string, name and location of loading image for preloader. default is "/img/loading.gif"
container: 'slides_container', // string, class name for slides container. default is "slides_container"
next: 'next', // string, class name for next button
prev: 'prev', // string, class name for previous button
pagination: true, // boolean, if you're not using pagination you can set to false, but don't have to
generatepagination: true, // boolean, auto generate pagination
paginationclass: 'pagination', // string, class name for pagination
fadespeed: 850, // number, set the speed of the fading animation in milliseconds
slidespeed: 850, // number, set the speed of the sliding animation in milliseconds
start: 1, // number, set the speed of the sliding animation in milliseconds
effect: 'slide', // string, '[next/prev], [pagination]', e.g. 'slide, fade' or simply 'fade' for both
crossfade: false, // boolean, crossfade images in a image based slideshow
randomize: false, // boolean, set to true to randomize slides
play: 0, // number, autoplay slideshow, a positive number will set to true and be the time between slide animation in milliseconds
pause: 0, // number, pause slideshow on click of next/prev or pagination. a positive number will set to true and be the time of pause in milliseconds
hoverpause: false, // boolean, set to true and hovering over slideshow will pause it
autoheight: false, // boolean, set to true to auto adjust height
autoheightspeed: 350, // number, set auto height animation time in milliseconds
bigtarget: false // boolean, set to true and the whole slide will link to next slide on click
};
// randomize slide order on load
$.fn.randomize = function(callback) {
function randomizeorder() { return(math.round(math.random())-0.5); }
return($(this).each(function() {
var $this = $(this);
var $children = $this.children();
var childcount = $children.length;
if (childcount > 1) {
$children.hide();
var indices = [];
for (i=0;i