Mercurial > hg > Members > innparusu > slides
diff 2015_06_02/s6/jquery.slideshow.js @ 0:47676a16ed13
Add Slides
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 14 Jul 2015 17:23:04 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2015_06_02/s6/jquery.slideshow.js Tue Jul 14 17:23:04 2015 +0900 @@ -0,0 +1,512 @@ + +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(); +} + +/*********************** + * 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 + }, 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( 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(); +} + + 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="#">Ø<\/a>' + + '<a accesskey="z" id="prev" href="#">«<\/a>' + + '<a accesskey="x" id="next" href="#">»<\/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() { + 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); + } ); +} + +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