Swiperってデフォルトで色々なスライドエフェクトがついていて、とっても便利です。
しかし今回はあえて、標準装備されていないスライドエフェクトをカスタマイズしてみました。
何かの参考になれば嬉しいです。
ここで使っているswiperのバージョンは4.5.0です。
swiperのバージョンによってはオプションの書き方が違うので、注意してください。
前後のスライドが縮小されて表示
言葉では上手く説明できないので、以下を確認してみてください。
See the Pen swiper custom slider1 by takblog (@blanks-site) on CodePen.
最近webサイトを制作した際に作ったものを簡単にしてみました。
作ったコードを見れば大したことないのですが、結構悩んで作りました。
javascript
const slides = document.getElementsByClassName("swiper-slide");
const mySwiper = new Swiper('.swiper-container', {
speed: 1000,
autoplay:{
delay:2000
},
centeredSlides:true,
slidesPerView:"auto",
loop:true,
loopedSlides:slides.length
});
mySwiper.on("autoplayStop",()=>{
mySwiper.autoplay.start();
});
css
.swiper-slide {
width: 300px;
}
.swiper-slide .slide-inner {
opacity: 0;
transition: 1.5s all ease;
width: 100px;
margin: 30px auto 0;
position: relative;
z-index: 1;
}
.swiper-slide.swiper-slide-prev .slide-inner, .swiper-slide.swiper-slide-duplicate-prev .slide-inner, .swiper-slide.swiper-slide-next .slide-inner, .swiper-slide.swiper-slide-duplicate-next .slide-inner {
opacity: .5;
width: 200px;
z-index: 2;
}
.swiper-slide.swiper-slide-prev .slide-inner, .swiper-slide.swiper-slide-duplicate-prev .slide-inner {
-webkit-transform: translateX(150px);
transform: translateX(150px);
}
.swiper-slide.swiper-slide-next .slide-inner, .swiper-slide.swiper-slide-duplicate-next .slide-inner {
-webkit-transform: translateX(-150px);
transform: translateX(-150px);
}
.swiper-slide.swiper-slide-active .slide-inner, .swiper-slide.swiper-slide-duplicate-active .slide-inner {
opacity: 1;
width: 300px;
z-index: 3;
margin: 0;
}
jsとcssは上記のような感じで、そこまで記述は長くないです。
現状、スライドが固定幅の時にしか使用できないので、もう少しブラッシュアップして、可変でも使用できるようなものになればいいかなと思ってます。
それぞれのwindow幅で、スライド幅を変更させるようにしてレスポンシブには対応させてください。
css の transition-duration と swiper の speed は
transition-duration >= speed
の関係のほうがいい感じに動きます。
最初はネガティブマージンで調整したのですが、ネガティブマージンで調整するとスライドがずれてしまったので、transformで前後のスライドをずらしています。
タイル状に変化するスライド
早速制作物を確認ください。
See the Pen swiper custom slider2 by takblog (@blanks-site) on CodePen.
これもjsが大変というよりも、cssをどのように活用するかという点で大変でした。
以下がコードになります。
javascript
const slides = document.getElementsByClassName("swiper-slide");
const slideInners = document.getElementsByClassName("slide-inner");
const $durationTime = 700;
const $delayTime = 250;
const mySwiper = new Swiper('.swiper-container', {
speed: 0,
effect:"fade",
loop:true,
speed:$durationTime + $delayTime*3,
autoplay:true
});
for( let i = 0; i< slideInners.length ; i++ ){
const imgsrc = slideInners[i].getElementsByClassName("slide-img")[0].getAttribute("src");
const span = slideInners[i].getElementsByTagName("span");
for( let n = 0; n < span.length; n++ ){
span[n].style.backgroundImage = `url(${imgsrc})`;
}
}
mySwiper.on("autoplayStop",()=>{
mySwiper.autoplay.start();
});
mySwiper.on("slideNextTransitionStart",()=>{
mySwiper.slides[mySwiper.activeIndex].style.opacity = 1;
mySwiper.slides[mySwiper.previousIndex].style.opacity = 1;
mySwiper.slides[mySwiper.activeIndex].classList.add("nextChange");
mySwiper.slides[mySwiper.previousIndex].classList.add("nextChange");
});
mySwiper.on("slideNextTransitionEnd",()=>{
mySwiper.slides[mySwiper.activeIndex].classList.remove("nextChange");
mySwiper.slides[mySwiper.previousIndex].classList.remove("nextChange");
});
mySwiper.on("slidePrevTransitionStart",()=>{
mySwiper.slides[mySwiper.activeIndex].style.opacity = 1;
mySwiper.slides[mySwiper.previousIndex].style.opacity = 1;
mySwiper.slides[mySwiper.activeIndex].classList.add("prevChange");
mySwiper.slides[mySwiper.previousIndex].classList.add("prevChange");
});
mySwiper.on("slidePrevTransitionEnd",()=>{
mySwiper.slides[mySwiper.activeIndex].classList.remove("prevChange");
mySwiper.slides[mySwiper.previousIndex].classList.remove("prevChange");
});
css
lide.swiper-slide-duplicate-active .slide-inner > span {
opacity: 1;
}
.swiper-slide.prevChange .slide-inner > span.box4 {
transition-delay: 0s;
}
.swiper-slide.prevChange .slide-inner > span.box3 {
transition-delay: 0.25s;
}
.swiper-slide.prevChange .slide-inner > span.box2 {
transition-delay: 0.5s;
}
.swiper-slide.prevChange .slide-inner > span.box1 {
transition-delay: 0.75s;
}
.swiper-slide.nextChange .slide-inner > span.box1 {
transition-delay: 0s;
}
.swiper-slide.nextChange .slide-inner > span.box2 {
transition-delay: 0.25s;
}
.swiper-slide.nextChange .slide-inner > span.box3 {
transition-delay: 0.5s;
}
.swiper-slide.nextChange .slide-inner > span.box4 {
transition-delay: 0.75s;
}
.slide-inner {
position: relative;
}
.slide-inner img {
opacity: 0;
}
.slide-inner > span {
display: block;
width: 50%;
height: 50%;
position: absolute;
background-repeat: no-repeat;
background-size: 200% 200%;
opacity: 0;
transition-duration: 0.7s;
transition-property: opacity;
transition-timing-function: ease;
}
.slide-inner > span.box1 {
top: 0;
left: 0;
background-position: left top;
}
.slide-inner > span.box2 {
top: 0;
right: 0;
background-position: right top;
}
.slide-inner > span.box3 {
bottom: 0;
right: 0;
background-position: right bottom;
}
.slide-inner > span.box4 {
bottom: 0;
left: 0;
background-position: left bottom;
}
html
<div id="wrapper">
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div class="slide-inner"><img class="slide-img" src="https://takblog.site/wp-content/themes/takblog/assets/img/blanks/post19_1.jpg" alt=""/><span class="box1"></span><span class="box2"></span><span class="box3"></span><span class="box4"></span>
</div>
</div>
</div>
</div>
</div>
画像として表示しているのはimgタグではなく、slide-inner要素の中にあるspanタグに設定された背景画像です。
jsの13~19行目でslide-inner内のslide-imgのクラスがついたimgタグのsrcをspanタグの背景画像に設定させています。
box1~box4のspanタグがそれぞれ、左上・右上・右下・左下に対応していて、それらを順番に透明度を変えることで、今回のようなエフェクトになっています。
この記事を書いている現在、Swiperは新たに5.0.1バージョンにアップデートされています。
次回からは5.0verを使って書いていこうと思います。