CSSアニメーション

# `transition`

## `transition`を定義する位置
:::note warn
`transition`は「変化前」に書くことを推奨
- 一般的に`transition`は「状態が変わったときに、どんな風に変化させるか」を事前に定義するもののため。
:::

**例✅マウスホバーの時にアニメーションをつける**
- マウスホバーしたら、ボックスが丸くなる
- `transition`は「変わる前の状態」に書くことが推奨されているので`box`クラスに書く
    - `.box` → 普段の状態（マウスを乗せてない時）
    - `.box:hover` → 状態が変わるとき（マウスを乗せた時）
```CSS
.box {
  width: 80px;
  height: 80px;
  background: pink;
  transition-property: border-radius;
  transition-duration: 1s;
}

.box:hover {
 border-radius: 50%;
```

**例✅定義位置の変化による挙動を確認する**

- `.box`に定義した時
    - マウスを乗せたとき（ホバーしたとき）： 1秒待ってから、1秒かけて右に移動します。
    - マウスを離したとき（ホバーを外したとき）： すぐに1秒かけて元の位置に戻ります。

```CSS
.box {
  width: 80px;
  height: 80px;
  background: pink;
  transition-property: transform;
  transition-duration: 1s;
  transition-delay: 1s;
}

.box:hover {
  transform: translateX(100px);
}
```
- `.box:hover`に定義した時（非推奨）
    - マウスを乗せたとき（ホバーしたとき）： 1秒待ってから、1秒かけて右に移動します。
    - マウスを離したとき（ホバーを外したとき）： `transition-delay`が`.box`に定義されていないため、デフォルト値（0秒）が適用されます。そのため、すぐに元の位置に戻ります。
```CSS
.box:hover {
  transition-delay: 1s;
  transform: translateX(100px);
```

## 一括指定構文
```CSS
transition: transition-property transition-duration イージング関数 ransition-delay;
```
省略したら初期値が使われます！

| 項目          | 説明                                                   |
| ----------- | ---------------------------------------------------- |
| `transition-property`    | どのプロパティにアニメーションをつけるか　（初期値：`all`） |
| `transition-duration`  | アニメーションの長さ（初期値：`0`）|
| `イージング関数`   | アニメーションの動き方（初期値：`ease`）           |
| `ransition-delay` | アニメーションが始まるまでの待ち時間（初期値：`0`）                         |

### 複数の指定も可
- `,`で区切ろう

```CSS
transition: transform 1s, border-radius 1s;
```

## 関連プロパティ
### ① `transition-property`
- **何のプロパティを変化させるか**を指定する
```CSS
transition-property: background-color;
```

複数指定もできる💪🏻
```CSS
transition-property: background-color, transform;
```

### ② `transition-duration`
- どれくらいの時間かけて変化させるか
```CSS
transition-duration: 0.3s;
```

### ③ `transition-timing-function`
- 変化のスピードのカーブ（イージング）を決める
```CSS
transition-timing-function: ease-in-out;
```
#### イージング関数

| 値             | 説明                   |
| ------------- | -------------------- |
| `ease`        | 最初ゆっくり → 速く → 最後ゆっくり（規定値） |
| `ease-out`    | 動きはじめは早く→最後ゆっくり（小さなUI部品）|
| `ease-in-out` | 最初と最後がゆっくり      （大きなUI部品） |
| `linear`      | 一定のスピード            （回転する部品）|
| `ease-in`     | 最初ゆっくり               |

### ④ `transition-delay`
- どれくらいあとに始めるか？🕒 ちょっと間をおいて変化したいときに使う！
```CSS
transition-delay: 0.2s;
```

### ⑤ ` transform-origin`
- 変形（transform）の「中心点」を決めるプロパティ
    - 要素を回転（`rotate`）させたり、拡大（`scale`）したりするとき、「どこを軸に変形するのか？」を決める
    - `translate`は「位置をずらす」変形なので、回転や拡大のような中心点の影響は受けない

```CSS
transform-origin: top left;
```

| 水平方向（X軸） | 垂直方向（Y軸） | 意味           |
| -------- | -------- | ------------ |
| `left`   | `top`    | 左上           |
| `left`   | `center` | 左中央          |
| `left`   | `bottom` | 左下           |
| `center` | `top`    | 上中央          |
| `center` | `center` | 中央（デフォルト）    |
| `center` | `bottom` | 下中央          |
| `right`  | `top`    | 右上           |
| `right`  | `center` | 右中央          |
| `right`  | `bottom` | 右下           |
| `50%`    | `50%`    | 中央（同じくデフォルト） |
| `100%`   | `0%`     | 右上（数値指定）     |
| `20px`   | `80px`   | 任意の位置（px指定）  |


#### X軸とY軸の方向
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627033/7485c3b1-8cf9-4c53-93a6-86246e2bba8b.png)

## `transform`
要素の形や位置、向きを動的に「変形」させるCSSプロパティ
### 構文
```CSS
transform: 変形関数1 変形関数2 変形関数3 ...;
```
 
| 変形関数         | 書き方                                      | 効果                 |
| ---------- | ---------------------------------------- | ------------------ |
| 移動（平行移動）   | `translateX(50px)` / `translateY(-20px)` / `translate(40px, -40px)` | 要素を横（X）・縦（Y）に動かす       |
| 拡大・縮小      | `scale(1.5)` / `scaleX(2)`               | 要素のサイズを変える（1が等倍）   |
| 回転         | `rotate(45deg)`                          | 指定した角度だけ回転させる（右回り） |
| 傾ける（斜めにする） | `skewX(30deg)` / `skewY(15deg)`          | 要素を傾ける             |

#### `translate`
- 横（X）と縦（Y）に動かす
```CSS
transform: translate(100px, 100px);
```

- 横（X）に動かす
    - 要素が 右に`100px` 動きます。
    - マイナス値にすると左へ動きます！
```CSS
transform: translateX(100px);
```

- 縦（Y）に動かす
    - 要素が 下に`100px` 動きます。
    - マイナス値にすると上に動くよ！
```CSS
transform: translateY(100px);
```



## 変数の組み合わせ
- 下記のように、変数を組み合わせることは可能
- 右→左に実行される
```CSS
  transform: translateX(100px) rotate(45deg);
  transform: rotate(45deg) translateX(100px);
```

**`transform: translateX(100px) rotate(45deg);`の場合**
- 45度回転した後に右に100px動く

**`transform: rotate(45deg) translateX(100px);`の場合**
- 右に100px動く
- translateは中心点が変わらないので、中心点が変わらないまま（中心点は初期値のまま）45度回転する

:::note warn
`transition`は途中経過を再現しない
- `transition`でアニメーションさせるときは、「Aの状態」から「Bの状態」へ、指定された時間で滑らかに移動する。
- つまり、「右に行ってから回転する」というような、途中のステップを一つずつ再現するわけではない。
- そのため、指定時間内で同時に実行されているように見えます。
:::

# `animation`
より複雑なアニメーションを実装することができる🫰🏻

## 一括指定構文
```CSS
animation: animation-name animation-duration イージング関数　animation-iteration-count animation-delay animation-direction...;
```
※イージング関数で設定できる値は`trasition`と同じ。
　プロパティ名は`animation-timing-function`。

## 関連プロパティ

### `animation-name`
🔹 何のアニメーションを使うかを指定します。
これは、あとで出てくる `@keyframes` の名前とリンクします。

### `animation-duration`
🔹 アニメーションがどれくらいの時間で動くかを指定します。
単位は s（秒） や ms（ミリ秒）。

### `animation-iteration-count`
🔹 アニメーションを何回繰り返すかを指定します。
`infinite`を指定すると、永遠にぐるぐる繰り返します！

| 値                | 意味                  | 例                                         |
| ---------------- | ------------------- | ----------------------------------------- |
| `1`（初期値）         | **1回だけ**アニメーションをする  | `animation-iteration-count: 1;`           |
| `2`, `3`, `5` など | 指定した回数だけ繰り返す        | `animation-iteration-count: 3;`（3回繰り返す）   |
| `infinite`       | **無限に繰り返す**（止まらない！） | `animation-iteration-count: infinite;`    |
| 小数（※少し特殊）        | 「途中まで」再生させたいとき      | `animation-iteration-count: 1.5;` → 1回半やる |


### `@keyframes`
🔹 アニメーションの中身（動きの定義）を作ります。

例1：
```CSS
@keyframes move-around {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}
```
- `from` は開始時点、`to` は終了時点です。
- この例では、「左から右にスライドしてくる」動きになります。

例2：
```CSS
@keyframes move-around {
  25% {
   transform: translate(100px, 0);
  }
  50% {
   transform: translate(100px, 100px);
   border-radius: 50%;
  }
  75% {
   transform: translate(0, 100px);
  }
  100% {
   transform: none;
  }
}
```
- この例では、四角が動き続けます。2秒時点で四角が丸くなり、また四角に戻ります。
- 4秒で定義したので（コード省略）、1秒ごとにアニメーションを定義し、変化させます。
- 50%以降は、前からどのくらい動かすかではなく、あくまでも**最初の位置からみてどこにきてほしいか**を指定します。
- この `@keyframes` の中で 0% と 100% の指定は特殊で、**省略すると元のスタイルを指定したのと同じこと**になります。
- 50％時点で、`border-radius`が指定されていますがそれ以降は指定されていません。その場合は初期値に戻るように補間されます。
    - 補完したくない場合は75％などで`border-radius: 0;`などと明示的に定義する必要があります。

### `animation-delay`
🔹 アニメーションを いつから始めるか を指定するプロパティ！
```CSS
animation-delay: 1s;
```
- マイナスの値も使えて、その場合はすでにアニメーションが途中から始まる感じになる

### `animation-direction`
🔹 アニメーションの進み方の向きを指定できる！
| 値                   | 意味                   |
| ------------------- | -------------------- |
| `normal`            | 最初から最後まで通常再生で進む（規定値）。 |
| `reverse`           | 最後から最初に向かって逆再生で進む（100％→0％に変化する）。|
| `alternate`         | 1回目の再生は通常方向（0%から100%）で、2回目の再生は逆方向（100%から0%）になる。以降、交互に再生方向が反転する。 |
| `alternate-reverse` | reverse	1回目の再生は逆方向（100%から0%）で、2回目の再生は通常方向（0%から100%）になる。以降、交互に再生方向が反転する。|

```CSS
animation-direction: alternate;
```

### `animation-fill-mode`
🔹 アニメーションの前後で、どんな見た目のままにしておくかを決めるプロパティ

| 値           | 説明                            | よくある使い方                 |
| ----------- | ----------------------------- | ----------------------- |
| `none`（初期値） | アニメーションの実行期間中のみスタイルが適用され、アニメーションが開始される前（`animation-delay`中）や終了後には、要素の元のCSSスタイルに戻ります。| 初期状態|
| `forwards`  | アニメーション終了時の見た目を保つ。（最後のキーフレーム（通常は `100%` または `to`）で定義されたスタイルが要素に適用されたままになります。） | アニメ後のスタイルをそのままにしたいとき！   |
| `backwards` | アニメーション**開始前から0%に設定した値を表示させる**      | 遅延中もアニメの最初の状態で見せたい時に便利  |
| `both`      |`backwards`の効果によりアニメーション**開始前から0%に設定した値を表示させ、`forwards`の効果によりアニメーション終了後も最後のキーフレームのスタイルが維持されます。
 | アニメ前後ともキープしたい！という場合に使用される |