/** * jQuery (a)Slideshow plugin * * Copyright (c) 2008 Trent Foley * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * @author Anton Shevchuk AntonShevchuk@gmail.com * @version 0.5.5 */ ;(function($) { defaults = { width:320, // width in px height:240, // height in px index:0, // start from frame number N time:3000, // time out beetwen slides title:true, // show title titleshow:false,// always show title panel:true, // show controls panel play:false, // play slideshow loop:true, effect:'fade', // aviable fade, scrollUp/Down/Left/Right, zoom, zoomFade, growX, growY effecttime:1000,// aviable fast,slow,normal and any valid fx speed value filter:true, // remove
, empty
,

and other stuff nextclick:false, // bind content click next slide playclick:false, // bind content click play/stop playhover:false, // bind content hover play/stop playhoverr:false, // bind content hover stop/play (reverse of playhover) playframe:true, // show frame "Play Now!" fullscreen:false, // in full window size imgresize:false, // resize image to slideshow window imgcenter:true, // set image to center // TODO imgajax:true, // load images from links linkajax:false, // load html from links help:'Plugin homepage: (a)Slideshow
'+ 'Author homepage: Anton Shevchuk', controls :{ // show/hide controls elements 'hide':true, // show controls bar on mouse hover 'first':true, // goto first frame 'prev':true, // goto previouse frame (if it first go to last) 'play':true, // play slideshow 'next':true, // goto next frame (if it last go to first) 'last':true, // goto last frame 'help':true, // show help message 'counter':true // show slide counter } }; /** * Create a new instance of slideshow. * * @classDescription This class creates a new slideshow and manipulate it * * @return {Object} Returns a new slideshow object. * @constructor */ $.fn.slideshow = function(settings) { var _slideshow = this; /* * Construct */ this.each(function(){ var ext = $(this); this.playFlag = false; this.playId = null; this.length = 0; this.inited = new Array(); /** * Build Html * @method */ this.build = function () { var _self = this; ext.wrapInner('

'); ext = ext.find('.slideshow'); // filter content if (this.options.filter) { ext.find('.slideshow-content > br').remove(); ext.find('.slideshow-content > p:empty').remove(); ext.find('.slideshow-content > div:empty').remove(); } // fullscreen if (this.options.fullscreen) { $('body').css({overflow:'hidden', padding:0}); this.options.width = $(window).width(); this.options.height = ($(window).height()>$(document).height())?$(window).height():$(document).height(); // this.options.width = this.options.width; // this.options.height = this.options.height; ext.addClass('slideshow-fullscreen'); } this.length = ext.find('.slideshow-content > *').length; // build title if (this.options.title) { ext.prepend('
'); if (!this.options.titleshow) { ext.find('.slideshow-label-place').hover(function(){ $(this).find('.slideshow-label').fadeIn(); }, function() { $(this).find('.slideshow-label').fadeOut(); }); ext.find('.slideshow-label').hide(); } ext.find('.slideshow-label-place').css('width', this.options.width); } // build panel if (this.options.panel) { ext.append('
'); panel = ext.find('.slideshow-panel'); if (this.options.controls.first) panel.append('First'); if (this.options.controls.prev) panel.append(''); if (this.options.controls.play) panel.append('Play'); if (this.options.controls.next) panel.append(''); if (this.options.controls.last) panel.append('Last'); if (this.options.controls.help) { panel.append('Help'); panel.prepend('
'+this.options.help+'
'); // panel.find('.slideshow-help').css('width', this.options.width - 4 + 'px'); } if (this.options.controls.counter) { panel.append(''+(this.options.index+1)+' / '+this.length+''); } if (this.options.controls.hide) { ext.find('.slideshow-panel-place').hover(function(){ $(this).find('.slideshow-panel').fadeIn(); }, function() { $(this).find('.slideshow-panel').fadeOut(); }); panel.hide(); } ext.find('.slideshow-panel-place').css('width', this.options.width); } /** * Set Size Options */ ext.css('width', this.options.width + 'px'); // ext.css('height', this.options.height + 'px'); ext.find('.slideshow-content').css('width', this.options.width); ext.find('.slideshow-content').css('height', this.options.height); /** * Change children styles */ ext.find('.slideshow-content > *').each(function(){ _self._build($(this)); }); // init slide (replace by ajax etc) this.init(this.options.index); // hide all slides ext.find('.slideshow-content > *:not(:eq('+this.options.index+'))').hide(); // show label this.label(); // add playframe if (this.options.playframe) { ext.find('.slideshow-content').append('
'); } // bind all events this.events(); return true; }; /** * Change CSS for every entity */ this._build = function(el){ el.css({margin :0, position: 'absolute', left: (this.options.width/2 - el.attr('width')/2), top : (this.options.height/2 - el.attr('height')/2), overflow:'hidden' }); if (el.is('img') && this.options.imgresize || el.is(':not(img)')){ el.css({width:'100%',height:'100%'}); } }; /** * Bind Events */ this.events = function() { var _self = this; /** * Go to next slide on content click (optional) */ if (_self.options.nextclick) ext.find('.slideshow-content').click(function(){ _self.stop(); _self.next(); return false; }); /** * Goto first slide button */ if (this.options.controls.first) ext.find('a.first').click(function(){ _self.stop(); _self.goSlide(0); return false; }); /** * Goto previouse slide button */ if (this.options.controls.prev) ext.find('a.prev').click(function(){ _self.stop(); _self.prev(); return false; }); /** * Play slideshow button */ if (this.options.controls.play) ext.find('a.play').click(function(){ if (_self.playFlag) { _self.stop(); } else { _self.play(); } return false; }); /** * Goto next slide button */ if (this.options.controls.next) ext.find('a.next').click(function(){ _self.stop(); _self.next(); return false; }); /** * Goto last slide button */ if (this.options.controls.last) ext.find('a.last').click(function(){ _self.stop(); _self.goSlide(_self.length-1); return false; }); /** * Show help message */ if (this.options.controls.help) ext.find('a.help').click(function(){ _self.stop(); ext.find('.slideshow-help').slideToggle(); return false; }); /** * Show playframe */ if (this.options.playframe) ext.find('.slideshow-frame').click(function(){ ext.find('.slideshow-frame').remove(); ext.find('.slideshow-shadow').remove(); if (_self.options.playclick) setTimeout(function(ms){ _self.play() }, _self.options.time); return false; }); /** * Play/stop on slideshow hover */ if (this.options.playhover) ext.hover(function(){ if (!_self.playFlag) { _self.play(); } }, function(){ if (_self.playFlag) { _self.stop(); } }); /** * Stop/Play on slideshow hover */ if (this.options.playhoverr) ext.hover(function(){ if (_self.playFlag) { _self.stop(); } }, function(){ if (!_self.playFlag) { _self.play(); } }); }; /** * Find and show label of slide * @method */ this.label = function () { if (!this.options.title) return false; label = ''; current = ext.find('.slideshow-content > *:eq('+this.options.index +')'); if (current.attr('alt')) { label = current.attr('alt'); } else if (current.attr('title')) { label = current.attr('title'); }else if (current.find('label:first').length>0) { current.find('label:first').hide(); label = current.find('label:first').html(); } ext.find('.slideshow-label').html(label); }; /** * Goto previous slide * @method */ this.prev = function () { if (this.options.index == 0) { i = (this.length-1); } else { i = this.options.index - 1; } this.goSlide(i); }; /** * Play Slideshow * @method */ this.play = function () { var _self = this; this.playFlag = true; this.playId = setTimeout(function(ms){ _self._play() }, this.options.time); ext.find('a.play').addClass('stop'); }; /** * Play Slideshow * @method */ this._play = function () { var _self = this; this.next(); if (this.playFlag) { if (this.options.index == (this.length-1) && !this.options.loop) { this.stop();return false; } this.playId = setTimeout(function(ms){ _self._play() }, this.options.time); } }; /** * Stop Slideshow * @method */ this.stop = function () { ext.find('a.play').removeClass('stop'); this.playFlag = false; clearTimeout(this.playId); }; /** * Goto next slide * @method */ this.next = function () { if (this.options.index == (this.length-1)) { i = 0; } else { i = this.options.index + 1; } this.goSlide(i); }; /** * Init N-slide * @method * @param {Integer} n */ this.init = function (index) { // initialize only ones for (var i = 0, loopCnt = this.inited.length; i < loopCnt; i++) { if (this.inited[i] === index) { return true; } } // index to inited stack this.inited.push(index); // current slide slide = ext.find('.slideshow-content > *:eq('+index+')'); var _self = this; /** * Replace A to content from HREF */ if (slide.get(0).tagName == 'A') { var href = slide.attr('href'); var title = slide.attr('title'); title = title.replace(/\"/i,'\''); // if you use single quotes for tag attribs var domain = document.domain; domain = domain.replace(/\./i,"\."); // for strong check domain name var reimage = new RegExp("\.(png|gif|jpg|jpeg|svg)$", "i"); var relocal = new RegExp("^((https?:\/\/"+domain+")|(?!http:\/\/))", "i"); if (this.options.imgajax && reimage.test(href)) { slide.replaceWith(''+title+''); } else if (this.options.linkajax && relocal.test(href)) { $.get(href, function(data){ slide.replaceWith('
'+data+'
'); }); } else { // nothing else // slide.wrap('

'); } slide = ext.find('.slideshow-content > *:eq('+index+')'); // reset css this._build(slide); } /** * Play/stop on content click (like image and other) */ if (this.options.playclick) $(slide).click(function(){ if (_self.playFlag) { _self.stop(); } else { _self.play(); } return false; }); }; /** * Goto N-slide * @method * @param {Integer} n */ this.goSlide = function (n) { if (this.options.index == n) return; this.init(n); var next = ext.find('.slideshow-content > *:eq('+n+')'); var prev = ext.find('.slideshow-content > *:eq('+this.options.index+')'); // restore next slide after all effects, set z-index = 0 for prev slide prev.css({zIndex:0}); if (this.options.imgresize) { next.css({zIndex:1, top: 0, left: 0, opacity: 1, width: this.options.width, height: this.options.height}); } else { next.css({zIndex:1, top: (this.options.height/2 - next.attr('height')/2), left: (this.options.width/2 - next.attr('width')/2), opacity: 1}); } this.options.index = n; if (this.options.effect == 'random' ) { var r = Math.random(); r = Math.floor(r*12); } else { r = -1; } // effect between slides switch (true) { case (this.options.effect == 'scrollUp' || r == 0): prev.css({width:'100%'}); next.css({top:0, height:0}); prevAni = {height: 0, top:this.options.height}; break; case (this.options.effect == 'scrollDown' || r == 1): prev.css({width:'100%'}); next.css({top:this.options.height,height:0}); prevAni = {height: 0, top:0}; break; case (this.options.effect == 'scrollRight' || r == 2): prev.css({right:0,left:'',height:'100%'}); next.css({right:'',left:0,height:'100%',width:'0%'}); prevAni = {width: 0}; break; case (this.options.effect == 'scrollLeft' || r == 3): prev.css({right:'',left:0,height:'100%'}); next.css({right:0,left:'',height:'100%',width:'0%'}); prevAni = {width: 0}; break; case (this.options.effect == 'growX' || r == 4): next.css({zIndex:2,opacity: 1,left: this.options.width/2, width: '0%', height:'100%'}); prevAni = {opacity: 0.8}; break; case (this.options.effect == 'growY' || r == 5): next.css({opacity: 1,top: this.options.height/2, width:'100%', height: '0%'}); prevAni = {opacity: 0.8}; break; case (this.options.effect == 'zoom' || r == 6): next.css({width: 0, height: 0, top: this.options.height/2, left: this.options.width/2}); prevAni = {width: 0, height: 0, top: this.options.height/2, left: this.options.width/2}; break; case (this.options.effect == 'zoomFade' || r == 7): next.css({zIndex:1, opacity: 0,width: 0, height: 0, top: this.options.height/2, left: this.options.width/2}); prevAni = {opacity: 0, width: 0, height: 0, top: this.options.height/2, left: this.options.width/2}; break; case (this.options.effect == 'zoomTL' || r == 8): next.css({zIndex:1, opacity: 0,width: this.options.width/2, height: this.options.height/2, top:0, left: 0}); prevAni = {opacity: 0, width: 0, height: 0, top: this.options.height, left: this.options.width}; break; case (this.options.effect == 'zoomBR' || r == 9): next.css({zIndex:1, opacity: 0,width: this.options.width/2, height: this.options.height/2, top: this.options.height/2, left: this.options.width/2}); prevAni = {opacity: 0, width: 0, height: 0, top: 0, left: 0}; break; case (this.options.effect == 'fade' || r == 10): default: prev.css({zIndex:0, opacity: 1}); next.css({zIndex:1, opacity: 0}); prevAni = {opacity: 0}; break; } var _self = this; prev.animate(prevAni,this.options.effecttime); // play next slide animation, hide prev slide, update label, update counter next.show().animate({opacity: 1}, this.options.effecttime, function () { prev.hide(); _self.label(); _self.counter(); }); }; /** * Update counter data * @method */ this.counter = function () { if (this.options.controls.counter) ext.find('.slideshow-panel span.counter').html((this.options.index+1) + ' / ' + this.length); }; // Now initialize the slideshow this.options = $.extend({}, defaults, settings); if (typeof(settings) != 'undefined') { if (typeof(settings.controls) != 'undefined') this.options.controls = $.extend({}, defaults.controls, settings.controls); } this.build(); /** * Show slideshow */ ext.show(); /** * Check play option */ if (this.options.play) { this.play(); } return ext; }); /** * external functions - append to $ */ _slideshow.playSlide = function(){ _slideshow.each(function () { this.play(); }) }; _slideshow.stopSlide = function(){ _slideshow.each(function () { this.stop(); }) }; _slideshow.nextSlide = function(){ _slideshow.each(function () { this.next(); }) }; _slideshow.prevSlide = function(){ _slideshow.each(function () { this.prev(); }) }; return this; } })(jQuery);