こんにちは〜お久しぶりです。

エンジニア
カトリーヌ
もう4月・・・早すぎる・・・🥺

エンジニア
カトリーヌ
さて、Swiperで無限に流れ続けるモーダルスライダーを作りたい!
でも・・・モーダルを開いたらスライダーが止まってほしい・・・!
しかも!閉じたあとに“どこにいたっけ?”ってならずに、ちゃんと開いた場所から再開したい!
さらに!!見たいコンテンツの位置にスムーズに移動できたら最高!
そんな理想のスライダーを実装してみました
目次
DEMO
さっそく完成版はこちらです。
See the Pen
【Swiper】流れ続けるスライダー&矢印で操作 by Catherine (@ikuradonburi)
on CodePen.
※Swiperの基本的な実装方法については省略します。本記事では、無限ループ+モーダル連携にフォーカスして解説します
※本記事では簡易的なモーダルを使用しています。必要に応じて、デザインや挙動を自由にカスタマイズしてください!
※本記事では簡易的なモーダルを使用しています。必要に応じて、デザインや挙動を自由にカスタマイズしてください!
コードの説明
基本的な実装は省略して、ポイントとなる箇所のみ説明します。
流れ続けるスライダー
Swiperの autoplay
設定
delay: 0 にすることで、途切れなくスライドし続ける動きになります。
autoplay: {
delay: 0, // 途切れずに流れ続ける
disableOnInteraction: false, // ユーザー操作後も自動再生を継続
},
CSSの transition-timing-function: linear;
linear を指定することで、速度が一定になり、なめらかに流れ続けるようになります。
.list {
transition-timing-function: linear;
}
矢印のよる操作
document.querySelector('.swiper-button-prev').addEventListener('click', function () {
slide.autoplay.stop(); // 一時停止
slide.slideTo(slide.activeIndex - 2, 1000); // 1枚前へスライド
restartAutoplay();
});
slide.autoplay.stop();
でスライドの動きを止めるslide.slideTo(slide.activeIndex - 2, 1000);
でスライドを移動 ※1restartAutoplay();
で自動再生を再開
function restartAutoplay() {
setTimeout(() => {
slide.autoplay.start();
}, 1000);
}
次のスライドに移動する.swiper-button-next
でも使用するので関数化しています。
すぐ再開すると操作性が悪くなるので、1秒空けています。
※1 -1だと挙動が不安定だったため、-2にしています。
.swiper-button-next
ではslide.slideTo(slide.activeIndex + 1, 1000);
となります。
これで無限に流れ続けながら、矢印で移動が可能になります。
モーダルを開いた時に動きを止める
if (modal.style.display === "block") {
const activeSlide = document.querySelector('.swiper-slide-active');
// 現在のスライドの幅 + 左右マージンを取得
const activeSlideStyle = window.getComputedStyle(activeSlide);
const slideWidth = activeSlide.offsetWidth;
const marginLeft = parseFloat(activeSlideStyle.marginLeft) || 0;
const marginRight = parseFloat(activeSlideStyle.marginRight) || 0;
const totalSlideWidth = slideWidth + marginLeft + marginRight;
// スライド位置補正
const translate = slide.getTranslate();
const slideOffset = -totalSlideWidth - (translate % totalSlideWidth);
const slideMoveDuration = slideOffset / -slideWidth;
slide.setTranslate(translate + slideOffset);
slide.setTransition(4000 * slideMoveDuration); // スライドの速度を調整
modal.style.display = "none"; //モーダルを非表示
} else {
// 現在のスライド位置を取得し、即座に停止
const currentSlidePosition = slide.getTranslate();
slide.setTranslate(currentSlidePosition);
slide.setTransition(0);
modal.style.display = "block"; //モーダルを表示
}
モーダルが表示された時
slide.getTranslate();
スライドの現在の位置を取得slide.setTranslate(currentSlidePosition);
取得した位置に固定slide.setTransition(0);
スライドのアニメーションを無効化
モーダルが非表示になった時
window.getComputedStyle(activeSlide);
クリック時に .swiper-slide-active に適用されているスタイル情報を取得するactiveSlide.offsetWidth;
アクティブ要素の幅を取得parseFloat(style.marginLeft) || 0;
指定されている場合文字列を数値に変換(例:10px→10)(marginRIghtも同様)slideWidth + marginLeft + marginRight;
マージンも含めた幅を取得slide.getTranslate();
スライドの現在の位置を取得-totalSlideWidth - (translate % totalSlideWidth);
現在のスライド位置のズレを補正して次のスライド位置を計算diff / -slideWidth;
スライド位置のズレに応じて、移動時間を計算
これでモーダルを開いた際に自動再生を停止し、閉じた時に再開できます。
まとめ
Swiperを使って無限に流れ続けるモーダルスライダー を作りつつ、以下の機能を追加しました!
- 矢印ボタンでスライド操作可能
- モーダルを開くとスライダーが停止し、閉じると再生再開
- モーダルを閉じた後も、開いた場所からスライドが再開
これで、「モーダルを開いて戻ったら位置が分からなくなる……」という問題を解決できました!
あとはデザインや動作の細かい調整を加えて、用途に応じてカスタマイズしてみてください!
ところで
弊社ロジカルスタジオでは、一緒に働く仲間を募集しています!
下記リンクからぜひご応募ください!