| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- ; (function (w, $, undefined) {
- w.jqBoxSlider = w.jqBoxSlider || {};
- var methods = {} // external method api
- , supports3D = true // set during vendorPrefix determination
- , slideAnimators = {} // map of animation effect objects
- , defaults = { // default required settings
- speed: 800
- , responsive: true
- , timeout: 5000
- , autoScroll: false
- , pauseOnHover: false
- , effect: 'scrollVert3d'
- , perspective: 1000
- };
- // API methods ---------------------------------------------------------------
- // sets up all selected boxes with applied options
- methods.init = function (opts) {
- var defaultSettings = $.extend({}, defaults, opts)
- , animator = methods.slideAnimator(defaultSettings.effect);
- return this.each(function () {
- var $this = $(this)
- , settings = $.extend({}, defaultSettings)
- , $slides = $this.children();
- $this.data('bssettings', settings);
- settings.slideAnimator = animator;
- settings.slideAnimator.initialize($this, $slides, settings);
- $slides.eq(settings.bsfaceindex || 0).addClass('jbs-current');
- setupControls($this, settings);
- if (settings.autoScroll) {
- settings.autointv = setInterval(function () {
- showNextSlide($this);
- }, settings.timeout + settings.speed);
- if (settings.pauseOnHover) {
- $this.on('hover', togglePlayPause);
- }
- }
- if (settings.responsive && jqBoxSlider.responder) {
- jqBoxSlider.responder.watch($this);
- }
- });
- };
- // toggles the autoplay state for each slider
- methods.playPause = function () {
- return this.each(function (i, el) {
- togglePlayPause.call($(this));
- });
- };
- // show the slide at the given index
- methods.showSlide = function (index) {
- index = parseInt(index, 10);
- return this.each(function () {
- var $box = $(this);
- var settings = $box.data('bssettings');
- resetAutoScroll($box);
- showNextSlide($box, index, index < settings.bsfaceindex);
- });
- };
- // moves the slider to the next slide
- methods.next = function () {
- return this.each(function () {
- var $box = $(this);
- showNextSlide($box);
- });
- };
- // moves the slider to the previous slide
- methods.prev = function () {
- return this.each(function () {
- var $box = $(this);
- showNextSlide($box, null, true);
- });
- };
- // registers and configures a slide animator
- methods.registerAnimator = function (names, animator) {
- $.each(names.split(','), function (i, name) {
- slideAnimators[name] = animator;
- });
- animator._cacheOriginalCSS = cacheCSS;
- if (typeof animator.configure === 'function') {
- animator.configure(supports3D, vendorPrefix);
- }
- };
- // returns a slide animation adaptor
- methods.slideAnimator = function (effect) {
- if (typeof slideAnimators[effect] === 'object') {
- return slideAnimators[effect];
- }
- throw new Error(
- 'The slide animator for the ' + effect +
- ' effect has not been registered'
- );
- };
- // sets or gets an option for the set of matched sliders
- methods.option = function (setting, newValue) {
- if (typeof newValue === 'undefined') {
- return (this.data('bssettings') || {})[setting];
- }
- if (setting === 'effect') {
- throw new Error('Effect can only be set during plugin initialisation');
- }
- return this.each(function (i, el) {
- var $box = $(this)
- , settings = $box.data('bssettings') || {}
- , $slides = filterSlides($box.children(), settings);
- settings[setting] = newValue;
- resetAutoScroll($box, settings);
- //if (typeof settings.slideAnimator.reset === 'function') {
- // settings.slideAnimator.reset($box, $slides, settings);
- //}
- });
- };
- // destroy the plugin for the selected sliders
- methods.destroy = function () {
- return this.each(function () {
- var $box = $(this)
- , data = $box.data() || {}
- , settings = data.bssettings;
- if (settings && typeof settings.slideAnimator === 'object') {
- clearInterval(settings.autointv);
- settings.slideAnimator.destroy($box, settings);
- tearDownControls(settings);
- $box
- .removeData('bssettings')
- .removeClass('jbs-in-motion')
- .find('.jbs-current')
- .removeClass('jbs-current');
- }
- });
- };
- // Called on window resize if the responder is being used
- methods.resize = function ($sliders) {
- return $.each($sliders || this, function (i, slider) {
- var $slider = $(slider)
- , settings = $slider.data('bssettings');
- if ( // Call resize method on animator if it exists
- settings &&
- settings.slideAnimator &&
- $.isFunction(settings.slideAnimator.resize)
- ) {
- settings.slideAnimator.resize(
- $slider
- , filterSlides($slider, settings)
- , settings
- );
- }
- });
- };
- $.extend(jqBoxSlider, methods);
- // Event listeners and controls ----------------------------------------------
- // initialise controls for $box
- var setupControls = function ($box, settings) {
- var $controls = $();
- if (settings.next != null) {
- $controls = $controls.add($(settings.next).on(
- 'click', { reverse: false }, nextSlideListener
- ));
- }
- if (settings.prev != null) {
- $controls = $controls.add($(settings.prev).on(
- 'click', { reverse: true }, nextSlideListener
- ));
- }
- if (settings.pause != null) {
- $controls = $controls.add($(settings.pause).on(
- 'click', playPauseListener
- ));
- }
- $controls.data('bsbox', $box);
- };
- var tearDownControls = function (settings) {
- $(
- settings.next,
- settings.prev,
- settings.pause
- )
- .off('click', nextSlideListener)
- .off('click', playPauseListener)
- .removeData('bsbox');
- };
- // event listener for a next button
- var nextSlideListener = function (ev) {
- var $box = $(this).data('bsbox');
- resetAutoScroll($box);
- showNextSlide($box, undefined, ev.data.reverse);
- ev.preventDefault();
- };
- // event listener for play pause button
- var playPauseListener = function (ev) {
- var $this = $(this)
- , $box = $this.data('bsbox');
- togglePlayPause.call($box);
- $this.toggleClass('paused');
- ev.preventDefault();
- };
- // event listener for pause on hover
- var togglePlayPause = function (ev, reset, settings) {
- var $box = $(this)
- , playing;
- settings = settings || $box.data('bssettings');
- playing = settings.autointv != null;
- if (typeof settings.onplaypause === 'function') {
- settings.onplaypause.call($box, playing ? 'pause' : 'play');
- }
- if (playing || reset) {
- settings.autointv = clearInterval(settings.autointv);
- if (!reset) return;
- }
- settings.autointv = setInterval(function () {
- showNextSlide($box);
- }, settings.timeout + settings.speed);
- };
- // moves the slider to the next or previous slide
- var showNextSlide = function ($box, index, reverse) {
- var settings = $box.data('bssettings')
- , $slides = filterSlides($box, settings)
- , currIndex
- , nextIndex
- , $currSlide
- , $nextSlide;
- currIndex = settings.bsfaceindex || 0;
- nextIndex = calculateIndex(currIndex, $slides.length, reverse, index);
- // only go forward if not already in motion
- // and user defined index is not out of bounds
- if ($box.hasClass('jbs-in-motion') || nextIndex === -1) return;
- $currSlide = $slides.eq(currIndex);
- $nextSlide = $slides.eq(nextIndex);
- $box.addClass('jbs-in-motion'); // stops user clunking through faces ----- FIXME: queue user clicks and keep rotating the box
- if (typeof settings.onbefore === 'function') {
- settings.onbefore.call($box, $currSlide, $nextSlide, currIndex, nextIndex);
- }
- // add additional settings for the transition and
- // call the slide animation
- $.extend(settings, settings.slideAnimator.transition($.extend({
- $box: $box
- , $slides: $slides
- , $currSlide: $currSlide
- , $nextSlide: $nextSlide
- , reverse: reverse
- , currIndex: currIndex
- , nextIndex: nextIndex
- }, settings)));
- setTimeout( // remove the active flag class once transition is complete
- function () {
- $box.removeClass('jbs-in-motion');
- $currSlide.removeClass('jbs-current');
- $nextSlide.addClass('jbs-current');
- if (typeof settings.onafter === 'function') {
- settings.onafter.call($box, $currSlide, $nextSlide, currIndex, nextIndex);
- }
- }
- , settings.speed
- );
- // cache settings for next transition
- settings.bsfaceindex = nextIndex;
- };
- var filterSlides = function ($box, settings) {
- var $slides = $box.children();
- // User defined slide filter
- if (typeof settings.slideFilter === 'function') {
- $slides = $slides.filter(settings.slideFilter);
- }
- // Effect defined filter
- if (typeof settings._slideFilter === 'function') {
- $slides = $slides.filter(function (index) {
- return settings._slideFilter.call($slides, index, settings);
- });
- }
- return $slides;
- };
- // if the box is autoscrolling it is reset
- var resetAutoScroll = function ($box, settings) {
- settings || (settings = $box.data('bssettings') || {});
- if (settings.autoScroll) {
- togglePlayPause.call($box, undefined, true, settings);
- }
- };
- // get the next slides index
- var calculateIndex = function (currIndex, slidesLen, reverse, index) {
- var nextIndex = index;
- if (nextIndex == null) { // came from next button click
- if (reverse) {
- nextIndex = currIndex - 1 < 0 ? slidesLen - 1 : currIndex - 1;
- }
- else {
- nextIndex = currIndex + 1 < slidesLen ? currIndex + 1 : 0;
- }
- }
- if ( // already on selected slide or incorrect index
- nextIndex === currIndex ||
- nextIndex >= slidesLen ||
- nextIndex < 0
- ) { return -1; }
- return nextIndex;
- };
- // caches the desired css for reapplying the original styling when
- // the plugin is destroyed or reset
- var cacheCSS = function ($el, name, settings, extraAtts) {
- var el = $el.get(0)
- , attributes = [
- 'position', 'top', 'left', 'display', 'overflow',
- 'width', 'height', 'zIndex'
- ].concat(extraAtts || []);
- settings.origCSS || (settings.origCSS = {});
- settings.origCSS[name] || (settings.origCSS[name] = {});
- $.each(attributes, function (i, att) {
- settings.origCSS[name][att] = el.style[att];
- });
- };
- // set the correct vendor prefix for the css properties
- var vendorPrefix = (function () {
- var bs = document.body.style
- , prefix = '';
- if ('webkitTransition' in bs) {
- prefix = '-webkit-';
- }
- if ('MozTransition' in bs) {
- prefix = '-moz-';
- }
- supports3D = (
- 'webkitPerspective' in bs ||
- 'MozPerspective' in bs ||
- 'perspective' in bs
- );
- return prefix;
- }());
- $.fn.boxSlider = function (m) {
- if (typeof m === 'string' && typeof methods[m] === 'function') {
- return methods[m].apply(this, Array.prototype.slice.call(arguments, 1));
- }
- return methods.init.apply(this, arguments);
- };
- }(window, jQuery || Zepto));
|