Parallax Image Slider With jQuery And Swiper.js
File Size: | 10.4 KB |
---|---|
Views Total: | 5307 |
Last Update: | |
Publish Date: | |
Official Website: | Go to website |
License: | MIT |

This project makes use of jQuery and Swiper.js to create a modern, mobile-friendly, multi-slide carousel slider with a pretty parallax scrolling effect when transitioning between images.
How to use it:
1. Load the necessary jQuery and Swiper.js libraries in the document.
<link rel="stylesheet" href="/path/to/cdn/swiper.min.css" /> <script src="/path/to/cdn/jquery.min.js"></script> <script src="/path/to/cdn/swiper.min.js"></script>
2. Add images to the slider.
<div class="multi-px-slider loading"> <!-- Left Slider --> <div class="swiper-container lg-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="mps-slide"> <div class="mps-img img-lg"><img data-src="https://source.unsplash.com/TWCSYLJMoVc/1280x960" alt="" class="swiper-lazy object-fit"></div> <div class="swiper-lazy-preloader"></div> </div> </div> <div class="swiper-slide"> <div class="mps-slide"> <div class="mps-img img-lg"><img data-src="https://source.unsplash.com/yHaburAEFo4/1280x960" alt="" class="swiper-lazy object-fit"></div> <div class="swiper-lazy-preloader"></div> </div> </div> <div class="swiper-slide"> <div class="mps-slide"> <div class="mps-img img-lg"><img data-src="https://source.unsplash.com/ihzhMA2-l4Q/1280x960" alt="" class="swiper-lazy object-fit"></div> <div class="swiper-lazy-preloader"></div> </div> </div> </div> <div class="pattern-2" data-swiper-parallax="-50%"></div> </div> <!-- Right Slider --> <div class="swiper-container sm-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <div class="mps-slide"> <div class="mps-img img-sm"><img data-src="https://source.unsplash.com/Dz5j0QKVUGY/1280x960" alt="" class="swiper-lazy object-fit"></div> <div class="swiper-lazy-preloader"></div> </div> </div> <div class="swiper-slide"> <div class="mps-slide"> <div class="mps-img img-sm"><img data-src="https://source.unsplash.com/HGa7kULkQWY/1280x960" alt="" class="swiper-lazy object-fit"></div> <div class="swiper-lazy-preloader"></div> </div> </div> <div class="swiper-slide"> <div class="mps-slide"> <div class="mps-img img-sm"><img data-src="https://source.unsplash.com/RRSXLJPbqEQ/1280x960" alt="" class="swiper-lazy object-fit"></div> <div class="swiper-lazy-preloader"></div> </div> </div> </div> </div> <!-- Controls --> <button type="button" class="mps-arrow mps-prev" aria-label="Previous">Previous</button> <button type="button" class="mps-arrow mps-next" aria-label="Next">Next</button> <!-- Curtain --> <div class="curtain"></div> </div>
3. The necessary CSS for the slider..
.object-fit { width: 100%; height: 100%; object-fit: cover; } /* plugin overrides */ .swiper-wrapper { height: 100%; } .swiper-slide { backface-visibility: hidden; overflow: hidden; } /* slider */ .multi-px-slider { height: 480px; position: relative; overflow: hidden; display: flex; transition: opacity .6s ease; } .multi-px-slider.loading { visibility: hidden; opacity: 0; } .mps-slide { position: relative; width: 100%; height: 100%; } .mps-img { height: 100%; overflow: hidden; } /* Large slider */ .lg-slider { width: 60%; } /* Small slider */ .sm-slider { width: 40%; } /* Arrows */ .mps-arrow { position: absolute; top: 50%; z-index: 3; transform: translateY(-50%); } .mps-prev { left: 1.5em; } .mps-next { right: 1.5em; } /* curtain */ .curtain { position: absolute; top: 0; left: 60%; z-index: 2; width: 40%; height: 100%; background-color: rgba(0,0,0,.5); } .is-animating .curtain { animation: curtain 3.75s ease-in-out; } @keyframes curtain { 0% { left: 60%; width: 40%; } 46% { left: 0%; width: 60%; } 53% { left: 0%; width: 60%; } 100% { left: 60%; width: 40%; } } .pattern-2 { background: url(./images/pattern-2.png) repeat-x; width: 330%; height: 80px; position: absolute; bottom: 0; left: 0; z-index: 2; opacity: .3; }
4. Enable the parallax slider.
// Params const mpSlider = document.querySelector('.multi-px-slider'); let interleaveOffset = 0.5; // init small slider const smallSlider = new Swiper('.sm-slider', { touchRatio: 0, // disable swipe loop: true, slidesPerView: 'auto', preloadImages: false, lazy: { loadPrevNext: true, loadPrevNextAmount: 2, }, watchSlidesProgress: true, watchSlidesVisibility: true, on: { init: function(){ let swiper = this; }, lazyImageReady: function(){ let swiper = this; setTimeout(function() { swiper.update(); }, 500); }, progress: function(){ let swiper = this; for (let i = 0; i < swiper.slides.length; i++) { let slideProgress = swiper.slides[i].progress, innerOffset = swiper.width * interleaveOffset, innerTranslate = slideProgress * innerOffset; swiper.slides[i].querySelector(".img-sm").style.transform = "translateX(" + innerTranslate + "px)"; } }, touchStart: function() { let swiper = this; for (let i = 0; i < swiper.slides.length; i++) { swiper.slides[i].style.transition = ""; } }, setTransition: function(speed) { let swiper = this; for (let i = 0; i < swiper.slides.length; i++) { swiper.slides[i].style.transition = speed + "ms"; swiper.slides[i].querySelector(".img-sm").style.transition = speed + "ms"; } } } }); // init large slider const largeSlider = new Swiper('.lg-slider', { parallax: true, loop: true, speed: 2000, slidesPerView: 'auto', preloadImages: false, lazy: { loadPrevNext: true, loadPrevNextAmount: 2, }, watchSlidesProgress: true, watchSlidesVisibility: true, touchEventsTarget: 'wrapper', controller: { control: smallSlider }, on: { init: function(){ let swiper = this; }, lazyImageReady: function(){ let swiper = this; setTimeout(function() { swiper.update(); mpSlider.classList.remove('loading'); }, 500); }, progress: function(){ let swiper = this; for (let i = 0; i < swiper.slides.length; i++) { let slideProgress = swiper.slides[i].progress, innerOffset = swiper.width * interleaveOffset, innerTranslate = slideProgress * innerOffset; swiper.slides[i].querySelector(".img-lg").style.transform = "translateX(" + innerTranslate + "px)"; } }, touchStart: function() { let swiper = this; for (let i = 0; i < swiper.slides.length; i++) { swiper.slides[i].style.transition = ""; } }, setTransition: function(speed) { let swiper = this; for (let i = 0; i < swiper.slides.length; i++) { swiper.slides[i].style.transition = speed + "ms"; swiper.slides[i].querySelector(".img-lg").style.transition = speed + "ms"; } } } }); // Set up animations let slideDelay = 2000; let $mpsArrow = $('.mps-arrow'); function runAnimation() { mpSlider.classList.add('is-animating'); } function endAnimation() { mpSlider.classList.remove('is-animating'); } // custom arrows $mpsArrow.each((i, el) => { const _this = $(el); _this.on('click', function() { // disable arrows $mpsArrow.prop('disabled', true); // run animation runAnimation(); // go to prev/next slide if (_this.hasClass('mps-prev')) { setTimeout(() => { largeSlider.slidePrev(); }, slideDelay) } else if (_this.hasClass('mps-next')) { setTimeout(() => { largeSlider.slideNext(); }, slideDelay) } // detect animation end const curtain = document.querySelector('.curtain'); curtain.addEventListener('animationend', () => { // re-enable arrows $mpsArrow.prop('disabled', false); // end animation endAnimation(); }); }) }) // check if slider is in viewport? let mpsInViewport = true; if (mpsInViewport) { $(document).off('keyup').on('keyup', function(e) { if (e.keyCode == '37') { $('.mps-prev').trigger('click'); } else if (e.keyCode == '39') { $('.mps-next').trigger('click'); } }); }
This awesome jQuery plugin is developed by EmDashVee. For more Advanced Usages, please check the demo page or visit the official website.