// # microfiche.js v1.8.0
//
// ## usage
//
// $('.my-slideshow').microfiche();
// $('.my-slideshow').microfiche({ cyclic: true, button: false });
// $('.my-slideshow').microfiche({ slidebypages: 1 });
//
// ## options
//
// the following options can be passed the first time `microfiche` is called
// on an element.
//
// ### cyclic
//
// if true, microfiche wraps around at front and beginning of the slideshow.
// this option is false by default.
//
// $('.my-slideshow').microfiche({ cyclic: true });
//
// ### buttons
//
// if true, microfiche will create previous/next buttons.
// this option is true by default.
//
// $('.my-slideshow').microfiche({ buttons: false });
//
// ### bullets
//
// if true, microfiche will create bullets for the pages available.
// this option is also true by default.
//
// $('.my-slideshow').microfiche({ bullets: false });
//
// ## commands
//
// the following commands can be run on a microfiche'd element at any point,
// including in the first call.
//
// ### slidebypages
//
// slides `n` screenfuls (negative `n` goes backwards).
//
// $('.my-slideshow').microfiche({ slidebypages: n });
//
// ### slidetopage
//
// slides to the `nth` screenful.
//
// $('.my-slideshow').microfiche({ slidetopage: n });
//
// ### slidetopoint
//
// slides to point `x` (rounded and constrained appropriately).
//
// $('.my-slideshow).microfiche({ slidetopoint: x });
//
// ### jumptopoint
//
// jumps without animation to point x (again, rounded and constrained).
//
// $('.my-slideshow').microfiche({ jumptopoint: x });
//
// ### autoplay
//
// automatically advances every `n` seconds.
//
// $('.my-slideshow').microfiche({ autoplay: n });
//
// ### autopause
//
// automatically pause autoplay when the user hovers over the carousel.
//
// $('.my-slideshow').microfiche({ autoplay: n, autopause: true });
//
// ### refresh
//
// to refresh an existing microfiche’s controls and content to adjust
// to a new container size, call the `refresh` method.
//
// $('.my-slideshow').microfiche({ refresh: true });
//
// ### refreshonresize
//
// automatically refresh microfiche filmstrip and controls on window
// resize event. set `true` to refresh with a 250ms debounce, or specify
// a custom debounce rate in ms. the default value is false.
//
// $('.my-slideshow').microfiche({ refreshonresize: 100 });
//
// ### destroy
//
// destroys the microfiche instance and clear related events
//
// $('my-slideshow').microfiche({ destroy: true });
// // or
// $('my-slideshow').data('microfiche').destroy();
//
// ### noscrollalign
//
// defines left, right, or center filmstrip alignment in the event that
// all items are visible on screen and no scrolling is required.
//
// $('.my-slideshow').microfiche({ noscrollalign: 'left' });
//
(function() {
window.microfiche = function(options) { this.initialize(options); return this; };
microfiche.version = '1.8.0';
$.extend(microfiche.prototype, {
// ## default options ##
//
// these may be overridden in the initializer.
options: {
autoplay : false,
autopause : false,
buttons : true,
bullets : true,
cyclic : false,
keyboard : false,
swipe : true,
clicktoadvance : false,
minduration : 250,
duration : 500,
maxduration : 500,
dragthreshold : 25,
elasticity : 0.5,
swipethreshold : 0.125,
refreshonresize : false,
prevbuttonlabel : '←',
nextbuttonlabel : '→',
noscrollalign : 'left'
},
// rather than relying on the literal position of `this.film`,
// we keep a tab on the current destination.
x: 0,
// ## setup ##
// build microfiche in steps.
initialize: function(options) {
this.options = $.extend({}, this.options, options);
this.el = $(options.el);
this.initialcontents = this.el.contents();
this.el.data('microfiche', this);
this.createfilm();
this.createscreen();
this.calibrate();
if (this.film.width() <= this.screen.width()) {
this.noscrollalign(this.options.noscrollalign);
this.refreshonresize(this.options.refreshonresize);
return;
}
this.createcontrols();
this.enabletouch();
this.enablekeyboard();
this.enableclick();
this.preparecyclic();
this.run(this.options);
},
// we create our film element, which we’ll slide back and forth in the screen.
// before appending any extra elements, we detach the existing children,
// append them to film, and tell them to float so they’ll (hopefully) lay-out
// nicely along the horizontal.
createfilm: function() {
this.film = $('
').
css({ position: 'absolute' });
this.el.children().appendto(this.film).css({ float: 'left' });
this.preparefilm && this.preparefilm();
},
// the screen is created and appended to our element, then the film is
// appended to the screen. screen manually takes its height from film.
createscreen: function() {
this.screen = $('
').
css({ position: 'relative', overflow: 'hidden' }).
appendto(this.el).
append(this.film);
},
// prepare duplicate content at either end, for our cyclic behaviour.
preparecyclic: function() {
if (!this.options.cyclic) return;
var clonel = this.film.clone(),
cloner = this.film.clone(),
w = this.film.width();
clonel.prependto(this.film).css({ position: 'absolute', left: -w + 'px' });
cloner.appendto(this.film).css({ position: 'absolute', left: w + 'px' });
},
// this slightly strange process tries to ensure we don’t get any wrapping
// in `this.film`, then fixes the dimensions of `this.film` and `this.screen`.
calibrate: function() {
this.screen.width(100000);
var w = this.film.width(),
h = this.film.height();
this.film.width(w).height(h);
this.screen.width('auto').height(h);
},
// create prev/next buttons and page bullets.
createcontrols: function() {
var self = this;
this.controls = $('').appendto(this.el);
this.controls.on('click', 'a, button', function(e) { self.didclickcontrol(e) });
if (this.options.bullets) this.createbullets();
if (this.options.buttons) this.createbuttons();
this.updatecontrols();
},
// create page bullets.
createbullets: function() {
var container = $('').appendto(this.controls);
for (var i = 0; i < this.totalpagecount(); i++) {
$('