var Loop = new Class({
loopCount: 0,
isStopped: true,
isLooping: false,
loopMethod: $empty,
setLoop: function(fn, delay){
if(this.isLooping) {
this.stopLoop();
var wasLooping = true;
} else {
var wasLooping = false;
}
this.loopMethod = fn;
this.loopDelay = delay || 3000;
if(wasLooping) this.startLoop();
return this;
},
stopLoop: function() {
this.isStopped = true;
this.isLooping = false;
$clear(this.periodical);
return this;
},
startLoop: function(delay) {
if(this.isStopped){
var delay = (delay) ? delay : this.loopDelay;
this.isStopped = false;
this.isLooping = true;
this.periodical = this.looper.periodical(delay,this);
};
return this;
},
resetLoop: function(){
this.loopCount = 0;
return this;
},
looper: function(){
this.loopCount++;
this.loopMethod(this.loopCount);
return this;
}
});
var Slideshow = new Class({
Implements: [Options, Events, Loop],
options: {
/*
onShow: $empty,
onShowComplete: $empty,
onReverse: $empty,
onPlay: $empty,
onPause: $empty
*/
delay: 7000,
transition: 'crossFade',
duration: '500',
autoplay: false
},
jQuery: 'slideshow',
initialize: function(element, options){
this.setOptions(options);
this.setLoop(this.showNext, this.options.delay);
this.element = jQuery(element);
this.slides = this.element.children();
this.current = this.slides[0];
this.setup();
if(this.options.autoplay) this.startLoop();
},
setup: function(){
this.setupElement();
this.setupSlides();
return this;
},
setupElement: function(){
var el = this.element;
if(el.css('position') != 'absolute' && el != document.body) el.css('position','relative');
return this;
},
setupSlides: function(){
this.slides.each(function(index, slide){
var slide = jQuery(slide);
this.storeTransition(slide).reset(slide);
if(index != 0) jQuery(slide).css('display','none');
}.bind(this));
return this;
},
storeTransition: function(slide){
var classes = slide.attr('class');
var transitionRegex = /transition:[a-zA-Z]+/;
var durationRegex = /duration:[0-9]+/;
var transition = (classes.match(transitionRegex)) ? classes.match(transitionRegex)[0].split(':')[1] : this.options.transition;
var duration = (classes.match(durationRegex)) ? classes.match(durationRegex)[0].split(':')[1] : this.options.duration;
slide.data('ssTransition', transition);
slide.data('ssDuration', duration);
return this;
},
getTransition: function(slide){
return slide.data('ssTransition');
},
getDuration: function(slide){
return slide.data('ssDuration');
},
show: function(slide){
this.fireEvent('show');
slide = (typeof slide == 'number') ? jQuery(this.slides[slide]) : jQuery(slide);
if(slide[0] != jQuery(this.current)[0]){
var transition = this.getTransition(slide);
var duration = this.getDuration(slide);
var previous = jQuery(this.current).css('z-index', 1);
var next = this.reset(slide);
this.transitions[transition](previous, next, duration.toInt(), this);
(function() {
previous.css('display','none'); // jquery
this.fireEvent('showComplete'); // Class.Extras
}).bind(this).delay(duration); // Function.delay, Function.bind
this.current = next;
}
return this;
},
reset: function(slide){
return jQuery(slide).css({ // jquery .css
'position': 'absolute',
'z-index': 0,
'display': 'block',
'left': 0,
'top': 0
}).show(); // jquery .show
},
nextSlide: function(){
var next = jQuery(this.current).next(); // jquery .next
return (next[0]) ? next : this.slides[0];
},
previousSlide: function(){
var previous = jQuery(this.current).prev(); // jquery .prev
return (previous[0]) ? previous : this.slides.last(); // jquery .last
},
showNext: function(){
this.show(this.nextSlide());
return this;
},
showPrevious: function(){
this.show(this.previousSlide());
return this;
},
play: function(){
this.startLoop();
this.fireEvent('play');
return this;
},
pause: function(){
this.stopLoop();
this.fireEvent('pause');
return this;
},
reverse: function(){
var fn = (this.loopMethod == this.showNext) ? this.showPrevious : this.showNext;
this.setLoop(fn, this.options.delay);
this.fireEvent('reverse');
return this;
}
});
Slideshow.adders = {
transitions:{},
add: function(className, fn){
this.transitions[className] = fn;
this.implement({
transitions: this.transitions
});
},
addAllThese : function(transitions){
$A(transitions).each(function(transition){
this.add(transition[0], transition[1]);
}, this);
}
}
$extend(Slideshow, Slideshow.adders);
Slideshow.implement(Slideshow.adders);
Slideshow.add('fade', function(previous, next, duration, instance){
previous.fadeOut(duration);
return this;
});
Slideshow.addAllThese([
['none', function(previous, next, duration, instance){
previous.css('display','none');
return this;
}],
['crossFade', function(previous, next, duration, instance){
previous.fadeOut(duration);
next.fadeIn(duration);
return this;
}],
['fadeThroughBackground', function(previous, next, duration, instance){
var half = duration/2;
next.hide();
previous.fadeOut(half,function(){
next.fadeIn(half);
});
}],
['pushLeft', function(previous, next, duration, instance){
var distance = instance.element.css('width').toInt();
next.css('left', distance);
[next, previous].each(function(slide){
var to = slide.css('left').toInt() - distance;
slide.animate({'left': to}, duration);
});
return this;
}],
['pushRight', function(previous, next, duration, instance){
var distance = instance.element.css('width').toInt();
next.css('left', -distance);
[next, previous].each(function(slide){
var to = slide.css('left').toInt() + distance;
slide.animate({'left': to}, duration);
});
return this;
}],
['pushDown', function(previous, next, duration, instance){
var distance = instance.element.css('height').toInt();
next.css('top', -distance);
[next, previous].each(function(slide){
var to = slide.css('top').toInt() + distance;
slide.animate({'top': to}, duration);
});
return this;
}],
['pushUp', function(previous, next, duration, instance){
var distance = instance.element.css('height').toInt();
next.css('top', distance);
[next, previous].each(function(slide){
var to = slide.css('top').toInt() - distance;
slide.animate({'top': to}, duration);
});
return this;
}],
['blindLeft', function(previous, next, duration, instance){
var distance = instance.element.css('width').toInt();
next
.css({
'left': distance,
'z-index': 1
})
.animate({'left': 0}, duration);
return this;
}],
['blindRight', function(previous, next, duration, instance){
var distance = instance.element.css('width').toInt();
next
.css({
'left': -distance,
'z-index': 1
})
.animate({'left': 0}, duration);
return this;
}],
['blindUp', function(previous, next, duration, instance){
var distance = instance.element.css('height').toInt();
next
.css({
'top': distance,
'z-index': 1
})
.animate({'top': 0}, duration);
return this;
}],
['blindDown', function(previous, next, duration, instance){
var distance = instance.element.css('height').toInt();
next
.css({
'top': -distance,
'z-index': 1
})
.animate({'top': 0}, duration);
return this;
}],
['blindDownFade', function(p,n,d,i){
this.blindDown(p,n,d,i).fade(p,n,d,i);
}],
['blindUpFade', function(p,n,d,i){
this.blindUp(p,n,d,i).fade(p,n,d,i);
}],
['blindLeftFade', function(p,n,d,i){
this.blindLeft(p,n,d,i).fade(p,n,d,i);
}],
['blindRightFade', function(p,n,d,i){
this.blindRight(p,n,d,i).fade(p,n,d,i);
}]
]);
var mySlideshow;
$(document).ready(function(){
// typical jquery instantiation + class event goodness
$('#ticker').slideshow({
delay: 2000,
autoplay: true,
transition: 'pushUp',
onShow: function(){ // can even add events here
this.element.effect('highlight');
}
});
// object oriented instance with a few options
mySlideshow = new Slideshow('#slides',{
delay: 3000,
autoplay: true
});
// Event demonstration
mySlideshow.addEvents({
onShow: function(){ $('#onShow').effect('highlight'); },
onShowComplete: function(){ $('#onShowComplete').effect('highlight'); },
onReverse: function(){ $('#onReverse').effect('highlight'); },
onPlay: function(){ $('#onPlay').effect('highlight'); },
onPause: function(){ $('#onPause').effect('highlight'); }
});
// the rest of the demo showing how to control the instance
var toggled = [$('#show'), $('#showNext'), $('#showPrevious'), $('#showIndex')];
$('#pause').click(function(){
// object oriented, call the method directly
mySlideshow.pause();
// conventional jquery with some plugin sugar
$('#ticker').slideshow('pause');
// demo stuff
toggled.each(function(button){
$(button).attr('disabled', false);
});
$(this).attr('disabled', true);
$('#play').attr('disabled', false);
$('#reverse').attr('disabled', true);
});
$('#play').click(function(){
// object oriented
mySlideshow.play();
// conventional jquery
$('#ticker').slideshow('play');
// demo stuff
toggled.each(function(button){
$(button).attr('disabled', true);
});
$(this).attr('disabled', true);
$('#pause').attr('disabled', false);
$('#reverse').attr('disabled', false);
});
$('#reverse').click(function(){
mySlideshow.reverse();
$('#ticker').slideshow('reverse');
});
$('#show').click(function(){
mySlideshow.show(4, 'one', 'two', 'three');
$('#ticker').slideshow('show');
});
$('#showIndex').click(function(){
mySlideshow.show(0);
$('#ticker').slideshow('show', 0);
});
$('#showNext').click(function(){
mySlideshow.showNext();
$('#ticker').slideshow('showNext');
});
$('#showPrevious').click(function(){
mySlideshow.showPrevious();
$('#ticker').slideshow('showPrevious');
});
});
<h1>Slideshow Demo</h1>
<div id="slides">
<div class="red transition:crossFade duration:1000">1</div>
<div class="green transition:blindUp">2</div>
<div class="blue transition:pushLeft duration:1000">3</div>
<div class="red transition:fadeThroughBackground duration:1000">4</div>
<div class="green transition:blindLeftFade duration:2000">5</div>
<div class="blue transition:blindRightFade duration:500">6</div>
</div>
<h2>Events</h2>
<p>
<span id="onShow">show</span>
<span id="onShowComplete">showComplete</span>
<span id="onPlay">play</span>
<span id="onPause">pause</span>
<span id="onReverse">reverse</span>
</p>
<h2>Methods</h2>
<p>
<button id="pause">pause</button>
<button id="play" disabled="disabled">play</button>
<button id="reverse">reverse</button>
<button id="showNext" disabled="disabled">showNext</button>
<button id="showPrevious" disabled="disabled">showPrevious</button>
<button id="show" disabled="disabled">show slide 5</button>
<button id="showIndex" disabled="disabled">show slide 1</button>
</p>
<h2>Conventional jQuery Instantiated Instance</h2>
<ol id="ticker">
<li>Lorem ipsum dolor sit amet, consectetur</li>
<li>adipisicing elit, sed do eiusmod tempor</li>
<li>incididunt ut labore et dolore magna aliqua.</li>
<li>Ut enim ad minim veniam, quis nostrud</li>
<li>exercitation ullamco laboris nisi ut aliquip</li>
<li>ex ea commodo consequat. Duis aute irure</li>
</ol>
div#slides {
width: 500px;
height: 280px;
overflow: hidden;
border: solid 2px #000;
}
div#slides div {
height: 280px;
width: 500px;
font-size: 100px;
line-height: 200px;
text-align: center;
color: #fff;
}
ol#ticker {
height: 1.4em;
overflow: hidden;
border: solid 1px #aaa;
background: #ccc;
}
ul#ticker li {
padding: 0.2em 0;
}
/* @end */
/* @group global */
body {
font-family: Helvetica, arial;
background: #fff;
}
h1 {
color: #0094d5;
}
h2 {
color: #43aa38;
}
a {
color: #0094d5;
}
a:visited, a:hover {
color: #00577e;
}
.red {
background: #e40053;
}
.blue {
background: #0094d5;
}
.green {
background: #43aa38;
}
h2 {
margin-top: 20px;
}