summaryrefslogtreecommitdiff
path: root/doc/s6/jquery.slideshow.js
diff options
context:
space:
mode:
Diffstat (limited to 'doc/s6/jquery.slideshow.js')
-rw-r--r--doc/s6/jquery.slideshow.js534
1 files changed, 534 insertions, 0 deletions
diff --git a/doc/s6/jquery.slideshow.js b/doc/s6/jquery.slideshow.js
new file mode 100644
index 0000000..6d6c560
--- /dev/null
+++ b/doc/s6/jquery.slideshow.js
@@ -0,0 +1,534 @@
+
+var Slideshow = {};
+
+
+/************************************
+ * lets you define your own "global" transition function
+ * passes in a reference to from and to slide wrapped in jQuery wrapper
+ */
+
+Slideshow.transition = function( $from, $to ) {
+ // $from.hide();
+ // $to.show();
+
+ $from.hide('fast');
+ $to.show('fast');
+}
+
+/***********************
+ * sample custom transition using scrollUp effect
+ * inspired by Karl Swedberg's Scroll Up Headline Reader jQuery Tutorial[1]
+ * [1] http://docs.jquery.com/Tutorials:Scroll_Up_Headline_Reader
+ */
+
+function transitionSlideUpSlideDown( $from, $to ) {
+ $from.slideUp( 500, function() { $to.slideDown( 1000 ); } );
+}
+
+function transitionFadeOutFadeIn( $from, $to ) {
+ $from.fadeOut( 500 );
+ $to.fadeIn( 500 );
+}
+
+function transitionScrollUp( $from, $to ) {
+ var cheight = $from.outerHeight();
+
+ // hide scrollbar during animation
+ $( 'body' ).css( 'overflow-y', 'hidden' );
+
+ $to.css( 'top', cheight+'px' );
+ $to.show();
+
+ $from.animate( {top: -cheight}, 'slow' );
+ $to.animate( {top: 0}, 'slow', function() {
+ $from.hide().css( 'top', '0px');
+
+ // restore possible scrollbar
+ $( 'body' ).css( 'overflow-y', 'auto' );
+ });
+}
+
+Slideshow.init = function( options ) {
+
+ var settings = $.extend({
+ mode : 'slideshow', // slideshow | outline | autoplay
+ projectionStyleId : '#styleProjection',
+ screenStyleId : '#styleScreen',
+ titleSelector : 'h1',
+ slideSelector : '.slide', // dummy (not yet working)
+ stepSelector : '.step', // dummy (not yet working)
+ debug : false,
+ change : null // todo: change to use a custom event and trigger
+ }, options || {});
+
+ settings.isProjection = true; // are we in projection (slideshow) mode (in contrast to screen (outline) mode)?
+ settings.snum = 1; // current slide # (non-zero based index e.g. starting with 1)
+ settings.smax = 1; // max number of slides
+ settings.incpos = 0; // current step in slide
+ settings.steps = null;
+ settings.autoplayInterval = null;
+
+ function debug( msg )
+ {
+ if( settings.debug && window.console && window.console.log )
+ window.console.log( '[debug] ' + msg );
+ }
+
+ function showHide( action )
+ {
+ var $navLinks = $( '#navLinks' )
+
+ switch( action ) {
+ case 's': $navLinks.css( 'visibility', 'visible' ); break;
+ case 'h': $navLinks.css( 'visibility', 'hidden' ); break;
+ case 'c': /* toggle control panel */
+ if( $navLinks.css( 'visibility' ) != 'visible' )
+ $navLinks.css( 'visibility', 'visible' );
+ else
+ $navLinks.css( 'visibility', 'hidden' );
+ break;
+ }
+ }
+
+ function updateCurrentSlideCounter()
+ {
+ $( '#currentSlide' ).html( settings.snum + '/' + settings.smax );
+ }
+
+ function updateJumpList()
+ {
+ $('#jumplist').get(0).selectedIndex = (settings.snum-1);
+ }
+
+ function updatePermaLink()
+ {
+ // todo: unify hash marks??; use #1 for div ids instead of #slide1?
+ window.location.hash = '#'+settings.snum;
+ }
+
+ function goTo( target )
+ {
+ if( target > settings.smax || target == settings.snum ) return;
+ go( target - settings.snum );
+ }
+
+ function go( dir )
+ {
+ debug( 'go: ' + dir );
+
+ if( dir == 0 ) return; /* same slide; nothing to do */
+
+ var cid = '#slide' + settings.snum; /* current slide (selector) id */
+ var csteps = settings.steps[settings.snum-1]; /* current slide steps array */
+
+ /* remove all step and stepcurrent classes from current slide */
+ if( csteps.length > 0) {
+ $( csteps ).each( function() {
+ $(this).removeClass( 'step' ).removeClass( 'stepcurrent' );
+ } );
+ }
+
+ /* set snum to next slide */
+ settings.snum += dir;
+ if( settings.snum > settings.smax ) settings.snum = settings.smax;
+ if( settings.snum < 1 ) settings.snum = 1;
+
+ var nid = '#slide' + settings.snum; /* next slide (selector) id */
+ var nsteps = settings.steps[settings.snum-1]; /* next slide steps array */
+
+ if( dir < 0 ) /* go backwards? */
+ {
+ settings.incpos = nsteps.length;
+ /* mark last step as current step */
+ if( nsteps.length > 0 )
+ $( nsteps[settings.incpos-1] ).addClass( 'stepcurrent' );
+ }
+ else /* go forwards? */
+ {
+ settings.incpos = 0;
+ if( nsteps.length > 0 ) {
+ $( nsteps ).each( function() {
+ $(this).addClass( 'step' ).removeClass( 'stepcurrent' );
+ } );
+ }
+ }
+
+ if( !(cid == nid) ) {
+ debug( "transition from " + cid + " to " + nid );
+ Slideshow.transition( $( cid ), $( nid ) );
+ }
+
+ updateJumpList();
+ updateCurrentSlideCounter();
+ updatePermaLink();
+
+ if (settings.change) { settings.change(); }
+}
+
+ function subgo( dir )
+ {
+ debug( 'subgo: ' + dir + ', incpos before: ' + settings.incpos + ', after: ' + (settings.incpos+dir) );
+
+ var csteps = settings.steps[settings.snum-1]; /* current slide steps array */
+
+ if( dir > 0)
+ { /* go forward? */
+ if( settings.incpos > 0 )
+ $( csteps[settings.incpos-1] ).removeClass( 'stepcurrent' );
+ $( csteps[settings.incpos] ).removeClass( 'step').addClass( 'stepcurrent' );
+ settings.incpos++;
+ }
+ else
+ { /* go backwards? */
+ settings.incpos--;
+ $( csteps[settings.incpos] ).removeClass( 'stepcurrent' ).addClass( 'step' );
+ if( settings.incpos > 0 )
+ $( csteps[settings.incpos-1] ).addClass( 'stepcurrent' );
+ }
+}
+
+
+function notOperaFix()
+{
+ $( settings.projectionStyleId ).attr( 'media','screen' );
+
+ var styleScreen = $( settings.screenStyleId ).get(0);
+ styleScreen.disabled = true;
+}
+
+
+function toggle()
+{
+ // toggle between projection (slide show) mode
+ // and screen (outline) mode
+
+ // get stylesheets
+ var styleProjection = $( settings.projectionStyleId ).get(0);
+ var styleScreen = $( settings.screenStyleId ).get(0);
+
+ if( !styleProjection.disabled )
+ {
+ styleProjection.disabled = true;
+ styleScreen.disabled = false;
+ settings.isProjection = false;
+ $('.slide').each( function() { $(this).show(); } );
+ }
+ else
+ {
+ styleProjection.disabled = false;
+ styleScreen.disabled = true;
+ settings.isProjection = true;
+ $('.slide').each( function(i) {
+ if( i == (settings.snum-1) )
+ $(this).show();
+ else
+ $(this).hide();
+ });
+ }
+}
+
+ function populateJumpList() {
+
+ var list = $('#jumplist').get(0);
+
+ $( '.slide' ).each( function(i) {
+ var text = $(this).find( settings.titleSelector ).text();
+ list.options[list.length] = new Option( (i+1)+' : '+ text, (i+1) );
+ });
+ }
+
+ function createControls()
+ {
+ // todo: make layout into an id (not class?)
+ // do we need or allow more than one element?
+
+
+ // if no div.layout exists, create one
+ if( $( '.layout' ).length == 0 )
+ $( "<div class='layout'></div>").appendTo( 'body' );
+
+ $( '.layout' )
+ .append( "<div id='controls'>" )
+ .append( "<div id='currentSlide'>" );
+
+ var $controls = $( '#controls' )
+
+ $controls.html( '<div id="navLinks">'
+ + '<a accesskey="t" id="toggle" href="#">&#216;<\/a>'
+ + '<a accesskey="z" id="prev" href="#">&laquo;<\/a>'
+ + '<a accesskey="x" id="next" href="#">&raquo;<\/a>'
+ + '<div id="navList"><select id="jumplist" /><\/div>'
+ + '<\/div>' );
+
+ $controls.hover( function() { showHide('s') }, function() { showHide('h') });
+ $('#toggle').click( function() { toggle(); } );
+ $('#prev').click( function() { go(-1); } );
+ $('#next').click( function() { go(1); } );
+
+ $('#jumplist').change( function() { goTo( parseInt( $( '#jumplist' ).val() )); } );
+
+ populateJumpList();
+ updateCurrentSlideCounter();
+ updatePermaLink();
+ }
+
+ function toggleSlideNumber()
+ {
+ // toggle slide number/counter
+ $( '#currentSlide' ).toggle();
+ }
+
+ function toggleFooter()
+ {
+ $( '#footer').toggle();
+ }
+
+
+ function keys(key)
+ {
+ if (!key) {
+ key = event;
+ key.which = key.keyCode;
+ }
+ if (key.which == 84) {
+ toggle(); // toggle between project and screen css media mode
+ return;
+ }
+ if( settings.isProjection ) {
+ switch (key.which) {
+ case 32: // spacebar
+ case 34: // page down
+ case 39: // rightkey
+ case 40: // downkey
+
+ var csteps = settings.steps[settings.snum-1]; /* current slide steps array */
+
+ if ( !csteps || settings.incpos >= csteps.length ) {
+ go(1);
+ } else {
+ subgo(1);
+ }
+ break;
+ case 33: // page up
+ case 37: // leftkey
+ case 38: // upkey
+
+ if( !settings.steps[settings.snum-1] || settings.incpos <= 0 ) {
+ go(-1);
+ } else {
+ subgo(-1);
+ }
+ break;
+ case 36: // home
+ goTo(1);
+ break;
+ case 35: // end
+ goTo(settings.smax);
+ break;
+ case 67: // c
+ showHide('c'); // toggle controls (navlinks,navlist)
+ break;
+ case 65: //a
+ case 80: //p
+ case 83: //s
+ toggleAutoplay();
+ break;
+ case 70: //f
+ toggleFooter();
+ break;
+ case 78: // n
+ toggleSlideNumber();
+ break;
+ case 68: // d
+ toggleDebug();
+ break;
+ }
+ }
+}
+
+function autoplay()
+{
+ // suspend autoplay in outline view (just slideshow view)
+ if( !settings.isProjection )
+ return;
+
+ // next slide/step, please
+ var csteps = settings.steps[settings.snum-1]; // current slide steps array
+ if( !csteps || settings.incpos >= csteps.length ) {
+ if( settings.snum >= settings.smax )
+ goTo( 1 ); // reached end of show? start with 1st slide again (for endless cycle)
+ else
+ go(1);
+ }
+ else {
+ subgo(1);
+ }
+}
+
+function toggleDebug()
+{
+ settings.debug = !settings.debug;
+ doDebug();
+}
+
+function doDebug()
+{
+ // fix/todo: save background into oldbackground
+ // so we can restore later
+
+ if( settings.debug == true )
+ {
+ $( '#header' ).css( 'background', '#FCC' );
+ $( '#footer' ).css( 'background', '#CCF' );
+ $( '#controls' ).css( 'background', '#BBD' );
+ $( '#currentSlide' ).css( 'background', '#FFC' );
+ }
+ else
+ {
+ $( '#header' ).css( 'background', 'transparent' );
+ $( '#footer' ).css( 'background', 'transparent' );
+ $( '#controls' ).css( 'background', 'transparent' );
+ $( '#currentSlide' ).css( 'background', 'transparent' );
+ }
+}
+
+
+function toggleAutoplay()
+{
+ if( settings.autoplayInterval )
+ {
+ clearInterval( settings.autoplayInterval );
+ settings.autoplayInterval = null;
+ }
+ else
+ {
+ settings.autoplayInterval = setInterval ( autoplay, 2000 );
+ }
+}
+
+
+
+function collectStepsWorker(obj) {
+
+ var steps = new Array();
+ if( !obj )
+ return steps;
+
+ $(obj).children().each( function() {
+ if( $(this).hasClass( 'step' ) ) {
+
+ debug( 'step found for ' + this.tagName );
+ $(this).removeClass( 'step' );
+
+ /* don't add enclosing list; instead add step class to all list items/children */
+ if( $(this).is( 'ol,ul' ) ) {
+ debug( ' ol or ul found; adding auto steps' );
+ $(this).children().addClass( 'step' );
+ }
+ else
+ {
+ steps.push( this )
+ }
+ }
+
+ steps = steps.concat( collectStepsWorker(this) );
+ });
+
+ return steps;
+}
+
+function collectSteps() {
+
+ var steps = new Array();
+
+ $slides.each( function(i) {
+ debug ( 'collectSteps for ' + this.id + ':' );
+ steps[i] = collectStepsWorker( this );
+ });
+
+ $( steps ).each( function(i) {
+ debug( 'slide ' + (i+1) + ': found ' + this.length + ' steps' );
+ });
+
+ return steps;
+}
+
+
+function addClicker() {
+ // if you click on heading of slide -> go to next slide (or next step)
+
+ $( settings.titleSelector, $slides ).click( function( ev ) {
+ if(ev.which != 1) return; // only process left clicks (e.g 1; middle and rightclick use 2 and 3)
+
+ if( !settings.isProjection ) // suspend clicker in outline view (just slideshow view)
+ return;
+
+ var csteps = settings.steps[settings.snum-1]; // current slide steps array
+ if ( !csteps || settings.incpos >= csteps.length )
+ go(1);
+ else
+ subgo(1);
+ } );
+
+
+ $( settings.titleSelector, $slides ).bind('contextmenu', function() {
+ if( !settings.isProjection ) // suspend clicker in outline view (just slideshow view)
+ return;
+
+ var csteps = settings.steps[settings.snum-1]; // current slide steps array
+ if ( !csteps || settings.incpos >= csteps.length )
+ go(-1);
+ else
+ subgo(-1);
+
+ return false;
+ } );
+}
+
+function addSlideIds() {
+ $slides.each( function(i) {
+ this.id = 'slide'+(i+1);
+ });
+ }
+
+ // init code here
+
+ // store possible slidenumber from hash */
+ // todo: use regex to extract number
+ // might be #slide1 or just #1
+
+ var gotoSlideNum = parseInt( window.location.hash.substring(1) );
+ debug( "gotoSlideNum=" + gotoSlideNum );
+
+ var $slides = $( '.slide' );
+ settings.smax = $slides.length;
+
+ addSlideIds();
+ settings.steps = collectSteps();
+
+ createControls();
+
+ addClicker();
+
+ /* opera is the only browser currently supporting css projection mode */
+ /* if( !$.browser.opera ) */
+ notOperaFix();
+
+ if( !isNaN( gotoSlideNum ))
+ {
+ debug( "restoring slide on (re)load #: " + gotoSlideNum );
+ goTo( gotoSlideNum );
+ }
+
+ if( settings.mode == 'outline' )
+ toggle();
+ else if( settings.mode == 'autoplay' )
+ toggleAutoplay();
+
+
+ if( settings.debug == true )
+ doDebug();
+
+ document.onkeyup = keys;
+
+} // end Slideshow