Swiperをカスタマイズ

はじめに

こんにちは!大ちゃんの駆け出し技術ブログです。

昨日出した記事ではSwiperの公式ドキュメントに合わせて、既存のscaffloldの雛形アプリケーションに追加して以下のようなスライダー画面を実装しました。

sakitadaiki.hatenablog.com

本日はSwiperの仕組みと、Swiperを使用して様々なスライダー画面を実装していきたいと思います!

Swiperの仕組み

昨日、公式のドキュメントをほぼ思考停止で実装していきました。しかし、完成した画面を見ると今まで再現したことのないスライダー画面をしっかりと作ることができましたね。この画面はどうやって作ることができたかわかりましたか?

ポイントはスライダーに与えたクラスとapplication.scss、application.jsの関係にあります。まず、現在スライダーを表示している画面は以下のファイルです。

 <!-- app/views/users/show.html.erb -->
<strong>Portrait:</strong>
<!-- Slider main container -->
<div class="swiper-container">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <% if @user.portraits.present? %>
      <% @user.portraits.each do |portrait| %>
        <%= image_tag url_for(portrait), class: 'swiper-slide' %>
      <% end %>
    <% else %>
        <%= image_tag '/images/haikyu.jpg', class: 'swiper-slide' %>
    <% end %>
  </div>
  <!-- ページネーション -->
  <div class="swiper-pagination"></div>

  <!-- ナヴィゲーションボタン -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>

  <!-- スクロールバー -->
  <div class="swiper-scrollbar"></div>
</div>

ここでスライダー画面を実際に表示しているHTMLは下記部分です。

  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    <% if @user.portraits.present? %>
      <% @user.portraits.each do |portrait| %>
        <%= image_tag url_for(portrait), class: 'swiper-slide' %>
      <% end %>
    <% else %>
        <%= image_tag '/images/haikyu.jpg', class: 'swiper-slide' %>
    <% end %>
  </div>

そして、スライダーにページネーションだったり、スクロールバーだったりを実装しているHTMLが下記部分です。

<!-- ページネーション -->
<div class="swiper-pagination"></div>

<!-- ナヴィゲーションボタン -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>

<!-- スクロールバー -->
<div class="swiper-scrollbar"></div>

つまり何が言いたいのかというと、「スライダー画面を実装しているHTML部分とその下のスライダーの機能を実装しているHTML部分は明確に役割が分かれている」、ということとです。

昨日説明しませんでしが、スライダー機能を実装しているHTMLのクラスにのみにapplication.jsで機能を与えています。paginationnavigationscrollbarの部分です。Optional parametersはスライダー全体の設定です。direction: 'vertical'は垂直方向に画像をスライドさせる設定をしています。loop: trueは1番最後に表示している画像から次の画像に移ると最初の画像に戻る設定をしています。

// app/assets/javascripts/application.js
const swiper = new Swiper('.swiper-container', {
  // Optional parameters
  direction: 'vertical',
  loop: true,

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },

  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },

  // And if we need scrollbar
  scrollbar: {
    el: '.swiper-scrollbar',
  },
});

よって、スライダー画面で与えられているクラスであるswiper-wrapperswiper-slideにはこの遂ライダーの機能には一切関与していません。言い換えれば、スライダー画面で与えられているこれらのクラスは、現状ただクラスが与えられているだけで何の役割も果たしていないということです。

これらのクラスがなぜあるのかというとただレイアウトを整えることを想定しています。つまり、scssにそれらのクラスを用いてレイアウトを整えるということですね!

例えば、scssに適当にクラスにレイアウトを定義します。

// app/assets/stylesheets/application.scss
.swiper-container {
  .swiper-wrapper {
    width: 100%;
    height: 600px;
    .swiper-slide {
      object-fit: cover;
    }
  }
}

object-fit: cover;をつけることで現在表示している画像の縦横の比率を整えてくれます。width: 100%;とすることで画面いっぱいに画像を表示します。実際に見てみましょう。

https://i.gyazo.com/aca61c09f425a4a62501f6fa0bcca155.gif

当然ですが、scssが反映されました。こんな感じでswiper-wrapperswiper-slideは画像の表示幅だったりのレイアウトを整えるために使用されることが想定されています。

スライダーのカスタマイズ

ではpaginationnavigationscrollbarの部分を設定しているjsファイルを変更してみましょう。今回はAmazon Prime videoのような画面になるように編集していきます。

https://i.gyazo.com/0b05b7cec8266df792398cb13a0bb922.gif

まず画像がPrime Videoの方だと水平方向に流れているのがわかります。先ほどOptional parametersdirection: 'vertical'の箇所でスライダーが垂直方向に流れるように設定していました。これをverticalからhorizontalに変更しましょう。

const swiper = new Swiper('.swiper-container', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,

画面を読み込み直すと表示が変わり、水平方向に画面が動くようになりました!

https://i.gyazo.com/8693f7a25926f99da10c284a5a10ee98.gif

あとPrime Videoと異なる部分として、数秒ごとに自動でスライドが切り替わるように設定されています。この自動で切り替わるようにする方法も実は簡単に導入することができます。autoplayという設定を加え、ms単位で切り替わる間隔を指定するだけです。

const swiper = new Swiper('.swiper-container', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  autoplay: {
    delay: 2500,
  },

画面を再度読み込み直すと、

https://i.gyazo.com/2a15f45e08d583bb07ddafe0ab38bbc1.gif

切り替えボタンを押さずとも勝手に切り替わるようになりました。もっと早く自動でスライドさせたいなら、2500の秒数をより短い間隔(1000(1秒))などに設定するだけです。

Optional parametersの設定だけでもかなり自由にスライドの設定を変えることができたと思います。実際、他のスライド方法を調べてみるとそのほとんどがOptional parametersの設定を変えることで再現できています。例えば、下のボックスが回転するようなお洒落なスライダーもOptional parametersの設定を変更することで実装できます。

https://i.gyazo.com/a0d2c28a16e7bcef4ebeea39d900222d.gif

JSファイルを下記のように変更します。navigationscrollbarの部分は削除しましょう。

const swiper = new Swiper('.swiper-container', {
  // Optional parameters
  effect: 'cube',
  grabCursor: true,
  cubeEffect: {
    shadow: true,
    slideShadows: true,
    shadowOffset: 20,
    shadowScale: 0.94,
  },

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },
});

app/views/users/show.html.erbでも同様に下記部分を削除しましょう。

<!-- ナヴィゲーションボタン -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>

<!-- スクロールバー -->
<div class="swiper-scrollbar"></div>

そしてscssで画像が正方形に表示されるように設定します。

.swiper-container {
  width: 300px;
  height: 300px;
  .swiper-wrapper {
    .swiper-slide {
      object-fit: cover;
    }
  }
}

これで画面を読み込み直すと、

https://i.gyazo.com/a504b7930d915b46cfd2458f49e553a3.gif

このように簡単に再現できてしまいました。RUNTEQでは9割りの学習がバックエンドでRailsしかほぼ学びません。しかし、ほんの少しのフロントエンドの知識があるだけでこんなふうにスライダーが実装できてしまいます!本当に便利ですよね。

加えていうと、paginationnavigationscrollbarの設定はもはやオプションと思ってください。そこにページネーションを付けるか、ボタンを付けるか、スクロールバーを付けるかの違いを作る、scssとは別で付ける装飾のようなものです。jsファイルにある設定でもほとんどいじることはありません。スクロールバーのデザインを変えるなどのオプションがあるだけです。

終わりに

3つの記事を通してswiperについて紹介しましたが、細かい仕組みの説明はしませんでしたが、正直仕組みを理解する必要はさほどない気がしています。結局調べてコピペするという作業で大体実装することができました。このほかにもおしゃんなスライダー画面を実装する方法はいくつもあるので皆さんも試してください!

以上、大ちゃんの駆け出し技術ブログでした!