CSSアニメーション、このくらいはわかった方がいいよ。


Reactのアニメーションを学ぶ前に背景知識としてCSSのアニメーションについて紹介する。
ReactではなくてもこのくらいのCSSアニメーションの扱い方は覚えた方がいいと思う。

## CSS transition

transition効果（時間的変化）を与えるために使うプロパティ
百聞は一見にしかず、早速だがソースコードをみよう。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Hover Transition</title>
    <style media="screen">
    a{
      font-family: Helvetica, Arial, sans-serif;
      text-decoration: none;
      color: #ffffff;
    }

    .button{
      padding: 0.74rem 1rem;
      border-radius: 0.3rem;
      box-shadow: 0;
      background-color: #bbbbbb;
    }

    .button:hover{
      background-color: #ee2222;
      box-shadow: 0 4px #990000;
      webkit-transition: 0.5s;
      transition: 0.5s;
    }
    </style>
  </head>
  <body>
    <a href="#" class="button">Hover Me!</div>
  </body>
</html>
```

buttonについて２つのクラスが用意されている。
マウスのカーソルをbuttonの上に移動する（hover）とbuttonの色と影（shadow）が変化する。
変化を目で識別するために、transition（時間差）を0.5sで設定している。
transitionではアニメーションの開始と終了だけ制御ができる。
開始と終了の間のアニメーションはすべてブラウザーに依存する。
![ani01.gif](https://qiita-image-store.s3.amazonaws.com/0/93752/1f5e3041-ac3c-ab16-fa48-febee37f2794.gif "ani01.gif")

## Keyframe Animations

アニメーションをブラウザーがすべて処理するtransitionに対してkeyframeはアニメーション中に到達するべきポイント（キーフレーム）を明示することで、アニメーションの中間地点の制御ができる。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Pulsing Heart</title>
    <style media="screen">
      body{
        text-align: center;
      }
      @keyframes pulsing-heart {
        0% { transform: none; }
        50% { transform: scale(1.4); }
        100% { transform: none; }
      }
      .heart {
        font-size: 10rem;
        color: #ff0000;
      }
      .heart:hover {
        animation: pulsing-heart .5s infinite;
        transform-origin: center;
      }
    </style>
  </head>
  <body>
    <div>
      <div class="heart">&hearts; </div>
    </div>
  </body>
</html>
```

@keyframesとtransformプロパティに値を設定することで、アニメーションが作られる。
上記のpulsing-heartはキーフレームの集合で、0%、50%、100%に該当する３つのキーフレームで構成されている。
transformプロパティで使えるメソッドには次の4つがある。

| メソッド  | 説明         |
| ---       | ---          |
| scale     | 対象のサイズ |
| translate | 対象の移動   |
| skew      | 対象の傾斜   |
| rotate    | 対象の回転   |

ブラウザーで確認してみよう。
赤いハートが表示されて、ハートの上にマウスのカーソルを移動すると心臓が鼓動するようにハートが変化する。
![ani02.gif](https://qiita-image-store.s3.amazonaws.com/0/93752/5e5f4111-123b-469f-c448-aec1f5dbe97c.gif "ani02.gif")

* 参考

[@keyframesのtransform](http://ri-mode.com/rainbow/2013/06/10/css3_keyframes_transform/)
[cssのanimation](http://webdrawer.net/css/cssanimation.html)

## class swappingとjavascript

異なるcssのclassを定義してあるイベントが発火した場合、javascriptでclassを変更することでアニメーションの効果が作られる。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Hacked together sidebar Transition</title>
    <style media="screen">
      ul {
        list-style-type: none;
        padding: 0;
      }
      li {
        padding: 15px;
        border-bottom: solid 1px #eee;
        background-color: #ddd;
      }
      .sidebar {
        background-color: #eee;
        box-shadow: 1px 0 3px #888888;
        position: absolute;
        width: 15rem;
        height: 100%;
      }
      .sidebar-transition {
        opacity: 0;
        left: -15rem;
      }
      .sidebar-transition-active {
        opacity: 1;
        left: 0;
        transition: 0.5s;
      }
    </style>
  </head>
  <body>
    <header>
      <button onclick="document.querySelector('.sidebar').classList.add('sidebar-transition-active');">&#9776;</button>
    </header>
    <div class='sidebar sidebar-transition'>
      <ul>
        <li>Some content</li>
        <li>Content B</li>
        <li>Content C</li>
        <li>Content X</li>
      </ul>
    </div>
  </body>
</html>
```

sidebarは幅が15rem、sidebar-transitionで透明にしてleftから-15remすることでsidebarを隠す。
sidebar-transition-activeでは不透明にしてleftを0に変えることでsidebarを表示する。
buttonをクリックするとsidebar-transitionでsidebar-transition-activeを追加することで隠されたsidebarが現れる。
![ani03.gif](https://qiita-image-store.s3.amazonaws.com/0/93752/7f385976-7dfa-0a00-e1aa-527417701f55.gif "ani03.gif")

## emとrem

「エム」と呼ぶ。
1emは1文字分の大きさで、font-sizeが100%（デフォルト）であれば「1em = 16px」になる。
emとremの違いは親要素のサイズを継承するかしないかである。

```css
body{
	font-size: 1.5em;
}
p{
	font-size: 1.5em;
}
```

この場合、pタグのフォントサイズは16px \* 1.5em \* 1.5em = 36px
emではないremで設定された場合は親要素のサイズを継承しないので、16px \* 1.5rem = 24px