Skip to content

Instantly share code, notes, and snippets.

@trinhtanloc789
Created November 1, 2019 12:40
Show Gist options
  • Save trinhtanloc789/3bdd8013da9a8a67f81076caa0418771 to your computer and use it in GitHub Desktop.
Save trinhtanloc789/3bdd8013da9a8a67f81076caa0418771 to your computer and use it in GitHub Desktop.
Swiper custom transition effect
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" style="background-image:url(https://picsum.photos/1920/1080?image=991)">
</div>
<div class="swiper-slide" style="background-image:url(https://picsum.photos/1920/1080?image=1081)">
</div>
<div class="swiper-slide" style="background-image:url(https://picsum.photos/1920/1080?image=1064)">
</div>
<div class="swiper-slide" style="background-image:url(https://picsum.photos/1920/1080?image=1000)">
</div>'
</div>
<div class="swiper-button-next swiper-button-white"></div>
<div class="swiper-button-prev swiper-button-white"></div>
</div>
<div class="copy">Tutorial available on <a target="_blank" href="https://medium.com/@arnost/creating-custom-slide-transitions-in-swiper-js-also-with-gsap-ac71f9badf53">Medium</a></div>
class SwiperDemo {
constructor() {
this.currentTransitionSpeed = 0;
this.init();
}
getTransitionSpeed() {
const transitionSpeed = this.currentTransitionSpeed;
// don't forget to reset the variable for future calls
this.currentTransitionSpeed = 0;
return transitionSpeed;
}
/*
A weird way to find this out but I've found no other.
Checks if the progress on the active slide is 1 or -1 which happens when swiper navigates to next/previous slide on click and keybord navigation.
If not then the slider is being dragged, so we get the right index by finding the startTranslate from touchEvents in array of transitions the swiper snaps to.
The startTranslate doesn't exist on initial load so we use the initialSlide index instead.
*/
getActiveIndexBeforeTransitionStart(swiper, slides) {
const isDragging = !Math.abs(slides[swiper.activeIndex].progress === 1);
if (isDragging) {
return swiper.slidesGrid.indexOf(
-swiper.touchEventsData.startTranslate || swiper.params.initialSlide
);
} else {
return swiper.activeIndex;
}
}
getDirection(animationProgress) {
if (animationProgress === 0) {
return "NONE";
} else if (animationProgress > 0) {
return "NEXT";
} else {
return "BACK";
}
}
progress(swiper, progress) {
/* 
if you need to change something for each progress
do it here (progress variable is always in range from 0 to 1) representing progress of the whole slider
*/
}
/*
this is a function for the setTransition swiper event. Can be used for setting the CSS transition duration on slides or wrapper. Sometimes called when the change is supposed to be animated, sometimes not called if the change should be immediate (e.g. dragging the slider)
*/
setTransition(swiper, transitionSpeed) {
this.currentTransitionSpeed = transitionSpeed;
// console.log("transition", transitionSpeed);
}
setTranslate(swiper, wrapperTranslate) {
const durationInSeconds = this.getTransitionSpeed() / 1000;
// convert slides object to plain array
const slides = Object.values(swiper.slides).slice(0, -1);
// get the index of the slide active before transition start (activeIndex changes halfway when dragging)
const originIndex = this.getActiveIndexBeforeTransitionStart(
swiper,
slides
);
// get information about animation progress from the active slide - the active slide's value is always -1 to 1.
/*
every slide has a progress attribute equal to the "distance" from the current active index.
*/
const animationProgress = slides[originIndex].progress;
// you can then get the drag direction like so:
const direction = this.getDirection(animationProgress);
// console.log(direction);
// do magic with each slide
slides.map((slide, index) => {
// to put the slides behind each other we have to set their CSS translate accordingly since by default they are arranged in line.
const offset = slide.swiperSlideOffset;
let x = -offset;
if (!swiper.params.virtualTranslate) x -= swiper.translate;
let y = 0;
if (!swiper.isHorizontal()) {
y = x;
x = 0;
}
TweenMax.set(slide, {
x,
y
});
// do our animation stuff!
const clip = (val, min, max) => Math.max(min, Math.min(val, max));
const ZOOM_FACTOR = 0.05;
const opacity = Math.max(1 - Math.abs(slide.progress), 0);
const clippedProgress = clip(slide.progress, -1, 1);
const scale = 1 - ZOOM_FACTOR * clippedProgress;
// you can do your CSS animation instead of using tweening.
TweenMax.to(slide, durationInSeconds, {
scale,
opacity
});
});
}
init() {
const that = this;
this.swiper = new Swiper(".swiper-container", {
// -----unrelated settings start -----
grabCursor: true,
keyboard: true,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
// -----unrelated settings end -----
speed: 1000,
watchSlidesProgress: true,
virtualTranslate: true,
effect: "myCustomTransition",
on: {
progress(progress) {
const swiper = this;
if (swiper.params.effect !== "myCustomTransition") return;
that.progress(swiper, progress);
},
setTransition(transition) {
const swiper = this;
if (swiper.params.effect !== "myCustomTransition") return;
that.setTransition(swiper, transition);
},
setTranslate(translate) {
const swiper = this;
if (swiper.params.effect !== "myCustomTransition") return;
that.setTranslate(swiper, translate);
}
}
});
}
}
const demo = new SwiperDemo();
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/js/swiper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
body {
background: #eee;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 14px;
color: #000;
background: #404449;
margin: 0;
padding: 0;
}
.swiper-container {
height: calc(100vh - 120px);
margin: 60px;
}
.swiper-slide {
overflow: hidden;
background-size: cover;
background-position: center;
transform-origin: center center;
}
.copy {
position: absolute;
bottom: 15px;
left: 0;
right: 0;
text-align: center;
color: white;
letter-spacing: 0.06em;
}
a {
color: white;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.4.6/css/swiper.min.css" rel="stylesheet" />

Swiper custom transition effect

Swiper custom slides transform effect. Ready for Swiper ver. 4. Vanilla js. Slider with beautiful transition/animation effect.

A Pen by Arnost Neurad on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment