diff --git a/Demos/Loop.js b/Demos/Loop.js index 4730af2..3a63ac0 100755 --- a/Demos/Loop.js +++ b/Demos/Loop.js @@ -19,9 +19,6 @@ provides: [Loop] ... */ - - - var Loop = new Class({ loopCount: 0, @@ -30,9 +27,15 @@ var Loop = new Class({ loopMethod: $empty, setLoop: function(fn,delay){ - if(this.isLooping) this.stopLoop(); + 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; }, diff --git a/Demos/demo.js b/Demos/demo.js index bf9ff7d..a5e6afa 100644 --- a/Demos/demo.js +++ b/Demos/demo.js @@ -3,7 +3,48 @@ var mySlideShow; window.addEvent('domready',function(){ mySlideShow = new SlideShow('slides',{ - delay: 2000 - }).startLoop(); + delay: 2000, + autoplay: true + }); + + + var toggled = [$('show'), $('showNext'), $('showPrevious')]; + + $('pause').addEvent('click',function(){ + + mySlideShow.pause(); + + toggled.each(function(button){ button.set('disabled', false); }); + this.set('disabled', true); + $('play').set('disabled', false); + $('reverse').set('disabled', true); + }); + + $('play').addEvent('click',function(){ + mySlideShow.play(); + + toggled.each(function(button){ + button.set('disabled', true); + }); + this.set('disabled', true); + $('pause').set('disabled', false); + $('reverse').set('disabled', false); + }); + + $('reverse').addEvent('click',function(){ + mySlideShow.reverse(); + }); + + $('show').addEvent('click',function(){ + mySlideShow.show(mySlideShow.slides[4]); + }); + + $('showNext').addEvent('click',function(){ + mySlideShow.showNext(); + }); + + $('showPrevious').addEvent('click',function(){ + mySlideShow.showPrevious(); + }); }); \ No newline at end of file diff --git a/Demos/index.html b/Demos/index.html index 714dbf7..0269674 100644 --- a/Demos/index.html +++ b/Demos/index.html @@ -17,12 +17,21 @@

SlideShow Demo

1
-
2
-
3
-
4
+
2
+
3
+
4
5
6
+

Methods

+

+ + +   + + + +

+SlideShow gets the transition information from the class attribute of your slide. It will only grab the immediate children of the container (`slideshow` in this case). You can put whatever element type you want as the slides, and put anything inside of the slides. + + #HTML +
1
-
2
+
2
3
4
5
@@ -21,17 +24,122 @@ Class: SlideShow {#SlideShow}
#### javascript - mySlideShow = new SlideShow('slides',{ - delay: 2000 - }).startLoop(); + +###### constructor + +Just pass in the slideshow container element to the constructor (and a few options, if you'd like) and you're set. + + #JS + mySlideShow2 = new SlideShow('slideshow'); + + // or + + mySlideShow = new SlideShow('slideshow',{ + delay: 2000, + transition: 'fade', + duration: 500, + autoplay: true + }); + +##### Controlling the slideshow + +By default, `autoplay` is false and you can control the slide show. + + // show the 4th slide + mySlideShow.show(mySlideShow.slides[3]); + + // or just grab the element if you know it's already in the slideshow + var el = $('someSlide'); + mySlideShow.show(el); + +SlideShow implements [Loop](http://mootools.net/forge/p/loop) (also on the forge) so it inherits `startLoop` and `stopLoop`. SlideShow creates aliases for these as `play` and `pause`. + + mySlideShow.play(); + + // later + mySlideShow.pause(); + +If you wanted a navigation piece you could do something like: + + var slideLabels = $$('some-elements-in-the-same-order-as-the-slides'); + + slideLabels.each(function(el, index){ + el.store('slide', mySlideShow.slides[index]); + + el.addEvent('click',function() + mySlideShow.show(el.retrieve('slide')); + }); + + }); + +#### css + +SlideShow will set the position of your container to `relative` if it is not already positioned `absolute`. It will also set all of your slides to `position: absolute`, `display: block`, and `z-index: 0`. Because they are positioned absolutely you'll need to give them a width. Also, you'll usually want to set the container overflow to hidden in your CSS. + + #CSS + div#slideshow { + width: 500px; + height: 280px; + overflow: hidden; + } + + div#slideshow div { + width: 500px + height: 280px; + } + ### Implements: Options, Events, [Loop][http://moodocs.net/rpflo/mootools-rpflo/Loop] -### Note: +### Adding your own transitions + +Adding transitions is a snap. The Class itself has an `add` function that takes two arguments: the name of the transition, and the function to control it. + +The function signature: + + function(previous, next, duration, instance) + +* `previous` is the previous slide element reference +* `next` is the next slide element reference +* `duration` is how long the transition should last. +* `instance` is the instance of SlideShow, handy to find the size of the container (`instance.element`) or any other information. + +When writing your own transitions there are a few things to note: + +1. The previous slide's `z-index` is `1` so it's on top. +2. The next slide's `z-index` is `0` so it's behind. +3. Both slides have `top: 0` and `left:0`, so you'll need to reposition `next` for any fancy movement. +4. All other slides have `display:none` +5. When the `duration` is met, the previous slide will be reset to `display: none`, `top:0`, `left:0`. + +So here are a few examples: + + SlideShow.add('fade', function(previous, next, duration, instance){ + previous.set('tween',{duration: duration}).fade('out'); + return this; + }); + +Pretty simple. Since the next slide is directly behind the previous, we can just fade out the previous slide and there's our new one. + + SlideShow.add('blindLeft', function(previous, next, duration, instance){ + var distance = instance.element.getStyle('width').toInt(); + next.setStyles({ + 'left': distance, + 'z-index': 2 + }).set('tween',{duration: duration}).tween('left', 0); + return this; + }); + +A bit more complicated. First we have to measure the distance our slide needs to travel, then we set it's `left` style to be totally out of the slideshow view and change it's `z-index` from `0` to `2` so it's above the previous slides `z-index: 1`. Once it's all setup we just tween left back to 0. Our slide smoothly slides over the the previous slide. + + SlideShow.add('blindLeftFade',function(p, n, d, i){ + this.blindLeft(p,n,d,i).fade(p,n,d,i); + }); + +`this` references the object containing all of the transitions _so you can chain effects_. -Your slideshow container needs to have either `position: absolute` or `relative`. SlideShow Method: constructor {#SlideShow:constructor} ------------------------------------------------------- diff --git a/README.md b/README.md index ab98772..f846aec 100644 --- a/README.md +++ b/README.md @@ -3,67 +3,161 @@ SlideShow ![SlideShow](http://github.com/rpflorence/SlideShow/raw/master/logo.png) -The ultimate, class-based, slideshow class. Use any element, not just images. so it's prefect for galleries, newstickers, whatever. Comes with packaged transitions but is ridiculously easy to extend and create your own transitions. +Easily extendable, class-based, slideshow widget. Use any element, not just images. Comes with packaged transitions but is easy to extend and create your own transitions. The class is built to handle the _basics_ of a slideshow, extend it to implement your own navigation piece and custom transitions. + +Features: +--------- + +* Autoplay +* Reverse +* Show next slide +* Show previous slide +* Show arbitrary slide +* Transitions by slide +* Durations by slide +* Default transitions +* Default durations + +Packaged Transitions +-------------------- + +* fade +* crossFade +* fadeThroughBackground +* pushLeft, pushRight, pushUp, pushDown +* blindLeft, blindRight, blindUp, blindDown +* blindLeftFade, blindRightFade, blindUpFade, blindDownFade + How to use ---------- #### html -
+SlideShow gets the transition information from the class attribute of your slide. It will only grab the immediate children of the container (`slideshow` in this case). You can put whatever element type you want as the slides, and put anything inside of the slides. + + #HTML +
1
-
2
+
2
3
4
5
6
+#### javascript + +###### constructor + +Just pass in the slideshow container element to the constructor (and a few options, if you'd like) and you're set. + + #JS + mySlideShow2 = new SlideShow('slideshow'); + + // or + + mySlideShow = new SlideShow('slideshow',{ + delay: 2000, + transition: 'fade', + duration: 500, + autoplay: true + }); + +##### Controlling the slideshow + +By default, `autoplay` is false and you can control the slide show. + + // show the 4th slide + mySlideShow.show(mySlideShow.slides[3]); + + // or just grab the element if you know it's already in the slideshow + var el = $('someSlide'); + mySlideShow.show(el); + +SlideShow implements [Loop](http://mootools.net/forge/p/loop) (also on the forge) so it inherits `startLoop` and `stopLoop`. SlideShow creates aliases for these as `play` and `pause`. + + mySlideShow.play(); + + // later + mySlideShow.pause(); + +If you wanted a navigation piece you could do something like: + + var slideLabels = $$('some-elements-in-the-same-order-as-the-slides'); + + slideLabels.each(function(el, index){ + el.store('slide', mySlideShow.slides[index]); + + el.addEvent('click',function() + mySlideShow.show(el.retrieve('slide')); + }); + + }); + #### css - div#slides { - position: relative; +SlideShow will set the position of your container to `relative` if it is not already positioned `absolute`. It will also set all of your slides to `position: absolute`, `display: block`, and `z-index: 0`. Because they are positioned absolutely you'll need to give them a width. Also, you'll usually want to set the container overflow to hidden in your CSS. + + #CSS + div#slideshow { width: 500px; height: 280px; overflow: hidden; } - div#slides div { - position: absolute; - width: 500px; + div#slideshow div { + width: 500px height: 280px; - } - -#### javascript - mySlideShow = new SlideShow('slides',{ - delay: 2000 - }).startLoop(); - - + } Extending SlideShow with your own transitions --------------------------------------------- +Adding transitions is a snap. The Class itself has an `add` function that takes two arguments: the name of the transition, and the function to control it. + +The function signature: + + function(previous, next, duration, instance) + +* `previous` is the previous slide element reference +* `next` is the next slide element reference +* `duration` is how long the transition should last. +* `instance` is the instance of SlideShow, handy to find the size of the container (`instance.element`) or any other information. + +When writing your own transitions there are a few things to note: + +1. The previous slide's `z-index` is `1` so it's on top. +2. The next slide's `z-index` is `0` so it's behind. +3. Both slides have `top: 0` and `left:0`, so you'll need to reposition `next` for any fancy movement. +4. All other slides have `display:none` +5. When the `duration` is met, the previous slide will be reset to `display: none`, `top:0`, `left:0`. + +So here are a few examples: + SlideShow.add('fade', function(previous, next, duration, instance){ previous.set('tween',{duration: duration}).fade('out'); return this; }); - + +Pretty simple. Since the next slide is directly behind the previous, we can just fade out the previous slide and there's our new one. + SlideShow.add('blindLeft', function(previous, next, duration, instance){ var distance = instance.element.getStyle('width').toInt(); next.setStyles({ 'left': distance, - 'z-index': 1 + 'z-index': 2 }).set('tween',{duration: duration}).tween('left', 0); return this; }); + +A bit more complicated. First we have to measure the distance our slide needs to travel, then we set it's `left` style to be totally out of the slideshow view and change it's `z-index` from `0` to `2` so it's above the previous slides `z-index: 1`. Once it's all setup we just tween left back to 0. Our slide smoothly slides over the the previous slide. - SlideShow.add('blindLeftFade',function(previous, next, duration, instance){ - this.blindLeft(previous, next, duration, instance).fade(previous, next, duration, instance); + SlideShow.add('blindLeftFade',function(p, n, d, i){ + this.blindLeft(p,n,d,i).fade(p,n,d,i); }); -That's it! The class will handle resetting just about anything you might to to the previous tween's styles. +`this` references the object containing all of the transitions _so you can chain effects_. -Yes, that last one combines the previous two effects into one. View the [MooDoc](http://moodocs.net/rpflo/mootools-rpflo/SlideShow) for more usage and examples. diff --git a/Source/SlideShow.js b/Source/SlideShow.js index 6d0c450..668cb77 100644 --- a/Source/SlideShow.js +++ b/Source/SlideShow.js @@ -11,6 +11,9 @@ authors: Ryan Florence docs: http://moodocs.net/rpflo/mootools-rpflo/SlideShow +requires: + - Loop + provides: [SlideShow] ... @@ -22,7 +25,10 @@ var SlideShow = new Class({ Implements: [Options, Events, Loop], options: { - delay: 7000 + delay: 7000, + transition: 'crossFade', + duration: '500', + autoplay: false }, initialize: function(element, options){ @@ -32,21 +38,36 @@ var SlideShow = new Class({ this.slides = this.element.getChildren(); this.current = this.slides[0]; this.setup(); + this.pause = this.stopLoop; + this.play = this.startLoop; + if(this.options.autoplay) this.startLoop(); }, setup: function(){ + this.setupElement(); + this.setupSlides(); + }, + + setupElement: function(){ + var el = this.element; + if(el.getStyle('position') != 'absolute' && el != document.body) el.setStyle('position','relative'); + return this; + }, + + setupSlides: function(){ this.slides.each(function(slide, index){ this.storeTransition(slide).reset(slide); if(index != 0) slide.setStyle('display','none'); }, this); + return this; }, storeTransition: function(slide){ var classes = slide.get('class'); var transitionRegex = /transition:[a-zA-Z]+/; var durationRegex = /duration:[0-9]+/; - var transition = classes.match(transitionRegex)[0].split(':')[1]; - var duration = classes.match(durationRegex)[0].split(':')[1]; + 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.store('ssTransition', transition); slide.store('ssDuration', duration); return this; @@ -61,15 +82,15 @@ var SlideShow = new Class({ }, show: function(slide){ - var transition = this.getTransition(slide); - var duration = this.getDuration(slide); - - var previous = this.current.setStyle('z-index', 1); - var next = this.reset(slide); - - this.transitions[transition](previous, next, duration, this); - (function() { previous.setStyle('display','none'); }).bind(this).delay(duration); - this.current = next; + if(slide != this.current){ + var transition = this.getTransition(slide); + var duration = this.getDuration(slide); + var previous = this.current.setStyle('z-index', 1); + var next = this.reset(slide); + this.transitions[transition](previous, next, duration, this); + (function() { previous.setStyle('display','none'); }).bind(this).delay(duration); + this.current = next; + } return this; }, @@ -102,6 +123,12 @@ var SlideShow = new Class({ showPrevious: function(){ this.show(this.previousSlide()); return this; + }, + + reverse: function(){ + var fn = (this.loopMethod == this.showNext) ? this.showPrevious : this.showNext; + this.setLoop(fn, this.options.delay); + return this; } }); @@ -140,6 +167,19 @@ SlideShow.addAllThese([ next.set('tween',{duration: duration}).fade('in'); return this; }], + + ['fadeThroughBackground', function(previous, next, duration, instance){ + var half = duration/2; + next.set('tween',{ + duration: half + }).fade('hide'); + previous.set('tween',{ + duration: half, + onComplete: function(){ + next.fade('in'); + } + }).fade('out'); + }], ['pushLeft', function(previous, next, duration, instance){ var distance = instance.element.getStyle('width').toInt(); diff --git a/package.yml b/package.yml index e09f99d..d12b3a5 100644 --- a/package.yml +++ b/package.yml @@ -3,5 +3,5 @@ author: rpflo category: Widgets tags: [slideshow, gallery] docs: http://moodocs.net/rpflo/mootools-rpflo/SlideShow -demo: http://mooshell.net/QqFPw/embedded/result,js,html,css/ -current: 0.5 \ No newline at end of file +demo: http://mootools.net/shell/VUe5J/embedded/result,js,html,css/ +current: 0.6 \ No newline at end of file