/*
anythingslider v1.5.18
by chris coyier: http://css-tricks.com
with major improvements by doug neiner: http://pixelgraphics.us/
based on work by remy sharp: http://jqueryfordesigners.com/
and crazy mods by rob garrison (aka mottie): https://github.com/proloser/anythingslider
to use the navigationformatter function, you must have a function that
accepts two paramaters, and returns a string of html text.
index = integer index (1 based);
panel = jquery wrapped li item this tab references
@return = must return a string of html/text
navigationformatter: function(index, panel){
return "panel #" + index; // this would have each tab with the text 'panel #x' where x = index
}
*/
(function($) {
$.anythingslider = function(el, options) {
// to avoid scope issues, use 'base' instead of 'this'
// to reference this class from internal events and functions.
var base = this, o;
// wraps the ul in the necessary divs and then gives access to jquery element
base.$el = $(el).addclass('anythingbase').wrap('
');
// add a reverse reference to the dom object
base.$el.data("anythingslider", base);
base.init = function(){
// added "o" to be used in the code instead of "base.options" which doesn't get modifed by the compiler - reduces size by ~1k
base.options = o = $.extend({}, $.anythingslider.defaults, options);
base.initialized = false;
if ($.isfunction(o.onbeforeinitialize)) { base.$el.bind('before_initialize', o.onbeforeinitialize); }
base.$el.trigger('before_initialize', base);
// cache existing dom elements for later
// base.$el = original ul
// for wrap - get parent() then closest in case the ul has "anythingslider" class
base.$wrapper = base.$el.parent().closest('div.anythingslider').addclass('anythingslider-' + o.theme);
base.$window = base.$el.closest('div.anythingwindow');
base.$controls = $('').appendto( (o.appendcontrolsto !== null && $(o.appendcontrolsto).length) ? $(o.appendcontrolsto) : base.$wrapper); // change so this works in jquery 1.3.2
base.win = window;
base.$win = $(base.win);
base.$nav = $('
// if a formatter function is present, use it
if ($.isfunction(o.navigationformatter)) {
tmp = o.navigationformatter(index, $(this));
$a.html(index +''+tmp+'');
// add formatting to title attribute if text is hidden
if (parseint($a.find('span').css('text-indent'),10) < 0) { $a.addclass(o.tooltipclass).attr('title', tmp); }
} else {
$a.html('' + index + '');
}
$a.bind(o.clickcontrols, function(e) {
if (!base.flag && o.enablenavigation) {
// prevent running functions twice (once for click, second time for focusin)
base.flag = true; settimeout(function(){ base.flag = false; }, 100);
base.gotopage(index);
if (o.hashtags) { base.sethash(index); }
}
e.preventdefault();
});
});
}
};
// creates the forward/backward buttons
base.buildnextbackbuttons = function() {
if (base.$forward) { return; }
base.$forward = $('' + o.forwardtext + '');
base.$back = $('' + o.backtext + '');
// bind to the forward and back buttons
base.$back.bind(o.clickarrows, function(e) {
base.goback();
e.preventdefault();
});
base.$forward.bind(o.clickarrows, function(e) {
base.goforward();
e.preventdefault();
});
// using tab to get to arrow links will show they have focus (outline is disabled in css)
base.$back.add(base.$forward).find('a').bind('focusin focusout',function(){
$(this).toggleclass('hover');
});
// append elements to page
base.$wrapper.prepend(base.$forward).prepend(base.$back);
base.$arrowwidth = base.$forward.width();
};
// creates the start/stop button
base.buildautoplay = function(){
if (base.$startstop || base.pages < 2) { return; }
base.$startstop = $("").html('' + (base.playing ? o.stoptext : o.starttext) + '');
base.$controls.prepend(base.$startstop);
base.$startstop
.bind(o.clickslideshow, function(e) {
if (o.enableplay) {
base.startstop(!base.playing);
if (base.playing) {
if (o.playrtl) {
base.goback(true);
} else {
base.goforward(true);
}
}
}
e.preventdefault();
})
// show button has focus while tabbing
.bind('focusin focusout',function(){
$(this).toggleclass('hover');
});
// use the same setting, but trigger the start;
base.startstop(base.playing);
};
// adjust slider dimensions on parent element resize
base.checkresize = function(stoptimer){
cleartimeout(base.resizetimer);
base.resizetimer = settimeout(function(){
var w = base.$outer.width(), h = (base.$outer[0].tagname === "body") ? base.$win.height() : base.$outer.height(), dim = base.outerdim;
if (dim[0] !== w || dim[1] !== h) {
base.outerdim = [ w, h ];
base.setdimensions(); // adjust panel sizes
// make sure page is lined up (use 1 millisecond animation time, because "0||x" ignores zeros)
base.gotopage(base.currentpage, base.playing, null, 1);
}
if (typeof(stoptimer) === 'undefined'){ base.checkresize(); }
}, 500);
};
// set panel dimensions to either resize content or adjust panel to content
base.setdimensions = function(){
var w, h, c, cw, dw, leftedge = 0,
// showmultiple must have o.width set!!
bww = (o.showmultiple > 1) ? o.width || base.$window.width()/o.showmultiple : base.$window.width(),
winw = base.$win.width();
if (o.expand){
w = base.$outer.width() - base.outerpad[0];
h = base.$outer.height() - base.outerpad[1];
base.$wrapper.add(base.$window).add(base.$items).css({ width: w, height: h });
bww = (o.showmultiple > 1) ? w/o.showmultiple : w;
}
base.$items.each(function(i){
c = $(this).children('*');
if (o.resizecontents){
// get viewport width & height from options (if set), or css
w = parseint(o.width,10) || bww;
h = parseint(o.height,10) || base.$window.height();
// resize panel
$(this).css({ width: w, height: h });
// resize panel contents, if solitary (wrapped content or solitary image)
if (c.length === 1){
c.css({ width: '100%', height: '100%' });
if (c[0].tagname === "object") { c.find('embed').andself().attr({ width: '100%', height: '100%' }); }
}
} else {
// get panel width & height and save it
w = $(this).width(); // if not defined, it will return the width of the ul parent
dw = (w >= winw) ? true : false; // width defined from css?
if (c.length === 1 && dw){
cw = (c.width() >= winw) ? bww : c.width(); // get width of solitary child
$(this).css('width', cw); // set width of panel
c.css('max-width', cw); // set max width for all children
w = cw;
}
w = (dw) ? o.width || bww : w;
$(this).css('width', w);
h = $(this).outerheight(); // get height after setting width
$(this).css('height', h);
}
base.panelsize[i] = [w,h,leftedge];
leftedge += w;
});
// set total width of slider, but don't go beyond the set max overall width (limited by opera)
base.$el.css('width', (leftedge < o.maxoverallwidth) ? leftedge : o.maxoverallwidth);
};
// get dimension of multiple panels, as needed
base.getdim = function(page){
page = (o.infiniteslides && base.pages > 1) ? page : page - 1;
var i,
w = base.panelsize[page][0],
h = base.panelsize[page][1];
if (o.showmultiple > 1) {
for (i=1; i < o.showmultiple; i++) {
w += base.panelsize[(page + i)%o.showmultiple][0];
h = math.max(h, base.panelsize[page + i][1]);
}
}
return [w,h];
};
base.gotopage = function(page, autoplay, callback, time) {
if (base.pages <= 1) { return; } // prevents animation
base.$lastpage = base.$currentpage;
if (typeof(page) !== "number") {
page = o.startpanel;
base.setcurrentpage(page);
}
// pause youtube videos before scrolling or prevent change if playing
if (base.hasemb && base.checkvideo(base.playing)) { return; }
if (page > base.pages + 1 - base.adjustlimit) { page = (!o.infiniteslides && !o.stopatend) ? 1 : base.pages; }
if (page < base.adjustlimit ) { page = (!o.infiniteslides && !o.stopatend) ? base.pages : 1; }
base.currentpage = ( page > base.pages ) ? base.pages : ( page < 1 ) ? 1 : base.currentpage;
base.$currentpage = base.$items.eq(base.currentpage - 1);
base.exactpage = page;
base.$el.trigger('slide_init', base);
base.slidecontrols(true, false);
// when autoplay isn't passed, we stop the timer
if (autoplay !== true) { autoplay = false; }
// stop the slider when we reach the last page, if the option stopatend is set to true
if (!autoplay || (o.stopatend && page === base.pages)) { base.startstop(false); }
base.$el.trigger('slide_begin', base);
// resize slider if content size varies
if (!o.resizecontents) {
// animating the wrapper resize before the window prevents flickering in firefox
var d = base.getdim(page);
base.$wrapper.filter(':not(:animated)').animate(
{ width: d[0], height: d[1] },
{ queue: false, duration: time || o.animationtime, easing: o.easing }
);
}
// animate slider
base.$el.filter(':not(:animated)').animate(
{ left : -base.panelsize[(o.infiniteslides && base.pages > 1) ? page : page - 1][2] },
{ queue: false, duration: time || o.animationtime, easing: o.easing, complete: function(){ base.endanimation(page, callback); } }
);
};
base.endanimation = function(page, callback){
if (page === 0) {
base.$el.css('left', -base.panelsize[base.pages][2]);
page = base.pages;
} else if (page > base.pages) {
// reset back to start position
base.$el.css('left', -base.panelsize[1][2]);
page = 1;
}
base.exactpage = page;
base.setcurrentpage(page, false);
// add active panel class
base.$items.removeclass('activepage').eq(page - base.adjustlimit).addclass('activepage');
if (!base.hovered) { base.slidecontrols(false); }
// continue youtube video if in current panel
if (base.hasemb){
var emb = base.$currentpage.find('object[id*=ytvideo], embed[id*=ytvideo]');
// player states: unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5).
if (emb.length && $.isfunction(emb[0].getplayerstate) && emb[0].getplayerstate() > 0 && emb[0].getplayerstate() !== 5) {
emb[0].playvideo();
}
}
base.$el.trigger('slide_complete', base);
// callback from external slide control: $('#slider').anythingslider(4, function(slider){ })
if (typeof callback === 'function') { callback(base); }
// continue slideshow after a delay
if (o.autoplaylocked && !base.playing) {
settimeout(function(){
base.startstop(true);
// subtract out slide delay as the slideshow waits that additional time.
}, o.resumedelay - o.delay);
}
};
base.setcurrentpage = function(page, move) {
page = parseint(page, 10);
if (page > base.pages + 1 - base.adjustlimit) { page = base.pages - base.adjustlimit; }
if (page < base.adjustlimit ) { page = 1; }
// set visual
if (o.buildnavigation){
base.$nav.find('.cur').removeclass('cur');
base.$nav.find('a').eq(page - 1).addclass('cur');
}
// hide/show arrows based on infinite scroll mode
if (!o.infiniteslides && o.stopatend){
base.$wrapper.find('span.forward')[ page === base.pages ? 'addclass' : 'removeclass']('disabled');
base.$wrapper.find('span.back')[ page === 1 ? 'addclass' : 'removeclass']('disabled');
if (page === base.pages && base.playing) { base.startstop(); }
}
// only change left if move does not equal false
if (!move) {
var d = base.getdim(page);
base.$wrapper.css({ width: d[0], height: d[1] });
base.$wrapper.scrollleft(0); // reset in case tabbing changed this scrollleft
base.$el.css('left', -base.panelsize[(o.infiniteslides && base.pages > 1) ? page : page - 1][2] );
}
// update local variable
base.currentpage = page;
base.$currentpage = base.$items.eq(page).addclass('activepage');
// set current slider as active so keyboard navigation works properly
if (!base.$wrapper.is('.activeslider')){
$('.activeslider').removeclass('activeslider');
base.$wrapper.addclass('activeslider');
}
};
base.goforward = function(autoplay) {
if (autoplay !== true) { autoplay = false; base.startstop(false); }
base.gotopage(base.currentpage + 1, autoplay);
};
base.goback = function(autoplay) {
if (autoplay !== true) { autoplay = false; base.startstop(false); }
base.gotopage(base.currentpage - 1, autoplay);
};
// this method tries to find a hash that matches panel-x
// if found, it tries to find a matching item
// if that is found as well, then that item starts visible
base.gotohash = function(){
var n = base.win.location.hash.match(base.regex);
return (n===null) ? '' : parseint(n[1],10);
};
base.sethash = function(n){
var s = 'panel' + base.runtimes + '-',
h = base.win.location.hash;
if ( typeof h !== 'undefined' ) {
base.win.location.hash = (h.indexof(s) > 0) ? h.replace(base.regex, s + n) : h + "&" + s + n;
}
};
// slide controls (nav and play/stop button up or down)
base.slidecontrols = function(toggle){
var dir = (toggle) ? 'slidedown' : 'slideup',
t1 = (toggle) ? 0 : o.animationtime,
t2 = (toggle) ? o.animationtime: 0,
op = (toggle) ? 1: 0,
sign = (toggle) ? 0 : 1; // 0 = visible, 1 = hidden
if (o.togglecontrols) {
base.$controls.stop(true,true).delay(t1)[dir](o.animationtime/2).delay(t2);
}
if (o.buildarrows && o.togglearrows) {
if (!base.hovered && base.playing) { sign = 1; op = 0; } // don't animate arrows during slideshow
base.$forward.stop(true,true).delay(t1).animate({ right: sign * base.$arrowwidth, opacity: op }, o.animationtime/2);
base.$back.stop(true,true).delay(t1).animate({ left: sign * base.$arrowwidth, opacity: op }, o.animationtime/2);
}
};
base.cleartimer = function(paused){
// clear the timer only if it is set
if (base.timer) {
base.win.clearinterval(base.timer);
if (!paused && base.slideshow) {
base.$el.trigger('slideshow_stop', base);
base.slideshow = false;
}
}
};
// handles stopping and playing the slideshow
// pass startstop(false) to stop and startstop(true) to play
base.startstop = function(playing, paused) {
if (playing !== true) { playing = false; } // default if not supplied is false
if (playing && !paused) {
base.$el.trigger('slideshow_start', base);
base.slideshow = true;
}
// update variable
base.playing = playing;
// toggle playing and text
if (o.autoplay) {
base.$startstop.toggleclass('playing', playing).html('' + (playing ? o.stoptext : o.starttext) + '');
// add button text to title attribute if it is hidden by text-indent
if (parseint(base.$startstop.find('span').css('text-indent'),10) < 0) {
base.$startstop.addclass(o.tooltipclass).attr('title', playing ? 'stop' : 'start');
}
}
if (playing){
base.cleartimer(true); // just in case this was triggered twice in a row
base.timer = base.win.setinterval(function() {
// prevent autoplay if video is playing
if (!(base.hasemb && base.checkvideo(playing))) {
if (o.playrtl) {
base.goback(true);
} else {
base.goforward(true);
}
}
}, o.delay);
} else {
base.cleartimer();
}
};
base.checkvideo = function(playing){
// pause youtube videos before scrolling?
var emb, ps, stopadvance = false;
base.$items.find('object[id*=ytvideo], embed[id*=ytvideo]').each(function(){ // include embed for ie; if not using swfobject, old detach/append code needs "object embed" here
emb = $(this);
if (emb.length && $.isfunction(emb[0].getplayerstate)) {
// player states: unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5).
ps = emb[0].getplayerstate();
// if autoplay, video playing, video is in current panel and resume option are true, then don't advance
if (playing && (ps === 1 || ps > 2) && base.$items.index(emb.closest('li.panel')) === base.currentpage && o.resumeonvideoend) {
stopadvance = true;
} else {
// pause video if not autoplaying (if already initialized)
if (ps > 0) { emb[0].pausevideo(); }
}
}
});
return stopadvance;
};
// trigger the initialization
base.init();
};
$.anythingslider.defaults = {
// appearance
width : null, // override the default css width
height : null, // override the default css height
expand : false, // if true, the entire slider will expand to fit the parent element
resizecontents : true, // if true, solitary images/objects in the panel will expand to fit the viewport
showmultiple : false, // set this value to a number and it will show that many slides at once
tooltipclass : 'tooltip', // class added to navigation & start/stop button (text copied to title if it is hidden by a negative text indent)
theme : 'default', // theme name
themedirectory : 'css/theme-{themename}.css', // theme directory & filename {themename} is replaced by the theme value above
// navigation
startpanel : 1, // this sets the initial panel
hashtags : true, // should links change the hashtag in the url?
infiniteslides : true, // if false, the slider will not wrap
enablekeyboard : true, // if false, keyboard arrow keys will not work for the current panel.
buildarrows : true, // if true, builds the forwards and backwards buttons
togglearrows : false, // if true, side navigation arrows will slide out on hovering & hide @ other times
buildnavigation : true, // if true, builds a list of anchor links to link to each panel
enablenavigation : true, // if false, navigation links will still be visible, but not clickable.
togglecontrols : false, // if true, slide in controls (navigation + play/stop button) on hover and slide change, hide @ other times
appendcontrolsto : null, // a html element (jquery object, selector or htmlnode) to which the controls will be appended if not null
navigationformatter : null, // details at the top of the file on this use (advanced use)
forwardtext : "»", // link text used to move the slider forward (hidden by css, replaced with arrow image)
backtext : "«", // link text used to move the slider back (hidden by css, replace with arrow image)
// slideshow options
enableplay : true, // if false, the play/stop button will still be visible, but not clickable.
autoplay : true, // this turns off the entire slideshow functionaly, not just if it starts running or not
autoplaylocked : false, // if true, user changing slides will not stop the slideshow
startstopped : false, // if autoplay is on, this can force it to start stopped
pauseonhover : true, // if true & the slideshow is active, the slideshow will pause on hover
resumeonvideoend : true, // if true & the slideshow is active & a youtube video is playing, it will pause the autoplay until the video is complete
stopatend : false, // if true & the slideshow is active, the slideshow will stop on the last page. this also stops the rewind effect when infiniteslides is false.
playrtl : false, // if true, the slideshow will move right-to-left
starttext : "start", // start button text
stoptext : "stop", // stop button text
delay : 3000, // how long between slideshow transitions in autoplay mode (in milliseconds)
resumedelay : 15000, // resume slideshow after user interaction, only if autoplaylocked is true (in milliseconds).
animationtime : 600, // how long the slideshow transition takes (in milliseconds)
easing : "swing", // anything other than "linear" or "swing" requires the easing plugin
// callbacks - removed from options to reduce size - they still work
// interactivity
clickarrows : "click", // event used to activate arrow functionality (e.g. "click" or "mouseenter")
clickcontrols : "click focusin", // events used to activate navigation control functionality
clickslideshow : "click", // event used to activate slideshow play/stop button
// misc options
addwmodetoobject : "opaque", // if your slider has an embedded object, the script will automatically add a wmode parameter with this setting
maxoverallwidth : 32766 // max width (in pixels) of combined sliders (side-to-side); set to 32766 to prevent problems with opera
};
$.fn.anythingslider = function(options, callback) {
return this.each(function(){
var page, anyslide = $(this).data('anythingslider');
// initialize the slider but prevent multiple initializations
if ((typeof(options)).match('object|undefined')){
if (!anyslide) {
(new $.anythingslider(this, options));
} else {
anyslide.updateslider();
}
// if options is a number, process as an external link to page #: $(element).anythingslider(#)
} else if (/\d/.test(options) && !isnan(options) && anyslide) {
page = (typeof(options) === "number") ? options : parseint($.trim(options),10); // accepts " 2 "
// ignore out of bound pages
if ( page >= 1 && page <= anyslide.pages ) {
anyslide.gotopage(page, false, callback); // page #, autoplay, one time callback
}
}
});
};
})(jquery);
/* anythingslider works with works with jquery 1.4+, but you can uncomment the code below to make it
work with jquery 1.3.2. you'll have to manually add the code below to the minified copy if needed */
/*
// copied from jquery 1.4.4 to make anythingslider backwards compatible to jquery 1.3.2
if (typeof jquery.fn.delay === 'undefined') {
jquery.fn.extend({
delay: function( time, type ) {
time = jquery.fx ? jquery.fx.speeds[time] || time : time; type = type || "fx";
return this.queue( type, function() { var elem = this; settimeout(function() { jquery.dequeue( elem, type ); }, time ); });
}
});
}
*/