JavaScriptのスライダーライブラリであるSwiperにおいて、ページネーションをカスタマイズする方法をご紹介しています。
今回は、現在表示中のスライド番号と総スライド枚数をそれぞれ表示し、その間にプログレスバーを実装してみました。
次のスライドに切り替わるまでの時間を視覚的に把握できるようになるのと、ちょっとしたアニメーションですが、Webサイトがリッチになります。
ページネーションにプログレスバーを導入した例
今回実装したのはこちらです。
スライダーの右下にページネーションを配置しています。
左側に現在のスライド番号、右側に総スライド枚数を表示し、その間に次のスライドに切り替わるまでのラインアニメーションを実装しています。
ざっくりとした実装方法は、次の通りです。
- スライド番号と総スライド枚数の表示:Swiperのfractionを使用
- プログレスバーのHTML:SwiperのrenderFractionで要素を追加
- ラインアニメーション:CSSで表現
コードの見本
SwiperをCDNの形式でindex.html内で読み込んでいます。
headタグ内
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css" />
bodyタグの終了直前
<script src="https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js"></script>
index.html
<div class="wrapper">
<div class="swiper lineAnimationSlider">
<div class="swiper-wrapper">
<div class="swiper-slide"><img src="./images/01.jpg" alt="サンプル画像"></div>
<div class="swiper-slide"><img src="./images/02.jpg" alt="サンプル画像"></div>
<div class="swiper-slide"><img src="./images/03.jpg" alt="サンプル画像"></div>
<div class="swiper-slide"><img src="./images/04.jpg" alt="サンプル画像"></div>
<div class="swiper-slide"><img src="./images/05.jpg" alt="サンプル画像"></div>
</div>
</div>
<div class="swiper-pagination"></div>
</div>
style.css
/* ==========================
画像サイズ調整
========================== */
.swiper-slide {
height: auto;
}
.swiper-slide img {
height: 100%;
width: 100%;
}
/* ==========================
paginationの位置を調整
========================== */
.wrapper {
position: relative;
}
.swiper-horizontal>.swiper-pagination-bullets,
.swiper-pagination-bullets.swiper-pagination-horizontal,
.swiper-pagination-custom,
.swiper-pagination-fraction {
bottom: -30px;
}
/* ==========================
fractionのカスタマイズ
========================== */
.swiper-pagination-fraction {
font-size: 12px;
font-weight: 600;
color: #1a1b1b;
display: flex;
align-items: center;
justify-content: flex-end;
position: absolute;
z-index: 1;
}
/* ==========================
ラインアニメーションをCSSで表現
========================== */
.swiper-pagination-fraction .border {
width: 70px;
height: 1px;
margin: 0 8px;
background-color: #ddd;
position: relative;
}
.swiper-pagination-fraction .border span {
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 100%;
height: 100%;
background-color: #1a1b1b;
transform: scaleX(0);
transform-origin: left center;
transition-timing-function: linear;
}
.swiper-pagination.is-active .border span {
transform: scaleX(1);
transition: transform 3.85s linear;
}
script.js
const lineAnimationSlider = new Swiper('.lineAnimationSlider', {
loop: true,
slidesPerView: 3,
spaceBetween: 20,
centeredSlides: true,
autoplay: {
delay: 4000,
disableOnInteraction: false,
},
speed: 1500,
pagination: {
el: '.swiper-pagination',
type: 'fraction',
renderFraction: function (currentClass, totalClass) {
return '<span class="' + currentClass + '"></span>' + '<span class="border js-border"><span></span></span>' + '<span class="' + totalClass + '"></span>';
}
},
on: {
init: function () {
setTimeout(() => {
const pagiNation = document.querySelector('.swiper-pagination');
pagiNation.classList.add('is-active');
}, 100);
},
slideChangeTransitionStart: function () {
const border = document.querySelector('.js-border span');
if (border) {
border.style.transform = 'scaleX(0)';
border.style.transitionDuration = '0s';
}
},
slideChangeTransitionEnd: function () {
const border = document.querySelector('.js-border span');
if (border) {
border.style.transform = 'scaleX(1)';
border.style.transitionDuration = '4000ms';
}
},
},
});
コードの解説
今回使用したSwiperのオプションについて解説します。
paginationオプション
pagination: {
el: '.swiper-pagination',
type: 'fraction',
renderFraction: function (currentClass, totalClass) {
return '<span class="' + currentClass + '"></span>' + '<span class="border js-border"><span></span></span>' + '<span class="' + totalClass + '"></span>';
}
},
type: 'fraction'
を指定し、現在のスライド番号と総スライド枚数を表示しています。
fractionは日本語で「分数」です。
今回は表示形式をカスタマイズしていますが、デフォルトでは「現在のスライド番号 / 総スライド枚数」のように分数でページの情報が表示されます。
次にrenderFraction:
パラメータで、fractionで出力されるHTMLを上書きしています。
具体的には、現在のスライド番号と総スライド枚数の間にspanタグを2つ挿入しています。外側のspanタグにはborder
クラスとjs-border
クラスをつけています。
onオプション
on: {
init: function () {
setTimeout(() => {
const pagiNation = document.querySelector('.swiper-pagination');
pagiNation.classList.add('is-active');
}, 100);
},
slideChangeTransitionStart: function () {
const border = document.querySelector('.js-border span');
if (border) {
border.style.transform = 'scaleX(0)';
border.style.transitionDuration = '0s';
}
},
slideChangeTransitionEnd: function () {
const border = document.querySelector('.js-border span');
if (border) {
border.style.transform = 'scaleX(1)';
border.style.transitionDuration = '4000ms';
}
},
},
init イベント
スライダーが初期化されたときの処理を記述しています。処理内容は、初期化の100ミリ秒後にswiper-pagination
の要素に、is-active
クラスを付与しています。
slideChangeTransitionStart イベント
スライド切り替えのトランジションが開始されたときの処理を記述しています。処理内容は、border
の要素の中のspanタグのスタイルを変更しています。
slideChangeTransitionEnd イベント
スライド切り替えのトランジションが完了したときの処理を記述しています。処理内容は、border
の要素の中のspanタグのスタイルを変更しています。
- スライド切り替えのトランジション開始時:scaleX(0)、アニメーション時間0秒
- スライド切り替えのトランジション完了時:scaleX(1)、アニメーション時間4000ミリ秒
以上です。最後までお読みいただきありがとうございました!
全く同じ要件の実装は少ないかもしれませんが、今回紹介したオプションを使用することで表現の幅がグッと広がるかと思います。
ちなみに私は今回のような地味で誰も気づかないようなアニメーションが好きで、自らのポートフォリオにも導入しています。