こんにちは、えりです。
ある案件で画面の右上からスタートして階段式に徐々に左下に下がっていくような無限ループスライダーの実装をお願いされました。
調べればできるやろーと思っていたのですがネット上にコードがなく、一から書く羽目になり…
- ライブラリ使わないでcssとjsだけでできそうかな?→無理だった
- slickでできるかな?→できたと思ったら1周した後にカクつく問題発生
- swiperに変更してみよう→できた!
という感じで、最終的にswiperを使用して実装できました。
slickで実装した際の不具合を修正しようと、slickのコードのままいろいろこねくり回したのですが全然うまくいかず…swiperにしたら一瞬で解決しました。やはり思い切りが大事。
では早速コードからいってみましょう!
まずはコードから。
See the Pen 右上から左下に向かって階段式に斜めに流れ続けるスライドショー by 東野江里 (@anyxfbuk-the-scripter) on CodePen.
かわいいわんこが右上から左下に向かって流れていきます。(この子はフリー素材のわんちゃんですがうちではジャック飼ってます。かわいい。)
Edit on Codepenをクリックして大きい画面で見た方が見やすいです。
swiperのjsとcss、jqueryはあらかじめ読み込んでおいてください。
ではコード解説していきましょう。
解説
html
<section class="p-kv" style="padding-bottom: 200px;">
<div class="swiper p-kv-slider">
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="https://pro-tabi.terua-channel.com/wp-content/uploads/2024/10/im-kv01.jpg" alt="画像1" />
</div>
<div class="swiper-slide">
<img src="https://pro-tabi.terua-channel.com/wp-content/uploads/2024/10/im-kv02.jpg" alt="画像2" />
</div>
<div class="swiper-slide">
<img src="https://pro-tabi.terua-channel.com/wp-content/uploads/2024/10/im-kv03.jpg" alt="画像3" />
</div>
<div class="swiper-slide">
<img src="https://pro-tabi.terua-channel.com/wp-content/uploads/2024/10/im-kv01.jpg" alt="画像1" />
</div>
<div class="swiper-slide">
<img src="https://pro-tabi.terua-channel.com/wp-content/uploads/2024/10/im-kv02.jpg" alt="画像2" />
</div>
<div class="swiper-slide">
<img src="https://pro-tabi.terua-channel.com/wp-content/uploads/2024/10/im-kv03.jpg" alt="画像3" />
</div>
</div>
</div>
</section>
特記事項はあまりありません。通常のswiperのコードです。
今回は無限ループ系のスライダーなので、ボタンも矢印も置いていません。
p-kv
にpadding
がついているのは調整のためなので無視して問題ないです。
1点だけ、後述するjsの関係で、.swiper
には独自のクラスをつけてください。今回はp-kv-slider
クラスをつけています。
css
.p-kv {
overflow: hidden;
}
.swiper-wrapper {
transition-timing-function: linear;
}
.swiper-slide img {
width: 100%;
aspect-ratio: 1 / 1;
object-fit: cover;
}
.p-kv
(スライドショーを囲っているクラス)もしくはbody
には必ずoverflow: hidden;
を設定してください。
これは今回の実装に限らずスライドショー系を実装する際は書いておかないと、画面に横スクロールのバーが表示されてしまうので注意!
また、今回は.swiper-wrapper
にtransition-timing-function: linear;
を追加するのが最重要です。
これがないと滑らかなスライドショーにならないので、必ず書いておいてください。
.swiper-slide img
はすべての画像が同じ縦横比(aspect-ratio
)で表示されるように調整していますが、ここは各自デザイン等に合わせて調整してもらって問題ないです。
js
1.Swiperの初期化
$(function() {
var swiper = new Swiper('.p-kv-slider', {
autoplay: {
delay: 0, // 自動再生の遅延を0に設定。つまり、スライダーは即座に自動再生される。
},
speed: 7500, // スライダーが次のスライドに切り替わるのにかかる時間を7.5秒に設定。
spaceBetween: 20, // 各スライド間の余白を20pxに設定。
slidesPerView: 3, // 表示するスライドの数を3枚に設定。
loop: true, // スライダーを無限ループさせる。
allowTouchMove: false, // タッチやドラッグでスライドを動かす操作を禁止。
on: {
init: function () {
updateSlidePosition(); // スライダーが初期化されたときに呼び出され、スライドの位置を更新。
},
slideChange: function () {
updateSlidePosition(); // スライドが変わるたびにスライド位置を更新。
},
resize: function () {
updateSlidePosition(); // ウィンドウサイズが変更されたときにもスライド位置を更新。
},
},
});
Swiperの設定:
- Swiperは
.p-kv-slider
クラスに対して適用しいます。 autoplay
のdelay: 0
により、スライダーは一度スタートすると止まることなく動き続けます。無限ループスライダーにはこれが必須です。speed
やspaceBetween
でアニメーション速度やスライド間のスペースを設定しています。調整してください。- 今回は
slidesPerView
を3
に設定しているので3枚ずつ表示されますが、それぞれのデザイン等に合わせて調整してください。cssで大きさ設定したい場合は'auto'
にすればOKです。また、swiperはここで設定した枚数の2倍の数のスライドがないとエラー起きるので注意! loop: true
でスライダーをループさせ、allowTouchMove: false
でスライドをタッチして操作できないようにしています。ここの記述も無限ループスライダーに必要です。
イベントハンドラー:
init
やslideChange
、resize
でスライドの位置を動的に更新するupdateSlidePosition
関数を呼び出しています。
2.updateSlidePosition
関数
function updateSlidePosition() {
var slides = $('.swiper-slide img'); // 各スライド内のimg要素を取得
var swiperWidth = $('.p-kv-slider').width(); // スライダー全体の幅を取得
slides.each(function(index, element) {
var slideWidth = $(element).outerWidth(); // 各スライドの幅を取得
var slideOffsetLeft = $(element).offset().left - $('.p-kv-slider').offset().left + slideWidth * -0.1; // スライドの左端の位置を計算し、少し左にずらす
var slideOffsetRight = slideOffsetLeft + slideWidth - slideWidth * -0.1; // スライドの右端も少し左にずらす
var translateY = 0; // 初期のtranslateY値
if (window.innerWidth > 768) { // PCの場合
if (slideOffsetLeft <= swiperWidth && slideOffsetRight >= 0) {
var positionPercentage = 1 - (slideOffsetLeft / swiperWidth); // スライダー内の位置を割合で計算
translateY = 100 * positionPercentage; // 位置に応じて最大100pxまでY方向に移動
}
} else { // SPの場合
if (slideOffsetLeft <= swiperWidth && slideOffsetRight >= 0) {
var positionPercentage = 1 - (slideOffsetLeft / swiperWidth); // 同様に位置を割合で計算
translateY = 50 * positionPercentage; // SPの場合は50pxまでY方向に移動
}
}
$(element).css('transform', 'translateY(' + translateY + 'px)'); // 計算したtranslateY値をCSSに適用
});
}
スライド位置の計算:
updateSlidePosition
関数では、スライド内の各img
要素の位置を計算し、CSSのtransform
を使って縦方向の位置(Y軸)を動的に調整しています。- 各スライドの左端と右端のオフセットを計算しており、スライダー内に入った場合にのみ、その位置に基づいてスライドを上下に移動させます。
PCとSPでの違い:
- 画面幅が768pxを超える場合はPCモードとして、スライドのY方向の移動量を最大100pxに設定。
- それ以下の画面幅ではSPモードとして、移動量を最大50pxに設定しています。(PCとSPを同じ移動量にすると、SP時かなり大きく移動しているように見えるので。ここの値は適宜調整してください)
3.定期的な位置更新
setInterval(updateSlidePosition, 100); // アニメーションのため、100msごとにスライド位置を更新
});
updateSlidePosition
が100ミリ秒ごとに実行され、スライドの位置が定期的に更新されます。
これにより、スライドが動くたびに画像が滑らかに上下に移動するアニメーション効果が実現されています。
まとめ
あるようでなかった階段式のスライドショーについて解説しました。
ただのスライドショーよりもキービジュアルが華やかな感じになるのでぜひ使ってみてください。
もしわからないことあれば質問ください!
記事にしてほしい・解説してほしい内容のリクエストもお待ちしています。