/** * Carousel - jQuery plugin for MetroUiCss framework */ (function($) { $.Carousel = function(element, options) { // default settings var defaults = { // auto slide change auto: true, // slide change period period: 6000, // animation duration duration: 1000, // animation effect (fade, slide, switch, slowdown) effect: 'slide', // animation direction (left, right) for some kinds of animation effect direction: 'left', // markers below the carousel markers: 'on', // prev and next arrows arrows: 'on', // stop sliding when cursor over the carousel stop: 'on' }; var plugin = this; // plugin settings plugin.settings = {}; var $element = $(element); // reference to the jQuery version of DOM element var slides, // all slides DOM objects currentSlideIndex, // index of current slide slideInPosition, // slide start position before it's appear slideOutPosition, // slide position after it's disappear parentWidth, parentHeight, animationInProgress, autoSlideTimer, markers, stopAutoSlide = false; // initialization plugin.init = function () { plugin.settings = $.extend({}, defaults, options); slides = $element.find('.slides:first-child > .slide'); // if only one slide if (slides.length <= 1) { return; } currentSlideIndex = 0; // parent block dimensions parentWidth = $element.innerWidth(); parentHeight = $element.innerHeight(); // slides positions, used for some kinds of animation slideInPosition = getSlideInPosition(); slideOutPosition = getSlideOutPosition(); // prepare slide elements slides.each(function (index, slide) { $slide = $(slide); // each slide must have position:absolute // if not, set it if ($slide.css('position') !== 'absolute') { $slide.css('position', 'absolute'); } // disappear all slides, except first if (index !== 0) { $slide.hide(); } }); if (plugin.settings.arrows === 'on') { // prev next buttons handlers $element.find('span.control.left').on('click', function(){ changeSlide('left'); startAutoSlide(); }); $element.find('span.control.right').on('click', function(){ changeSlide('right'); startAutoSlide(); }); } else { $element.find('span.control').hide(); } // markers if (plugin.settings.markers === 'on') { insertMarkers(); } // enable auto slide if (plugin.settings.auto === true) { startAutoSlide(); // stop sliding when cursor over the carousel if (plugin.settings.stop === 'on') { $element.on('mouseenter', function () { stopAutoSlide = true; }); $element.on('mouseleave', function () { stopAutoSlide = false; startAutoSlide(); }); } } }; /** * returns start position for appearing slide {left: xxx} */ var getSlideInPosition = function () { var pos; if (plugin.settings.direction === 'left') { pos = { 'left': parentWidth } } else if (plugin.settings.direction === 'right') { pos = { 'left': -parentWidth } } return pos; }; /** * returns end position of disappearing slide {left: xxx} */ var getSlideOutPosition = function () { var pos; if (plugin.settings.direction === 'left') { pos = { 'left': -parentWidth } } else if (plugin.settings.direction === 'right') { pos = { 'left': parentWidth } } return pos; }; /** * start or restart auto change */ var startAutoSlide = function () { clearInterval(autoSlideTimer); // start slide changer timer autoSlideTimer = setInterval(function () { if (stopAutoSlide) { return; } changeSlide(); }, plugin.settings.period); }; /** * inserts markers below the carousel */ var insertMarkers = function () { var div, ul, li, i; div = $('
'); ul = $('').appendTo(div); for (i = 0; i < slides.length; i++) { li = $('
  • '); if (i === 0) { li.addClass('active'); } li.appendTo(ul); } markers = ul.find('li'); ul.find('li a').on('click', function () { var $this = $(this), index; // index of appearing slide index = $this.data('num'); if (index === currentSlideIndex) { return; } changeSlide(undefined, 'switch', index); startAutoSlide(); }); div.appendTo($element); }; /** * changes slide to next */ var changeSlide = function(direction, effect, slideIndex) { var outSlide, // disappearin slide element inSlide, // appearing slide element nextSlideIndex, delta = 1, slideDirection = 1; effect = effect || plugin.settings.effect; // correct slide direction, used for 'slide' and 'slowdown' effects if ((effect === 'slide' || effect === 'slowdown') && typeof direction !== 'undefined' && direction !== plugin.settings.direction) { slideDirection = -1; } if (direction === 'left') { delta = -1; } outSlide = $(slides[currentSlideIndex]); nextSlideIndex = typeof slideIndex !== 'undefined' ? slideIndex : currentSlideIndex + delta; if (nextSlideIndex >= slides.length) { nextSlideIndex = 0; } if (nextSlideIndex < 0) { nextSlideIndex = slides.length - 1; } inSlide = $(slides[nextSlideIndex]); if (animationInProgress === true) { return; } // switch effect is quickly, no need to wait if (effect !== 'switch') { // when animation in progress no other animation occur animationInProgress = true; setTimeout(function () { animationInProgress = false; }, plugin.settings.duration) } // change slide with selected effect switch (effect) { case 'switch': changeSlideSwitch(outSlide, inSlide); break; case 'slide': changeSlideSlide(outSlide, inSlide, slideDirection); break; case 'fade': changeSlideFade(outSlide, inSlide); break; case 'slowdown': changeSlideSlowdown(outSlide, inSlide, slideDirection); break; } currentSlideIndex = nextSlideIndex; // switch marker if (plugin.settings.markers === 'on') { markers.removeClass('active'); $(markers.get(currentSlideIndex)).addClass('active'); } }; /** * switch effect */ var changeSlideSwitch = function (outSlide, inSlide) { inSlide.show().css({'left': 0}); outSlide.hide(); }; /** * slide effect */ var changeSlideSlide = function (outSlide, inSlide, slideDirection) { var unmovedPosition = {'left': 0}, duration = plugin.settings.duration; if (slideDirection !== -1) { inSlide.css(slideInPosition); inSlide.show(); outSlide.animate(slideOutPosition, duration); inSlide.animate(unmovedPosition, duration); } else { inSlide.css(slideOutPosition); inSlide.show(); outSlide.animate(slideInPosition, duration); inSlide.animate(unmovedPosition, duration); } }; /** * slowdown slide effect (custom easing 'doubleSqrt') */ var changeSlideSlowdown = function (outSlide, inSlide, slideDirection) { var unmovedPosition = {'left': 0}, options; options = { 'duration': plugin.settings.duration, 'easing': 'doubleSqrt' }; if (slideDirection !== -1) { inSlide.css(slideInPosition); inSlide.show(); outSlide.animate(slideOutPosition, options); inSlide.animate(unmovedPosition, options); } else { inSlide.css(slideOutPosition); inSlide.show(); outSlide.animate(slideInPosition, options); inSlide.animate(unmovedPosition, options); } }; /** * fade effect */ var changeSlideFade = function (outSlide, inSlide) { inSlide.fadeIn(plugin.settings.duration); outSlide.fadeOut(plugin.settings.duration); }; plugin.init(); }; $.fn.Carousel = function(options) { return this.each(function() { if (undefined == $(this).data('Carousel')) { var plugin = new $.Carousel(this, options); $(this).data('Carousel', plugin); } }); }; // easing effect for jquery animation $.easing.doubleSqrt = function(t, millisecondsSince, startValue, endValue, totalDuration) { var res = Math.sqrt(Math.sqrt(t)); return res; }; })(jQuery); $(window).ready(function(){ var allCarousels = $('[data-role=carousel], .carousel'); allCarousels.each(function (index, carousel) { var params = {}; $carousel = $(carousel); params.auto = $carousel.data('paramAuto'); params.period = $carousel.data('paramPeriod'); params.duration = $carousel.data('paramDuration'); params.effect = $carousel.data('paramEffect'); params.direction = $carousel.data('paramDirection'); params.markers = $carousel.data('paramMarkers'); params.arrows = $carousel.data('paramArrows'); params.stop = $carousel.data('paramStop'); $carousel.Carousel(params); }) });