/** * PgwSlideshow - Version 2.0 * * Copyright 2014, Jonathan M. Piat * http://pgwjs.com - http://pagawa.com * * Released under the GNU GPLv3 license - http://opensource.org/licenses/gpl-3.0 */ ;(function($){ $.fn.pgwSlideshow = function(options) { var defaults = { mainClassName : 'pgwSlideshow', transitionEffect : 'sliding', displayList : true, displayControls : true, touchControls : true, autoSlide : false, beforeSlide : false, afterSlide : false, maxHeight : null, adaptiveDuration : 200, transitionDuration : 500, intervalDuration : 3000 }; if (this.length == 0) { return this; } else if(this.length > 1) { this.each(function() { $(this).pgwSlideshow(options); }); return this; } var pgwSlideshow = this; pgwSlideshow.plugin = this; pgwSlideshow.config = {}; pgwSlideshow.data = []; pgwSlideshow.currentSlide = 0; pgwSlideshow.slideCount = 0; pgwSlideshow.resizeEvent = null; pgwSlideshow.intervalEvent = null; pgwSlideshow.touchFirstPosition = null; pgwSlideshow.touchListLastPosition = false; pgwSlideshow.window = $(window); // Init var init = function() { // Merge user options with the default configuration pgwSlideshow.config = $.extend({}, defaults, options); // Setup setup(); // Check list if (pgwSlideshow.config.displayList) { checkList(); } // Resize trigger pgwSlideshow.window.resize(function() { clearTimeout(pgwSlideshow.resizeEvent); pgwSlideshow.resizeEvent = setTimeout(function() { setSizeClass(); var maxHeight = pgwSlideshow.plugin.find('.ps-current > ul > li.elt_' + pgwSlideshow.currentSlide + ' img').height(); updateHeight(maxHeight); if (pgwSlideshow.config.displayList) { checkList(); checkSelectedItem(); } }, 100); }); // Activate interval if (pgwSlideshow.config.autoSlide) { activateInterval(); } return true; }; // Update the current height var updateHeight = function(height, animate) { // Check maxHeight if (pgwSlideshow.config.maxHeight) { if (height + pgwSlideshow.plugin.find('.ps-list').height() > pgwSlideshow.config.maxHeight) { height = pgwSlideshow.config.maxHeight - pgwSlideshow.plugin.find('.ps-list').height(); } } if (typeof pgwSlideshow.plugin.find('.ps-current').animate == 'function') { pgwSlideshow.plugin.find('.ps-current').stop().animate({ //height: height height: 'auto' }, pgwSlideshow.config.adaptiveDuration, function() { if (pgwSlideshow.config.maxHeight) { pgwSlideshow.plugin.find('.ps-current > ul > li img').css('max-height', height + 'px'); } }); } else { pgwSlideshow.plugin.find('.ps-current').css('height', height); if (pgwSlideshow.config.maxHeight) { pgwSlideshow.plugin.find('.ps-current > ul > li img').css('max-height', height + 'px'); } } return true; }; // Set list width var setListWidth = function() { var listWidth = 0; // The plugin must be visible for a correct calculation pgwSlideshow.plugin.show(); pgwSlideshow.plugin.find('.ps-list > ul > li').show().each(function() { listWidth += $(this).width(); }); pgwSlideshow.plugin.find('.ps-list > ul').width(listWidth); return true; } // Set size class var setSizeClass = function() { if (pgwSlideshow.plugin.width() <= 480) { pgwSlideshow.plugin.addClass('narrow').removeClass('wide'); } else { pgwSlideshow.plugin.addClass('wide').removeClass('narrow'); } return true; }; // Setup var setup = function() { // Create container pgwSlideshow.plugin.removeClass('pgwSlideshow').removeClass(pgwSlideshow.config.mainClassName); pgwSlideshow.plugin.wrap('
'); pgwSlideshow.plugin = pgwSlideshow.plugin.parent(); pgwSlideshow.plugin.wrap('
'); pgwSlideshow.plugin = pgwSlideshow.plugin.parent(); pgwSlideshow.plugin.prepend('
'); pgwSlideshow.slideCount = pgwSlideshow.plugin.find('.ps-list > ul > li').length; if (pgwSlideshow.slideCount == 0) { throw new Error('pgwSlideshow - No slider item has been found'); return false; } // Prev / Next icons if (pgwSlideshow.slideCount > 1) { // Slider controls if (pgwSlideshow.config.displayControls) { pgwSlideshow.plugin.find('.ps-current').prepend(''); pgwSlideshow.plugin.find('.ps-current').append(''); pgwSlideshow.plugin.find('.ps-current .ps-prev').click(function() { pgwSlideshow.previousSlide(); }); pgwSlideshow.plugin.find('.ps-current .ps-next').click(function() { pgwSlideshow.nextSlide(); }); } // Touch controls for current image if (pgwSlideshow.config.touchControls) { pgwSlideshow.plugin.find('.ps-current').on('touchstart', function(e) { try { if (e.originalEvent.touches[0].clientX && pgwSlideshow.touchFirstPosition == null) { pgwSlideshow.touchFirstPosition = e.originalEvent.touches[0].clientX; } } catch(e) { pgwSlideshow.touchFirstPosition = null; } }); pgwSlideshow.plugin.find('.ps-current').on('touchmove', function(e) { try { if (e.originalEvent.touches[0].clientX && pgwSlideshow.touchFirstPosition != null) { if (e.originalEvent.touches[0].clientX > (pgwSlideshow.touchFirstPosition + 50)) { pgwSlideshow.touchFirstPosition = null; pgwSlideshow.previousSlide(); } else if (e.originalEvent.touches[0].clientX < (pgwSlideshow.touchFirstPosition - 50)) { pgwSlideshow.touchFirstPosition = null; pgwSlideshow.nextSlide(); } } } catch(e) { pgwSlideshow.touchFirstPosition = null; } }); pgwSlideshow.plugin.find('.ps-current').on('touchend', function(e) { pgwSlideshow.touchFirstPosition = null; }); } } // Get slideshow elements var elementId = 1; pgwSlideshow.plugin.find('.ps-list > ul > li').each(function() { var element = getElement($(this)); element.id = elementId; pgwSlideshow.data.push(element); $(this).addClass('elt_' + element.id); $(this).wrapInner(''); // Set element in the current list var currentElement = $('
  • '); if (element.image) { currentElement.html('' + (element.title ? element.title : '') + ''); } else if (element.thumbnail) { if(element.imgvideo){ //currentElement.html(''); currentElement.html('
    '); }else{ currentElement.html('' + (element.title ? element.title : '') + ''); } } else if (element.video) { currentElement.html(''); } if (element.link) { currentElement.html('' + currentElement.html() + ''); } pgwSlideshow.plugin.find('.ps-current > ul').append(currentElement); $(this).css('cursor', 'pointer').click(function(event) { event.preventDefault(); displayElement(element.id); }); elementId++; }); // Set list elements if (pgwSlideshow.config.displayList) { setListWidth(); pgwSlideshow.plugin.find('.ps-list').prepend(''); pgwSlideshow.plugin.find('.ps-list').append(''); pgwSlideshow.plugin.find('.ps-list').show(); } else { pgwSlideshow.plugin.find('.ps-list').hide(); } // Attach slide events if (pgwSlideshow.config.autoSlide) { pgwSlideshow.plugin.on('mouseenter', function() { clearInterval(pgwSlideshow.intervalEvent); pgwSlideshow.intervalEvent = null; }).on('mouseleave', function() { activateInterval(); }); } // Disable current elements pgwSlideshow.plugin.find('.ps-current > ul > li').hide(); // Display the first element displayElement(1); // Set the first height pgwSlideshow.plugin.find('.ps-current > ul > li.elt_1 img').on('load', function() { setSizeClass(); var maxHeight = pgwSlideshow.plugin.find('.ps-current > ul > li.elt_1 img').height(); updateHeight(maxHeight); }); // Enable slideshow setSizeClass(); pgwSlideshow.plugin.show(); return true; }; // Get element var getElement = function(obj) { var element = {}; // Get link var elementLink = obj.find('a').attr('href'); if ((typeof elementLink != 'undefined') && (elementLink != '')) { element.link = elementLink; var elementLinkTarget = obj.find('a').attr('target'); if ((typeof elementLinkTarget != 'undefined') && (elementLinkTarget != '')) { element.linkTarget = elementLinkTarget; } } // Get image var elementThumbnail = obj.find('img').attr('src'); if ((typeof elementThumbnail != 'undefined') && (elementThumbnail != '')) { element.thumbnail = elementThumbnail; var elementImgVideo = obj.find('img').attr('video-src'); if ((typeof elementImgVideo != 'undefined') && (elementImgVideo != '')) { element.imgvideo = elementImgVideo; } } var elementImage = obj.find('img').attr('data-large-src'); if ((typeof elementImage != 'undefined') && (elementImage != '')) { element.image = elementImage; } var elementVideo = obj.find('video source').attr('src'); if ((typeof elementVideo != 'undefined') && (elementVideo != '')) { element.video = elementVideo; } // Get title var elementTitle = obj.find('img').attr('alt'); if ((typeof elementTitle != 'undefined') && (elementTitle != '')) { element.title = elementTitle; } // Get description var elementDescription = obj.find('img').attr('data-description'); if ((typeof elementDescription != 'undefined') && (elementDescription != '')) { element.description = elementDescription; } return element; }; // Finish element var finishElement = function(element) { // Element caption var elementText = ''; if (element.title) { elementText += '' + element.title + ''; } if (element.description) { if (elementText != '') elementText += '
    '; elementText += element.description; } if (elementText != '') { if (element.link) { elementText = '' + elementText + ''; } if (typeof pgwSlideshow.plugin.find('.ps-caption').fadeIn == 'function') { pgwSlideshow.plugin.find('.ps-caption').html(elementText); pgwSlideshow.plugin.find('.ps-caption').fadeIn(pgwSlideshow.config.transitionDuration / 2); } else { pgwSlideshow.plugin.find('.ps-caption').html(elementText); pgwSlideshow.plugin.find('.ps-caption').show(); } } // Update list items pgwSlideshow.plugin.find('.ps-list > ul > li .ps-item').removeClass('ps-selected'); pgwSlideshow.plugin.find('.ps-list > ul > li.elt_' + element.id + ' .ps-item').addClass('ps-selected'); // Check selected item if (pgwSlideshow.config.displayList) { checkList(); checkSelectedItem(); } // Slideshow controls if (pgwSlideshow.config.displayControls) { if (typeof pgwSlideshow.plugin.find('.ps-current > .ps-prev').fadeIn == 'function') { pgwSlideshow.plugin.find('.ps-current > .ps-prev, .ps-current > .ps-next').fadeIn(pgwSlideshow.config.transitionDuration / 2); } else { pgwSlideshow.plugin.find('.ps-current > .ps-prev, .ps-current > .ps-next').show(); } } // After slide if (typeof pgwSlideshow.config.afterSlide == 'function') { pgwSlideshow.config.afterSlide(element.id); } // Set the container height //var maxHeight = pgwSlideshow.plugin.find('.ps-current .elt_' + element.id + ' img').height(); var maxHeight; if(element.video){ maxHeight = pgwSlideshow.plugin.find('.ps-current .elt_' + element.id + ' video').height(); maxHeight += 15; }else{ maxHeight = pgwSlideshow.plugin.find('.ps-current .elt_' + element.id + ' img').height(); } updateHeight(maxHeight, true); return true; } // Fade an element var fadeElement = function(element) { var elementContainer = pgwSlideshow.plugin.find('.ps-current > ul'); elementContainer.find('li').not('.elt_' + pgwSlideshow.currentSlide).not('.elt_' + element.id).each(function(){ if (typeof $(this).stop == 'function') { $(this).stop(); } $(this).css('position', '').css('z-index', 1).hide(); }); // Current element if (pgwSlideshow.currentSlide > 0) { var currentElement = elementContainer.find('.elt_' + pgwSlideshow.currentSlide); if (typeof currentElement.animate != 'function') { currentElement.animate = function(css, duration, callback) { currentElement.css(css); if (callback) { callback(); } }; } if (typeof currentElement.stop == 'function') { currentElement.stop(); } currentElement.css('position', 'absolute').animate({ opacity : 0, }, pgwSlideshow.config.transitionDuration, function() { currentElement.css('position', '').css('z-index', 1).hide(); }); } // Update current id pgwSlideshow.currentSlide = element.id; // Next element var nextElement = elementContainer.find('.elt_' + element.id); if (typeof nextElement.animate != 'function') { nextElement.animate = function(css, duration, callback) { nextElement.css(css); if (callback) { callback(); } }; } if (typeof nextElement.stop == 'function') { nextElement.stop(); } nextElement.css('position', 'absolute').show().animate({ opacity : 1, }, pgwSlideshow.config.transitionDuration, function() { nextElement.css('position', '').css('z-index', 2).css('display', 'block'); finishElement(element); }); return true; } // Slide an element var slideElement = function(element, direction) { var elementContainer = pgwSlideshow.plugin.find('.ps-current > ul'); if (typeof direction == 'undefined') { direction = 'left'; } if (pgwSlideshow.currentSlide == 0) { elementContainer.find('.elt_1').css({ position : '', left : '', opacity : 1, 'z-index' : 2 }).show(); pgwSlideshow.plugin.find('.ps-list > li.elt_1').css('opacity', '1'); finishElement(element); } else { if (pgwSlideshow.transitionInProgress) { return false; } pgwSlideshow.transitionInProgress = true; // Get direction details var elementWidth = elementContainer.width(); if (direction == 'left') { var elementDest = -elementWidth; var nextOrigin = elementWidth; } else { var elementDest = elementWidth; var nextOrigin = -elementWidth; } var currentElement = elementContainer.find('.elt_' + pgwSlideshow.currentSlide); if (typeof currentElement.animate != 'function') { currentElement.animate = function(css, duration, callback) { currentElement.css(css); if (callback) { callback(); } }; } currentElement.css('position', 'absolute').animate({ left : elementDest, }, pgwSlideshow.config.transitionDuration, function() { currentElement.css('position', '').css('z-index', 1).css('left', '').css('opacity', 0).hide(); }); // Next element var nextElement = elementContainer.find('.elt_' + element.id); if (typeof nextElement.animate != 'function') { nextElement.animate = function(css, duration, callback) { nextElement.css(css); if (callback) { callback(); } }; } nextElement.css('position', 'absolute').css('left', nextOrigin).css('opacity', 1).show().animate({ left : 0, }, pgwSlideshow.config.transitionDuration, function() { nextElement.css('position', '').css('left', '').css('z-index', 2).show(); pgwSlideshow.transitionInProgress = false; finishElement(element); }); } // Update current id pgwSlideshow.currentSlide = element.id; return true; } // Display current element var displayElement = function(elementId, apiController, direction) { if (elementId == pgwSlideshow.currentSlide) { return false; } var element = pgwSlideshow.data[elementId - 1]; if (typeof element == 'undefined') { throw new Error('pgwSlideshow - The element ' + elementId + ' is undefined'); return false; } if (typeof direction == 'undefined') { direction = 'left'; } // Before slide if (typeof pgwSlideshow.config.beforeSlide == 'function') { pgwSlideshow.config.beforeSlide(elementId); } if (typeof pgwSlideshow.plugin.find('.ps-caption').fadeOut == 'function') { pgwSlideshow.plugin.find('.ps-caption, .ps-prev, .ps-next').fadeOut(pgwSlideshow.config.transitionDuration / 2); } else { pgwSlideshow.plugin.find('.ps-caption, .ps-prev, .ps-next').hide(); } // Choose the transition effect if (pgwSlideshow.config.transitionEffect == 'sliding') { slideElement(element, direction); } else { fadeElement(element); } // Reset interval to avoid a half interval after an API control if (typeof apiController != 'undefined' && pgwSlideshow.config.autoSlide) { activateInterval(); } return true; }; // Activate interval var activateInterval = function() { clearInterval(pgwSlideshow.intervalEvent); if (pgwSlideshow.slideCount > 1 && pgwSlideshow.config.autoSlide) { pgwSlideshow.intervalEvent = setInterval(function() { if (pgwSlideshow.currentSlide + 1 <= pgwSlideshow.slideCount) { var nextItem = pgwSlideshow.currentSlide + 1; } else { var nextItem = 1; } displayElement(nextItem); }, pgwSlideshow.config.intervalDuration); } return true; }; // Check slide list var checkList = function() { if (! pgwSlideshow.config.displayList) return false; // Refresh list width setListWidth(); var containerObject = pgwSlideshow.plugin.find('.ps-list'); var containerWidth = containerObject.width(); var listObject = pgwSlideshow.plugin.find('.ps-list > ul'); var listWidth = listObject.width(); if (listWidth > containerWidth) { listObject.css('margin', '0 45px'); var marginLeft = parseInt(listObject.css('margin-left')); var marginRight = parseInt(listObject.css('margin-right')); containerWidth -= (marginLeft + marginRight); // Left button containerObject.find('.ps-prev').show().unbind('click').click(function() { var oldPosition = parseInt(listObject.css('left')); var newPosition = oldPosition + containerWidth; if (oldPosition == 0) { newPosition = -(listWidth - containerWidth); } else if (newPosition > 0) { newPosition = 0; } if (typeof listObject.animate == 'function') { listObject.animate({ left: newPosition }, pgwSlideshow.config.transitionDuration); } else { listObject.css('left', newPosition); } }); // Right button containerObject.find('.ps-next').show().unbind('click').click(function() { var oldPosition = parseInt(listObject.css('left')); var newPosition = oldPosition - containerWidth; var maxPosition = -(listWidth - containerWidth); if (oldPosition == maxPosition) { newPosition = 0; } else if (newPosition < maxPosition) { newPosition = maxPosition; } if (typeof listObject.animate == 'function') { listObject.animate({ left: newPosition }, pgwSlideshow.config.transitionDuration); } else { listObject.css('left', newPosition); } }); // Touch controls for the list if (pgwSlideshow.config.touchControls) { pgwSlideshow.plugin.find('.ps-list > ul').on('touchmove', function(e) { try { if (e.originalEvent.touches[0].clientX) { var lastPosition = (pgwSlideshow.touchListLastPosition == false ? 0 : pgwSlideshow.touchListLastPosition); nbPixels = (pgwSlideshow.touchListLastPosition == false ? 1 : Math.abs(lastPosition - e.originalEvent.touches[0].clientX)); pgwSlideshow.touchListLastPosition = e.originalEvent.touches[0].clientX; var touchDirection = ''; if (lastPosition > e.originalEvent.touches[0].clientX) { touchDirection = 'left'; } else if (lastPosition < e.originalEvent.touches[0].clientX) { touchDirection = 'right'; } } var oldPosition = parseInt(listObject.css('left')); if (touchDirection == 'left') { var containerWidth = containerObject.width(); var listWidth = listObject.width(); var marginLeft = parseInt(listObject.css('margin-left')); var marginRight = parseInt(listObject.css('margin-right')); containerWidth -= (marginLeft + marginRight); var maxPosition = -(listWidth - containerWidth); var newPosition = oldPosition - nbPixels; if (newPosition > maxPosition) { listObject.css('left', newPosition); } } else if (touchDirection == 'right') { var newPosition = oldPosition + nbPixels; if (newPosition < 0) { listObject.css('left', newPosition); } else { listObject.css('left', 0); } } } catch(e) { pgwSlideshow.touchListLastPosition = false; } }); pgwSlideshow.plugin.find('.ps-list > ul').on('touchend', function(e) { pgwSlideshow.touchListLastPosition = false; }); } } else { var marginLeft = parseInt((containerWidth - listWidth) / 2); listObject.css('left', 0).css('margin-left', marginLeft); containerObject.find('.ps-prev').hide(); containerObject.find('.ps-next').hide(); pgwSlideshow.plugin.find('.ps-list > ul').unbind('touchstart touchmove touchend'); } return true; }; // Check the visibility of the selected item var checkSelectedItem = function() { var containerWidth = pgwSlideshow.plugin.find('.ps-list').width(); var listObject = pgwSlideshow.plugin.find('.ps-list > ul'); var listWidth = listObject.width(); var marginLeft = parseInt(listObject.css('margin-left')); var marginRight = parseInt(listObject.css('margin-right')); containerWidth -= (marginLeft + marginRight); var visibleZoneStart = Math.abs(parseInt(listObject.css('left'))); var visibleZoneEnd = visibleZoneStart + containerWidth; var elementZoneStart = pgwSlideshow.plugin.find('.ps-list .ps-selected').position().left; var elementZoneEnd = elementZoneStart + pgwSlideshow.plugin.find('.ps-list .ps-selected').width(); if ((elementZoneStart < visibleZoneStart) || (elementZoneEnd > visibleZoneEnd) || (listWidth > containerWidth && visibleZoneEnd > elementZoneEnd)) { var maxPosition = -(listWidth - containerWidth); if (-elementZoneStart < maxPosition) { listObject.css('left', maxPosition); } else { listObject.css('left', -elementZoneStart); } } return true; }; // Start auto slide pgwSlideshow.startSlide = function() { pgwSlideshow.config.autoSlide = true; activateInterval(); return true; }; // Stop auto slide pgwSlideshow.stopSlide = function() { pgwSlideshow.config.autoSlide = false; clearInterval(pgwSlideshow.intervalEvent); return true; }; // Get current slide pgwSlideshow.getCurrentSlide = function() { return pgwSlideshow.currentSlide; }; // Get slide count pgwSlideshow.getSlideCount = function() { return pgwSlideshow.slideCount; }; // Display slide pgwSlideshow.displaySlide = function(itemId) { displayElement(itemId, true); return true; }; // Next slide pgwSlideshow.nextSlide = function() { if (pgwSlideshow.currentSlide + 1 <= pgwSlideshow.slideCount) { var nextItem = pgwSlideshow.currentSlide + 1; } else { var nextItem = 1; } displayElement(nextItem, true, 'left'); return true; }; // Previous slide pgwSlideshow.previousSlide = function() { if (pgwSlideshow.currentSlide - 1 >= 1) { var previousItem = pgwSlideshow.currentSlide - 1; } else { var previousItem = pgwSlideshow.slideCount; } displayElement(previousItem, true, 'right'); return true; }; // Destroy slider pgwSlideshow.destroy = function(soft) { clearInterval(pgwSlideshow.intervalEvent); if (typeof soft != 'undefined') { pgwSlideshow.plugin.find('.ps-list > ul > li').each(function() { $(this).attr('style', null).removeClass().unbind('click'); $(this).html($(this).find('span').html()); }); pgwSlideshow.plugin.find('.ps-current').remove(); pgwSlideshow.plugin.find('.ps-list').find('.ps-prev, .ps-next').remove(); pgwSlideshow.plugin.find('.ps-list > ul').addClass(pgwSlideshow.config.mainClassName).attr('style', ''); pgwSlideshow.plugin.find('.ps-list > ul').unwrap().unwrap(); pgwSlideshow.hide(); } else { pgwSlideshow.parent().parent().remove(); } pgwSlideshow.plugin = null; pgwSlideshow.data = []; pgwSlideshow.config = {}; pgwSlideshow.currentSlide = 0; pgwSlideshow.slideCount = 0; pgwSlideshow.resizeEvent = null; pgwSlideshow.intervalEvent = null; pgwSlideshow.touchFirstPosition = null; pgwSlideshow.window = null; return true; }; // Reload slider pgwSlideshow.reload = function(newOptions) { pgwSlideshow.destroy(true); pgwSlideshow = this; pgwSlideshow.plugin = this; pgwSlideshow.window = $(window); pgwSlideshow.plugin.show(); // Merge new options with the default configuration pgwSlideshow.config = $.extend({}, defaults, newOptions); // Setup setup(); // Resize listener pgwSlideshow.window.resize(function() { clearTimeout(pgwSlideshow.resizeEvent); pgwSlideshow.resizeEvent = setTimeout(function() { setSizeClass(); var maxHeight = pgwSlideshow.plugin.find('.ps-current > ul > li.elt_' + pgwSlideshow.currentSlide + ' img').css('max-height', '').height(); updateHeight(maxHeight); if (pgwSlideshow.config.displayList) { checkList(); checkSelectedItem(); } }, 100); }); // Activate interval if (pgwSlideshow.config.autoSlide) { activateInterval(); } return true; }; // Slideshow initialization init(); return this; } })(window.Zepto || window.jQuery);