Git'er DonejRoulettearg¡eBarg!ehhROGERSii

jRoulette

a touch enabled image browser

jRoulette is an image slideshow carousel which means that the slides loop from the end to the beginning and vice versa. Developed as a jQuery plugin, jRoulette supports swipe gestures, automatic start, pagination, and left/right bumpers. Although the final version retains little semblance to the original, Andrew Marcus & Love Media jBond Slider served as the inspiration and the code starting point. Many thanks!

Paul Klee

1914
Ancient Sound
Captive
Dream City
Embrace
Highway Byways
Park Idols
Parnassum
Tunisian Gardens
Paul Klee the artist
<!doctype html>
<html>

<head>
	<meta charset="utf-8" />
	<title>&gt;arg&iexcl;eBarg!e: jRoulette</title>
	<meta name="description" content="&hellip;a continuous image carousel." />
	<meta name="author" content="Henry Rogers" />
	<meta name="viewport" content="width=device-width, initial-scale=1" />
	<!--[if lt IE 9]>
		<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->
	<!-- Adding "maximum-scale=1" fixes the Mobile Safari auto-zoom bug: http://filamentgroup.com/examples/iosScaleBug/ -->
	<link type="text/css" rel="stylesheet" href="jroulette.css" />
</head>

<body lang="en">

	<div id="header-container" class="wrapper lab">
    	<header>
			<h1>&gt;arg&iexcl;eBarg!e:</h1>
			<span>&hellip;such as an argument, often a worthless, but energetic, conversation or comment.</span>
		</header>
	</div>

	<div id="main" class="wrapper lab" role="main">
    <article>

        <header>
			<div style="float:right">
				<a href="https://github.com/hhrogersii/argleBargle/tree/master/jroulette/"><img id="octodex" src="/img/octodex.png" width="24" height="24" alt="Git'er Done" /></a>  &larr;
	 			<a href="http://hhrogersii.com/lab/jroulette/">jRoulette</a> &larr; 
				<a href="http://hhrogersii.com/lab/">arg&iexcl;eBarg!e</a> &larr; 
				<a href="http://hhrogersii.com/">hhROGERSii</a>
			</div>
        	<h2>jRoulette</h2>
        	<p>&hellip;a continuous image carousel.</p>
        </header>

		<section>
			<div class="section" style="position:relative">
				<h3>Paul Klee</h3>
<div class="jroulette">
	<div class="roul-touchmargin">
		<div class="roul-bump-left"></div>
		<div class="roul-wrap">
			<div class="roul-boxy">
				<div class="roul-slds" id="slide-0" style="left:0px">
					<img src="klee_1914.jpg" alt="1914" width="300" height="360" />
				</div>
				<div class="roul-slds" id="slide-1" style="left:640px">
					<img src="klee_ancient-sound.jpg" alt="Ancient Sound" width="348" height="360" />
				</div>
				<div class="roul-slds" id="slide-2" style="left:1280px">
					<img src="klee_captive.jpg" alt="Captive" width="321" height="360" />
				</div>	
				<div class="roul-slds" id="slide-3" style="left:1920px">
					<img src="klee_dream-city.jpg" alt="Dream City" width="232" height="360" />
				</div>
				<div class="roul-slds" id="slide-4" style="left:2560px">
					<img src="klee_embrace.jpg" alt="Embrace" width="448" height="360" />
				</div>
				<div class="roul-slds" id="slide-5" style="left:3200px">
					<img src="klee_highway-byways.jpg" alt="Highway Byways" width="285" height="360" />
				</div>
				<div class="roul-slds" id="slide-6" style="left:3840px">
					<img src="klee_park-idols.jpg" alt="Park Idols" width="225" height="360" />
				</div>
				<div class="roul-slds" id="slide-7" style="left:4480px">
					<img src="klee_parnassum.jpg" alt="Parnassum" width="458" height="360" />
				</div>
				<div class="roul-slds" id="slide-8" style="left:4480px">
					<img src="klee_tunisian-gardens.jpg" alt="Tunisian Gardens" width="273" height="360" />
				</div>
				<div class="roul-slds" id="slide-9" style="left:4480px">
					<img src="paul_klee_artist.jpg" alt="Paul Klee the artist" width="485" height="360" />
				</div>
			</div>
		</div>
		<div class="roul-bump-right"></div>
	</div>
	<div class="roul-page">
		<ul>
			<li id="page-0"><a href="##page-0"></a></li>
			<li id="page-1"><a href="##page-1"></a></li>
			<li id="page-2"><a href="##page-2"></a></li>
			<li id="page-3"><a href="##page-3"></a></li>
			<li id="page-4"><a href="##page-4"></a></li>
			<li id="page-5"><a href="##page-5"></a></li>
			<li id="page-6"><a href="##page-6"></a></li>
			<li id="page-7"><a href="##page-7"></a></li>
			<li id="page-8"><a href="##page-8"></a></li>
			<li id="page-9"><a href="##page-9"></a></li>
		</ul>
	</div>
</div>
			</div>
		</section>

   		<footer>
			<p>
				<a href="https://github.com/hhrogersii/argleBargle/tree/master/jroulette/"><img id="octodex" src="/img/octodex.png" width="24" height="24" alt="Git'er Done" /></a>  &larr;
	 			<a href="http://hhrogersii.com/lab/jroulette/">jRoulette</a> &larr; 
				<a href="http://hhrogersii.com/lab/">arg&iexcl;eBarg!e</a> &larr; 
				<a href="http://hhrogersii.com/">hhROGERSii</a>
			</p>
		</footer>

    </article>

	</div>

	<div id="footer-container" class="wrapper lab">
		<footer>
			<p>All code authored by hhrogersii is available for use with or without attribution under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>.
			<br />See disclaimers provided by the authors of code included in this site for the terms and conditions of the use of their work.</p>
		</footer>
	</div>

	<!--Thank you jQuery -->
	<script src="http://code.jquery.com/jquery-latest.js"></script>
	<script>!window.jQuery && document.write(unescape('%3Cscript src="/js/libs/jquery-1.5.1.min.js"%3E%3C/script%3E'))</script>
	<script type="text/javascript" src="jroulette.js"></script>
	<script>
		$(document).ready(
			function(){
				$('.roul-touchmargin').jRoulette(
					{ desktopMode:'touchMargin', mobileMode:'touchMargin' }
				);
			}
		);
	</script>
</body>

</html>
/*jslint browser: true, undef: false, sloppy: true, vars: true, white: true, forin: false, nomen: false, maxerr: 100, indent: 4 */
/*globals document,$,jQuery*/
/* 
 * jRoulette v0.1
 * Designed and written by hhrogersii
 * Licensed under MIT

 * Inspired by jBond Slider 0.9
 * Andrew Marcus & Love Media, 2010
 * Licensed under MIT
 */

(function ($) {

	'use strict';

	$.fn.extend(
		{
			jRoulette: function ( opt )
			{
				jQuery.extend(
					jQuery.easing
				  , {
						roul_ease: function ( x, t, b, c, d )
						{
							x = x;
							return ( t === d ) ? b+c : c*(-Math.pow(2,-10*t/d)+1)+b;
						}
					}
				);

				var dflts = {
								scroll:		3
							  , bounce:		4
							  , veloce:		5
							  , neutra:		6	// Rest area width in px
							  , mspeed:		7	// Max speed
			
							  , wrapSelector:	'.roul-wrap'
							  , boxySelector:	'.roul-boxy'
							  , sldsSelector:	'.roul-slds'
							  , bumpSelector:	'.roul-bump'
							  , pageSelector:	'.roul-page'
							  , easingMargin:	 'swing' //'roul_ease'
			
							  , slideClickCallback: function ( i, d )
								{
									i = d;
								}
							}
				 		  , option = {};

				if ( !opt )
				{
					opt = dflts;
				}
				else
				{
					for ( option in dflts )
					{
						if ( dflts.hasOwnProperty(option) && opt[option] === undefined )
						{
							opt[option] = dflts[option];
						}
					}
				}

				//private
				function getLeft ( f )
				{
					return parseInt( f.css('left'), 10 );
				}
				function setLeft ( f, d )
				{
					f.css( 'left', ( getLeft(f) + d ) );
				}

				function wrapIndex ( v, l )
				{
					return ( v + l ) % l;
				}

				function manual ( i )
				{
					clearInterval( i );
				}

				//public
				return this.each(

					function ()
					{
						var roul = $(this)
						  , wrap = roul.children( opt.wrapSelector )
						  , boxy = wrap.children( opt.boxySelector )
						  , slds = boxy.children( opt.sldsSelector )
						  , scnt = slds.length
						  , frst = slds.first()
						  , bump = roul.children( opt.bumpSelector+'-left,' +opt.bumpSelector+'-right' )
						  , page = $( opt.pageSelector ).find('li')
						  , sdim = frst.width()
						  , adim = scnt * sdim
						  , touch = 0, delta = 0, veloc = 0, crrnt = 0, dirct = 0, autos = 0
						;

						function animate ( target, fn )
						{
							var callback = ( !fn ) ? jQuery.noop : fn
							  , time = parseFloat( (opt.scroll).toString() + 's' ) * 1000;

							page.removeClass('hover');

							frst.animate(
								{
									'left': target
								}
							  , {
									duration:	time
								  , easing:		opt.easingMargin
								  , complete:	callback
								  , step:		function ( now )
									{
										slds.css(
											'left'
										  , function ( index )
											{
												return ( (index * sdim) + now ) % adim;
											}
										);
									}
								}
							);

							page.eq( ( scnt - crrnt ) % scnt ).addClass('hover');
						}

						function change ( e, c, d )
						{
							manual( autos );

							slds.stop( true );
							e.preventDefault();
							e.stopPropagation();

							crrnt = c;
							dirct = d;
						}

						function select ( e, p )
						{
							if ( scnt-p === crrnt )
							{
								return false;
							}

							var cur = crrnt;
							var tar = scnt - p;

							var dis = cur - tar;
							var abs = Math.abs( dis );
							var opp = scnt - abs;
							var dir = abs / dis;

							//var shift = Math.min( abs , (scnt-abs) ) * abs / dis;	
							var shf = (
										( tar < cur )
									? ( ( abs < opp ) ?  1 : -1 ) 
									: ( ( abs < opp ) ? -1 :  1 ) 
								);

							if ( shf !== dir )
							{
								setLeft( frst, ( adim * -dir ) );
							}

							change( 
								e
							  , tar
							  , dir
							);
							
							animate( tar * sdim );
						}

						function browse ( e, d )
						{
							if ( ( d > 0 && crrnt === scnt-1 ) || ( d < 0 && crrnt === 0 ) )
							{
								setLeft( frst, ( adim * -d ) );
							}

							change( 
								e
							  , wrapIndex( ( crrnt + d ), scnt )
							  , d
							);

							animate( crrnt * sdim );
						}

						function automatic()
						{
							autos = window.setInterval(
								function () 
								{
									if ( crrnt === 0 )
									{
										setLeft( frst, adim );
									}
									slds.stop( true );
									crrnt = wrapIndex( ( crrnt + -1 ), scnt );
									dirct = -1;
									animate( crrnt * sdim );
								}
							  , 4000
							);
						}

						function back ()
						{
							crrnt = wrapIndex( ( -Math.round( getLeft( frst ) / sdim ) ), scnt );

							var shift = wrapIndex( ( -crrnt ), scnt ) * sdim;

							if ( shift === 0 && getLeft( frst ) > 2400 )
							{
								setLeft( frst, ( adim * dirct ) );
							}

							animate( shift );
						}

						function end ()
						{
							touch = 0;

							if ( Math.abs(veloc) > opt.veloce )
							{
								animate( getLeft( frst ) + Math.floor( Math.sqrt( Math.abs(veloc) * opt.bounce ) ) * veloc, back );
							}
							else
							{
								back();
							}

							slds.unbind( 'mousemove move' );
							$(document).unbind( 'mouseup end' );

							return false;
						}

						function move ( x )
						{
							veloc = x - touch - delta;
							delta = x - touch;
							dirct = Math.abs(veloc)/veloc;

							slds.css(
								'left'
							  , function ( index )
								{
									return wrapIndex( (index * sdim) + delta, adim );
								}
							);

							return false;
						}

						function begin ( e )
						{
							if ( e.button === 2 )
							{
								return false;
							}
							var me = ( e.originalEvent && e.originalEvent.touches ) ? e.originalEvent.touches[0] : e;

							slds.stop();
							e.preventDefault();
							e.stopPropagation();

							manual( autos );

							delta = 0;
							veloc = 0;
							touch = me.pageX - getLeft( frst );

							slds.on(
								'mousemove move'
							  , function (me)
								{
									move(me.pageX);
								}
							);

							$(document).on(
								'mouseup end'
							  , function ()
								{
									end();
								}
							);

							return false;
						}

						roul.find('a').click(
							function ()
							{
								if ( delta !== 0 )
								{
									return false;
								}
							}
						);

						/* Setting zero position */
						wrap.css(
							'left'
						  , (     (    (   Math.ceil(  (scnt+1) / 2 ) - 1  )   *  -sdim    )    ).toString() + 'px'
						);

						boxy.children( opt.sldsSelector ).click(
							function ()
							{
								opt.slideClickCallback( slds.index(this), delta );
							}
						);

						slds.on(
							'mousedown begin'
						  , function (e)
							{
								begin(e);
							}
						);

						bump.on(
							{
								click: function(e)
								{
									if ( touch === 0 )
									{
										browse( e, ( $(this).attr('class').indexOf('right')>0 ? -1 : 1 ) );
									}
								}
							  , mouseenter: function()
								{
									if ( touch === 0 )
									{
										$(this).addClass('hover');
									}
								}
							  , mouseleave: function()
								{
									$(this).removeClass('hover');
 								}
							} 
						);

						page.on(
							{
								click: function (e)
								{
									select( e, $(this).index() );
								}
							  , mouseenter: function()
								{
									$(this).addClass('hover');
								}
							  , mouseleave: function()
								{
									$(this).removeClass('hover');
								}
							}
						);

						automatic();
					}
				);//end public
			}//end roul
		}//end map
	);//end extend
}( jQuery ) );
.jroulette {
	padding-bottom:30px;
	width:660px;
}
.roul-touchmargin {
	height: 360px;
	position: relative;
	overflow: hidden;
	width: 640px;
	border: 10px solid #fff7d1;
}
.roul-wrap {
	-webkit-transform: translate3d(0px, 0px, 0px);
	-webkit-transition-property: -webkit-transform;
	-webkit-transition-duration: 0s;
	-webkit-transition-timing-function: cubic-bezier(0,1,1,1);
	position: absolute;
	left: 0;
	top: 0;
}
.roul-wrap a {
	-webkit-transition: none;
	-moz-transition: none;
	-o-transition: none;
	transition: none;
	border: none;
	
}
.roul-boxy {
	width: 4480px;
}
.roul-slds {
	margin: 0;
	width: 640px;
	position: absolute;
	text-align: center;
	background-color: #e4e2d3;
}
.roul-slds img {
	/* width: 640px; */
	height: 360px;
	border: none;
}
.roul-slds a {
	cursor:move;
}
.roul-bump-left, .roul-bump-right {
	background-color: white;
	width: 40px;
	height: 360px;
	opacity: .0;
	-moz-opacity: .0;
	cursor: pointer;
}
.roul-bump-left.hover, .roul-bump-right.hover {
	opacity: .7;
	-moz-opacity: .7;
}
.roul-bump-left.hover {
	background: no-repeat url('/img/arrow_next_left.png') center center rgba(255,255,255,0.6);
}
.roul-bump-right.hover {
	background: no-repeat url('/img/arrow_next_right.png') center center rgba(255,255,255,0.6);
}
.roul-bump-left {
	float: left;
	position: absolute;
    z-index: 100;
}
.roul-bump-right {
	float: right;
}
.roul-page {
	text-align: center;
	float: left;
	width: 660px;
}
.roul-page ul {
	list-style-position: inside;
	list-style-type:decimal;
	display: inline-block;
}
.roul-page li {
	color: #aa8b64;
	width: 26px;
	float: left; 
	font-size:16px; 
	margin: 2px;
	padding: 4px 0 4px 8px
}
.roul-page li.hover {
	text-shadow: 0px 0px 3px;
	/* -moz-box-shadow:inset 0 0 6px 6px #ECE5CF;
		-webkit-box-shadow:inset 0 0 6px 6px #ECE5CF;
			box-shadow:inset 0 0 6px 6px #ECE5CF;
	background-color: #b89e8a; */                          
	color: #333;
}
.roul-page li a {
	position:absolute; 
	left:-1000px;
}