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.










