🐧
スライダープラグインSplideをカスタマイズしてオシャンなサイトのFV再現してみた
今回再現したサイト
(こんなオシャンなサイトいつか実務で作ってみたい...黙r)
完成図
実装できた仕様
- スライド切り替えアニメーションの追加
- スライド切り替えのプログレスバー追加(FV右側にあるゲージみたいなやつ)
- スライドの枚数と現在のスライドのインデックス番号の取得、表示(今何枚目だよーってやつ)
コードの全体像
Splideの導入方法については、公式サイト(日本語にも対応)を参照ください。
<section id="image-carousel" class="splide">
<div class="splide__track">
<ul class="splide__list">
<li class="splide__slide">
<img src="images/cafe-1.jpg" alt="" />
</li>
<li class="splide__slide">
<img src="images/cafe-2.jpg" alt="" />
</li>
<li class="splide__slide">
<img src="images/cafe-3.jpg" alt="" />
</li>
<li class="splide__slide">
<img src="images/cafe-4.jpg" alt="" />
</li>
<li class="splide__slide">
<img src="images/cafe-5.jpg" alt="" />
</li>
</ul>
<div class="pagination">
<span id="current-slide"></span>
<span id="progressBarOuter"><span id="progressBar"></span></span>
<span id="slide-length"></span>
</div>
</div>
</section>
.splide__slide img {
width: 100%;
height: 100%;
object-fit: cover;
}
.splide__slide {
height: 700px;
overflow: hidden;
&:before {
position: absolute;
content: "";
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2;
background-color: rgba(grey, 0.3);
}
&.is-active {
img {
animation-name: fadeInAnime;
animation-duration: 12s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
@keyframes fadeInAnime {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
}
}
}
.splide__track {
position: relative;
}
.pagination {
position: absolute;
right: 100px;
top: 50%;
transform: translateY(-50%);
z-index: 2;
display: flex;
flex-direction: column;
color: white;
align-items: center;
gap: 10px;
#progressBarOuter {
width: 2px;
height: 100px;
background-color: white;
position: relative;
#progressBar {
position: absolute;
content: "";
width: 100%;
height: 100%;
background-color: rgb(60, 60, 60);
top: 0;
left: 0;
animation: linear 6s;
animation-fill-mode: forwards;
opacity: 0;
transform-origin: top;
@keyframes progressAnime {
0% {
transform: scaleY(0);
}
100% {
transform: scaleY(1);
}
}
}
}
}
const splide = new Splide("#image-carousel", {
type: "fade",//スライド切り替え時fadeのアニメーション付与
autoplay: true,//自動再生
pauseOnHover: false,//スライドにhover時自動再生停止禁止
pauseOnFocus: false,//スライドfocus時自動再生停止禁止
rewind: true,//スライドの最後のページに行ったら、最初のページに戻れるようにする
interval: 6000,//次のスライドに行くまでの速さ
arrows: false,//デフォルトのページ送りボタンを非表示
speed: 2000,//ページ送りアニメーションの速さ
pagination: false,//デフォルトのページネーションを非表示
}).mount();
//アクティブスライドが変わった時に発生(次のスライドが表示されるタイミング)
splide.on("active", function () {
slideIndex();
progressBarAnimeStart();
});
//スライダーが動く直前に発生(次のスライドに行く直前に発生)
splide.on("move", function () {
progressBarAnimeStop();
});
//スライドの枚数と現在のスライドが何枚目かを取得しDOM内に追加
function slideIndex() {
//splide.indexでスライドのインデックス番号が0から取得される。+1することで現在のスライド枚数が取得できる
document.getElementById("current-slide").textContent = splide.index + 1;
//splide.lengthでスライドの枚数が取得可能。
document.getElementById("slide-length").textContent = splide.length;
}
slideIndex();//ハンドラのイベント実行前にも関数呼び出ししないと1枚目のスライドで番号が表示されない
function progressBarAnimeStart() {
//[#progressBar]を可視化し、animation-name付与してアニメーション開始
document.getElementById("progressBar").style.opacity = 1;
document.getElementById("progressBar").style.animationName = "progressAnime";
}
progressBarAnimeStart();//こちらもハンドライベント実行前に実行するために、ここで呼び出す
function progressBarAnimeStop() {
//次のスライドにうつる直前でanimation-nameプロパティを空にしてアニメーションを停止させる
document.getElementById("progressBar").style.animationName = "";
}
ポイント
スライド切り替えアニメーションはCSSで付与
今回は、スライドが徐々にズームアウトするようなアニメーションの再現を行いました。
アニメーション自体は、keyframeで難しくなく実装可能です。
ポイントと思うところとして
Splideは現在のスライドに「is-active」クラスが付与されていく仕様になっていたので
それに対してアニメションを付与した点です。
.splide__slide {
height: 700px;
overflow: hidden;
&:before {
position: absolute;
content: "";
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 2;
background-color: rgba(grey, 0.3);
}
//この部分
&.is-active {
img {
animation-name: fadeInAnime;
animation-duration: 12s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
@keyframes fadeInAnime {
0% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
}
}
}
autoplay:trueだけではループしない
タイトルの通りでした。
これだけでループすると思い込んでましたが、「rewind:true」 のオプション指定も必須です。
難航したことと対策
ほんと、スライドの切り替えにかかる時間ワカランです。
プログレスバーのduration設定に難航した
interval: 6000,//次のスライドに行くまでの速さ
speed: 2000,//ページ送りアニメーションの速さ
こうなので、単純に「6000ms」 + 「2000ms」 = 「8000ms」と思うじゃないですか
これは違う。
じゃあ、シンプルに6秒か?
これも違う。
どんどんプログレスバーのアニメーションがずれるずれる。。。
対策
結果、以下で対応しました。
- ページ読み込み時にまずプログレスバーのアニメーション開始
- スライドが切り替わる直前にアニメーション一旦停止(animation-nameを空にして強制終了)
- スライドが切り替わった後に再度アニメーションを開始(animation-nameを付与して開始)
こうすることで、「interval」と同じ秒数を「animation-duration」に設定すれば問題解決!!
最後に
Splide便利ですね。カスタマイズ結構しやすいかもしれない。
今後もオシャンなスライダー探してSplideの可能性広げる旅を続けます。
またいい感じにできたら記事書きたいと思います。
ありがとうございました。
Discussion