Rails Tutorialの知識から【ポートフォリオ】を作って勉強する話 #3 Bootstrap4, jQueryプラグイン導入編

# こんな人におすすめ
* プログラミング初心者でポートフォリオの作り方が分からない
* Rails Tutorialをやってみたが理解することが難しい

前回：[#2 RSpec導入編](https://qiita.com/aokyo17/items/02d107214ca6de846018)
次回：[#4 System spec導入編](https://qiita.com/aokyo17/items/356b7628194937851848)

# 今回の流れ
1. 今回のイメージを理解する
2. Bootstrap4を導入する
3. トップページを作る
4. jQueryプラグインを使う

※ この記事は、ポートフォリオを作る理由を**web系自社開発企業に転職するため**とします。
※ 2020年3月28日、記事を大幅に更新しました。

# 今回のイメージを理解する
ゴールは、トップページの外観を完成させることです。
その際に、デザインのためBootstrap4とjQueryプラグインを使います。

以上です。

# Bootstrap4を導入する
Bootstrapとは、簡単に整ったデザインが組み込めるフレームワークです。
Rails Tutorialでも使っていますが、あちらはBootstrap3です。
よって、導入までの手順が異なります。以下の通りです。

1. Gemfileにbootstrapとjquery-railsを追加する
2. application.cssをapplication.scssにする
3. application.scssを編集する
4. application.jsを編集する

## 1. Gemfileにbootstrapとjquery-railsを追加する
２つのGemを追加します。
書くところはRails Tutorialと同じくgem 'rails'の下で大丈夫です。

```diff:Gemfile
+ gem 'bootstrap', '~> 4.3.1'
+ gem 'jquery-rails'
```

```shell:shell
$ bundle install
```

2つ目のjquery-railsは以下の理由で必要です。
> BootstrapはjQueryに依存していますが、Rails 5.1以上はjQueryが入っていないのでインストールする必要があります。

## 2. application.cssをapplication.scssにする
app/assets/stylesheets/application.cssのファイル名を.scssに変更します。
ここはRails Tutorialと変わりません。

```
application.cssのファイル名を.scssに変更
```

## 3. application.scssを編集
以下を削除します。
一見コメントアウトに見えますが、プログラムとして動いています。

```scss:app/assets/stylesheets/application.scss
- *= require_tree .
- *= require_self
```
代わりに以下を加えます。
この辺りを深く知る必要はありません。おまじないだと捉えて構いません。

```scss:app/assets/stylesheets/application.scss
@import "bootstrap";
```

## 4. application.jsを編集
以下を加えます。
こちらもコメントアウトではありません。

```js:app⁩/assets⁩/⁨javascripts/application.js
//= require jquery3
//= require popper
//= require bootstrap-sprockets
```

以上で導入が完了しました。

参考になりました↓
[Bootstrap Ruby Gem（GitHub）](https://github.com/twbs/bootstrap-rubygem)
[Railsアプリで Bootstrap 4 を利用する](https://qiita.com/NaokiIshimura/items/c8db09daefff5c11dadf)

# トップページを作る
トップページを作ります。
とりあえず完成形を載せます。その後に解説します。
![lantern_lantern_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454653/f95f2e11-ba0b-4001-f64d-8a8430fd5013.png)
ロゴはIllstratorで作成、アイコンは[ICOON MONO](http://icooon-mono.com/)を使いました。

ではトップページをBootstrap4で表現するとどうなるのかを解説します。
トップページはヘッダー部分、画像部分、紹介部分の3つで構成しています。

```erb:app/views/layouts/application.html.erb
<html>
  <head>
    <title><%= full_title(yield(:title)) %></title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all',
                               'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application',
                               'data-turbolinks-track': 'reload' %>
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>
```

ヘッダーとそれ以外は<%= render '〇〇' %>を使って分けています。
分けたパーシャルのファイル名にはアンダーバーがつきます。

```erb:app/views/layouts/_header.html.erb
<header>
  <nav class="navbar navbar-expand-sm navbar-dark fixed-top navbar-extend">
    <a class="navbar-brand" herf="#">
      <div class="navbar-brand-extend">
        <%= link_to image_tag('lantern_lantern_logo.png', width: 50), root_path, class: "logo-img" %>
        <%= link_to image_tag('lantern_lantern_text.png', height: 30), root_path, class: "logo-text" %>
      </div>
    </a>
    <button class="navbar-toggler" data-toggle="collapse" data-target="#menu">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div id="menu" class="collapse navbar-collapse">
      <ul class="navbar-nav ml-auto">
        <li class="nav-item"><a href="#" class="nav-link"><button class="btn btn-info btn-md">Login</button></a></li>
      </ul>
    </div>
  </nav>
</header>
```

```erb:app/views/static_pages/home.html.erb
<div class="jumbotron jumbotron-fluid jumbotron-extend">
  <div class="container">
    <h1>動画を愛そう。</h1>
    <p>動画をみる時、人生は幸せ？それとも罪悪感？</p>
    <p>Lantern Lanternは、学習と娯楽に費やした動画時間を入力し、</p>
    <p>1日の、1ヶ月の、1年の動画時間を計測します。</p>
    <p>Lantern Lanternは、動画の時間を貯金します。</p>
    <%= link_to "はじめる", signup_path, class: "btn btn-info btn-lg" %>
  </div>
</div>

<div class="container">
  <div class="container discription-container">
    <div class="row">
      <div class="col-md-4">
        <div class="discription-img-container">
          <%= image_tag 'movie.png', class: 'discription-img' %>
        </div>
        <h2>動画時間を入力</h2>
        <p>動画の視聴時間を入力することで動画に使った時間を可視化することが可能です。</p>
      </div>
      <div class="col-md-4">
        <div class="discription-img-container">
          <%= image_tag 'art.png', class: 'discription-img' %>
        </div>
        <h2>学習時間も娯楽時間も</h2>
        <p>動画は単に暇つぶしのためだけのものではありません。学習など有効的に活用し記録することで有意義と感じる心理的効果が期待できます。</p>
      </div>
      <div class="col-md-4">
        <div class="discription-img-container">
          <%= image_tag 'memo.png', class: 'discription-img' %>
        </div>
        <h2>日記にも使える</h2>
        <p>ログ機能によりどんな動画を観たのかどんな感想を持ったのかを記録することも可能です。動画との人生を豊かにする日記となるでしょう。</p>
      </div>
    </div>
  </div>
</div>
```

scssによって、入れ子や変数などが使えます。
変数を使うには、$を使います。

```scss:app/assets/stylesheets/application.scss.erb
// 中略
 @import "bootstrap";

$lantern-light-white: #f5f5f6;
$lantern-dark-white: #cdced1;
$lantern-black: #050c17;
$lantern-red: #b1046b;
$lantern-violet: #640c41;
$lantern-yellow: #bdb319;
$lantern-blue: #0071bc;
$lantern-dark-blue: #0c2e64;

body {
  background-color: $lantern-black;
}

// header

.navbar-extend {
  margin-bottom: 0;
  background-color: $lantern-black;
  opacity: 0.9;
  ul li a button {
    padding: 0.375rem 1.5rem;
  }
}

.logo-img:hover {
  opacity: 0.6;
}

.logo-text {
  padding-top: 2px;
  :hover {
    opacity: 0.6;
  }
}

// jumbotron

.jumbotron-extend {
  background-image: url(<%= asset_path "shinkai_01.jpg" %>);
  background-size: cover;
  background-repeat: no-repeat;
  .container {
    margin-top: 6rem;
    h1,
    p {
      margin-bottom: 0.75rem;
      color: $lantern-light-white;
    }
    h1 {
      margin-bottom: 1.5rem;
    }
    p:last-of-type {
      margin-bottom: 2rem;
    }
  }
}

// discription

.discription-container h2, .discription-container p {
  color: $lantern-light-white;
}

.discription-container {
  margin: 3rem 0;
  padding: 3rem 1rem;
  h2 {
  font-size: 1.6rem;
  text-align: center;
  margin-bottom: 1.8rem;
  }
  p {
    font-size: 1rem;
    line-height: 2.1rem;
  }
}

.discription-img-container {
  margin-bottom: 3rem;
  text-align: center;
}

.discription-img {
  width: 12rem;
  border-radius: 0.1rem;
}
```

書き方は、[Bootstrap公式](https://getbootstrap.com/)がとても分かりやすいので参考にします。

jumbotronには、深海の画像を挿入しています。
ディレクトリは、app/assets/imagesを使います。
画像呼び出しは、asset_pathを使います。
それにともない、application.scssを.scss.erbに変更します。

```
画像はapp/assets/imagesに配置
application.scssを.scss.erbに変更
```

# jQueryプラグインを使う
深海の背景に[jQuery Ripples](https://sirxemic.github.io/jquery.ripples/)というプラグインを使って水の波紋を表現します。
以下のようにディレクトリを構成します。

```
lantern_app
├── 他
└── vendor
    └── assets
        └── javascripts
            └── プラグイン
```

ここでの手順は以下の通りです。

* ディレクトリを作成する
* jQuery Ripplesをダウンロードする
* application.jsを編集する
* 実際の処理を書く

## ディレクトリを作成する
説明は省略します。

```shell:shell
$ mkdir vendor/assets
$ mkdir vendor/assets/javascripts
```

## jQuery Ripplesをダウンロードする
[jQuery Ripples（GitHub）](https://github.com/sirxemic/jquery.ripples/)をダウンロードします。
dist内にあるjquery.ripples-min.jsをvendor/assets/javascriptsに入れます。

```
jQuery Ripplesをダウンロードする
jquery.ripples-min.jsをvendor/assets/javascriptsに入れる
```

## application.jsを編集する
再びapplication.jsを編集します。
assetsツリーより前にvendorツリーを読み込む必要があります。
よって、以下のような順番になります。

```js:app⁩/assets⁩/⁨javascripts/application.js
// 中略
//= require rails-ujs
//= require activestorage
//= require turbolinks
//= require jquery3
//= require popper
//= require bootstrap-sprockets
//= require_tree ../../../vendor/assets/javascripts/.
//= require_tree .
```

## 実際の処理を書く
トップページの深海の画像が波打つよう、処理を書きます。
以下のように書きます。

```js:app⁩/assets⁩/⁨javascripts/application.js
// 中略
$(document).ready(function() {
  $('.jumbotron').ripples({ //波紋をつけたい要素の指定
		resolution: 800, //波紋の広がりの速度（値が大きいほど遅くなる）
		dropRadius: 30, //波紋の大きさ（値が大きいほどでかくなる）
		perturbance: 0.002 //波紋による屈折量（値が大きいほどブレる）
	});
});
```

参考になりました↓
[railsでのjsプラグインの使い方](https://qiita.com/namachapanda20/items/f14bdd39c0973847ddcd)
[【jQuery】リアルな波紋模様を再現する［jQuery Ripples］を使ってみる。](https://on-ze.com/archives/7180)
[波紋を作るjQueryプラグイン「jQuery Ripples」](https://www.weblab.co.jp/staff/html/5511.html)
[【Rails入門】5分でできるjQuery導入方法!初心者向けにまとめました](https://www.sejuku.net/blog/57790)

今回は以上です。

---
前回：[#2 RSpec導入編](https://qiita.com/aokyo17/items/02d107214ca6de846018)
次回：[#4 System spec導入編](https://qiita.com/aokyo17/items/356b7628194937851848)