年末まで毎日webサイトを作り続ける大学生 〜41日目 要素が画面内に入るとふわっとフェードインさせる〜

##はじめに
こんにちは！@70days_jsです。

要素が画面内に入るとふわっとフェードインする機能を作りました。

今日は41日目。(2019/11/28)
よろしくお願いします。

##サイトURL
https://sin2cos21.github.io/day41.html

##やったこと
画面内に入るとふわっとフェードインするようにしました。
![test2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/fec237fc-353e-55d8-69c0-7dc8798efeb6.gif)


今回はJavaScriptとCSSを併用するので、
まずJavaScriptで要素が画面内に入るのを検知する機能を作りました。
そのあとCSSでふわっとする機能をつけました。

ではJavaScriptの方から説明していきます。

###要素が画面内に入ったのを検知する(JavaScript)
まず考え方ですが、要素が画面内に入ったのを検知する機能というのは、「要素が任意の位置までくれば検知する」機能を作ればカバーできます。

というわけで、とりあえず画面の半分を越えれば要素の色が変わるコードを書きました。

gif↓
![test1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516248/4613b943-72f8-04c9-fc0d-22425a818884.gif)

画面の半分を越えれば青色が赤色に変わっているのが分かると思います。

ではhtmlからいきます。

```html
html
<body>
    <div class="blank">空白</div>
    <div class="fade-out">
        test
    </div>
    <div class="blank">空白</div>
    <div class="fade-out">
        test2
    </div>
    <div class="blank">空白</div>
</body>
```

.fade-outクラスのついたdivの背景色を変えていました。
次はcss↓

```css

css
body {
    margin: 0;
}

.blank {
    height: 200vh;
    background-color: yellow;
}

.fade-out {
    background-color: blue;
}

.fade-in {
    background-color: red;
}
```

画面の半分を越えれば.fade-inクラスをつける事で、背景色が青色から赤色に変わります。
次はJavaScript↓

```javascript


##メモ
//色を変えたい要素（.fade-outクラスのついた要素）を取得する変数
let contents = document.querySelectorAll('.fade-out');
//画面の高さを取得する変数
let windowIn = window.innerHeight;
//現在位置を格納する変数
let nowPosition;
//付け加えるクラス名を格納する変数
let myClassName = 'fade-in';

//querySelectorAllは配列を返すので、for文で要素を1つずつ取り出します
for (var i = 0; contents.length > i; i++) {
//取り出した要素を格納します
    let content = contents[i];
//取り出した要素の位置を取得します
    let contentPosition = content.getBoundingClientRect().top;

//スクロールが行われると関数を実行するイベントリスナーをつけます
    window.addEventListener('scroll', function () {
//現在位置を取得します
        nowPosition = window.pageYOffset;
//要素に.fade-inクラスがなければ実行します。あれば実行しません（これはやる必要ないかも）
       if (content.classList.contains(myClassName) === false) {
//画面の高さ + 現在位置 が、要素の位置+画面の半分を越えれば.fade-inクラスをつけて色を変更します
            if (windowIn + nowPosition > contentPosition + (windowIn / 2)) {
                content.classList.add(myClassName);
            }
        }
    }, false)
}
```

大体のことはコメントに書いておきました。

最後の方にある(windowIn / 2)が画面の半分を表しています。
この部分を好きな位置に変更すれば、好きな位置で要素に何かしらの変化を与えることができるようになります

###ふわっと表示する機能をつける（CSS)

transformとtransitionを使って実装します。
今回は[海外のウェブサイトでよくみる「要素が画面内に入ったらふわっとフェードインするあれ」の実装方法 | imasashi.net ](https://imasashi.net/element-fadein.html)さんのサイトで紹介されていた書き方を使います。↓

```css
.fade-out {
    opacity : 0.1;
    transform : translate(0, 50px);
    transition : all 500ms;
}

.fade-in {
    opacity : 1;
    transform : translate(0, 0);
}
```

opacityで最初は薄い表示にしていますね。
特定の位置までくればopacityを1にして、translateを0にして、はっきりと元の位置で要素を表示するようになっていますね。


###組み合わせて、画面内に入るとふわっとフェードインさせる機能を作る

あとは上でやったことを組み合わせるだけでOKです。

```html
body>
    <div class="blank">
        <h1>Awesome Site</h1>
        <p>fugafuga</p>
    </div>
    <div class="box-wrapper">
        <div class="box fade-out">box1</div>
        <div class="box fade-out">box2</div>
        <div class="box fade-out">box3</div>
        <div class="box fade-out">box4</div>
        <div class="box fade-out">box5</div>
        <div class="box fade-out">box6</div>
        <div class="box fade-out">box7</div>
        <div class="box fade-out">box8</div>
        <div class="box fade-out">box9</div>
        <div class="box fade-out">box10</div>
    </div>
    <div class="blank">空白</div>
</body>
```

フェードインするには長さが必要なので、場所取りのために.blankクラスのついたdivを書いています。


cssは何も変わりません。↓

```css
.fade-out {
    opacity : 0.1;
    transform : translate(0, 50px);
    transition : all 500ms;
}

.fade-in {
    opacity : 1;
    transform : translate(0, 0);
}
```


次はJavaScriptですが、プラスアルファで何かしたくて、要素の背景をランダムで設定する機能をつけたりしました。↓

```javascript
let contents = document.querySelectorAll('.fade-out');
let windowIn = window.innerHeight;
console.log('windowの高さ: ' + windowIn);
let nowPosition;
let myClassName = 'fade-in';


for (var i = 0; contents.length > i; i++) {
    let content = contents[i];
    let contentPosition = content.getBoundingClientRect().top;
    console.log('contentの位置: ' + contentPosition);

    randomColor(content);

    window.addEventListener('scroll', function () {
        nowPosition = window.pageYOffset;
        console.log('現在位置: ' + nowPosition);
        if (content.classList.contains(myClassName) === false) {
            if (windowIn + nowPosition > contentPosition + (windowIn / 4)) {
                content.classList.add(myClassName);
            }
        }
    }, false)
}


function randomRGB() {
    let r = Math.floor(Math.random() * 256);
    let g = Math.floor(Math.random() * 256);
    let b = Math.floor(Math.random() * 256);
    let rgb = [r, g, b];
    return rgb;
}

function randomColor(element) {
    let rgb = randomRGB();
    let r = rgb[0];
    let g = rgb[1];
    let b = rgb[2];
    element.style.backgroundColor = 'rgba(' + r + ', ' + g + ',' + b + ', .5)';
}
```

要素がフェードインする場所も、(windowIn / 4)で1/4に変えています。
ここはロジックとかではなく、試してみていい感じのところにしました。


##感想
サイトに動きがあると華がでるというか、なんかいいですね。。。

最後までお読みいただきありがとうございます。明日も投稿しますのでよろしくお願い致します。

##参考
1. 海外のウェブサイトでよくみる「要素が画面内に入ったらふわっとフェードインするあれ」の実装方法 | imasashi.net (https://imasashi.net/element-fadein.html)

とても分かりやすかったです。ありがとうございます！