👀

スライダープラグインSplideをカスタマイズしてオサレなサイトのFV再現してみた②

2022/08/17に公開

再現したいサイト

今回再現したいのは、こちらのサイトです。
FVのアニメーションをカルーセルのアニメーションとして実装したいと思います。

https://bandit.co.jp/

完成図

最初に完成図。こちらです。

https://www.lets-retire-early.com/Splide-02/

コードの全体像

<section class="image-carousel splide">
    <div class="splide__track">
      <ul class="splide__list">
        <li class="splide__slide">
          <img src="images/season1.jpg" alt="">
        </li>
        <li class="splide__slide">
          <img src="images/season2.jpg" alt="">
        </li>
        <li class="splide__slide">
          <img src="images/season3.jpg" alt="">
        </li>
        <li class="splide__slide">
          <img src="images/season4.jpg" alt="">
        </li>
      </ul>
    </div>
    <div class="cover-slides">
      <div class="cover-slide cover-slide--1"></div>
      <div class="cover-slide cover-slide--2"></div>
      <div class="cover-slide cover-slide--3"></div>
      <div class="cover-slide cover-slide--4"></div>
      <div class="cover-slide cover-slide--5"></div>
    </div>
 </section>
  .image-carousel {
    position: relative;
    width: 100vw;
    height: 100vh;
  }

  .splide__track {
    height: 100%;
  }

  .splide__slide {
    width: 100%;
    height: 100%;

    &.is-active {
      img {
        animation:zoomoutAnime 2s forwards;

        @keyframes zoomoutAnime {
          0% {
            transform: scale(1.1);
          }
          100% {
            transform: scale(1);
          }
        }
      }
    }

    img {
      object-fit: cover;
      object-position: center center;
    }
  }

  .cover-slide {
    position: absolute;
    background-color: white;
    width: 25vw;
    height: 100%;
    top: 0;
    animation: 0.8s forwards;
    transform-origin: right;
    @keyframes turningAnime {
      0% {
        transform: scaleX(1);
      }
      100% {
        transform: scaleX(0);
      }
    }

    &.cover-slide--1 {
      left: 0;
      width:12.5vw;
    }
    &.cover-slide--2 {
      left: 12.5%;
      animation-delay: 0.1s;
    }
    &.cover-slide--3 {
      animation-delay: 0.25s;
      left: 37.5%;
    }
    &.cover-slide--4 {
      left: 62.5%;
      animation-delay: 0.35s;
    }
    &.cover-slide--5 {
      left:87.5%;
      animation-delay: 0.45s;
      width:12.5vw;
    }
  }
const splide = new Splide(".image-carousel", {
  type: "fade",//スライド切り替え時fadeのアニメーション付与
  autoplay: true,//自動再生
  pauseOnHover: false,//スライドにhover時自動再生停止禁止
  pauseOnFocus: false,//スライドfocus時自動再生停止禁止
  rewind: true,//スライドの最後のページに行ったら、最初のページに戻れるようにする
  arrows: false,//デフォルトのページ送りボタンを非表示
  interval: 5000,//次のスライドに行くまでの速さ
  speed: 2000,//ページ送りアニメーションの速さ
  pagination: false,//デフォルトのページネーションを非表示
}).mount();

function slideAnimeStart() {
  // animation-name付与してアニメーション開始
  const coverSlide = document.querySelectorAll(".cover-slide");
  for (let i = 0; i < coverSlide.length; i++){
    coverSlide[i].style.animationName = "turningAnime";
  }
}
function slideAnimeStop() {
  //次のスライドにうつる直前でanimation-nameプロパティを空にしてアニメーションを停止させる
  const coverSlide = document.querySelectorAll(".cover-slide");
  for (let i = 0; i < coverSlide.length; i++){
    coverSlide[i].style.animationName = "";
  }
}

// ページが読み込まれたらすぐにアニメーションスタート
slideAnimeStart();

//アクティブスライドが変わった時に発生(次のスライドが表示されるタイミング)
splide.on('active', function () {
  slideAnimeStart();
})

//スライダーが動く直前に発生(次のスライドに行く直前に発生)
splide.on('move', function () {
  slideAnimeStop();
})

解説

コード内に全て記載しておりますが、ポイントは以下です。

  • 画像のzoomoutアニメーションは「is-active」クラスに付与
  • ページ読み込み時に、slideAnimeStart関数を実行し、白ボックスのアニメーションを開始
  • 次のスライドに移る前にslideAnimeStop関数を実行し、アニメーションを止める。
    理由:止めてリセットしなければ、タイミングがずれていってしまうため。
    (アニメーションの間隔の時間を計算して設定できれば、その方がベストかもしれません!)
  • アクティブスライドが切り替わったタイミングで、再びslideAnimeStart関数を呼ぶ

実装してみて

実際にやってみての感想は、前回の時と同じような流れだと感じました。
スライドが表示されたときに行いたいアニメーションは「is-active」クラスに付与する。
スライドが移る前後に行う処理は、Splideの元々用意されているイベントハンドラを使用する。
この流れがカスタマイズの一つの判例なのかもしれません。
また、この流れ以外の処理が必要そうなオサレサイトが見つかったら
記事にまとめたいと思います。
お読み頂きありがとうございました!

Discussion