SVGで作るかわいいキャラクターアニメーション - 表情の動きを実装してみよう

## はじめに
前回の記事に対して表情を追加してみました。

https://qiita.com/Tadataka_Takahashi/items/881c402a5ac636faacca

SVGを使ってキャラクターを作成する際、表情のアニメーションを追加することで、よりインタラクティブで魅力的な表現が可能になります。この記事では、SVGを使って簡単なキャラクターを作成し、目や口の表情をアニメーション化する方法を解説します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/efc43f85-d774-0e8d-0b26-ac7282e859a1.png)

## 実装するアニメーションの概要
今回は以下のような機能を実装します：
- キャラクターの基本形状の作成（顔、装飾など）
- 目のアニメーション（通常の目 → 「> <」→ 笑顔 → 横線）
- 口のアニメーション（表情に合わせた変化）

## 完成イメージ

![animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/e066122b-d317-dee1-5466-24511bcef117.gif)

## 実装手順

### 1. 基本的な顔の形状を作成
まず、キャラクターの基本となる顔の形状を作成します。

```svg
<!-- 本体(緑色) -->
<ellipse cx="0" cy="0" rx="50" ry="45" fill="#4CAF50"></ellipse>

<!-- 顔部分(クリーム色) -->
<ellipse cx="0" cy="0" rx="30" ry="25" fill="#FDF1D2"></ellipse>
```

### 2. 装飾パーツの追加
キャラクターの特徴となる葉っぱとヒゲを追加します。

```svg
<!-- 左葉 -->
<path d="M -20 -32 C -30 -50, -10 -60, -15 -40 C -18 -35, -18 -35, -20 -32 Z" fill="#4CAF50" />
<path d="M -20 -34 C -27 -47, -13 -52, -16 -40 C -18 -37, -18 -37, -20 -34 Z" fill="#FFD83D" />

<!-- ヒゲの例（左側） -->
<line x1="-20" y1="0" x2="-35" y2="0" stroke="#000" stroke-width="1"></line>
<line x1="-20" y1="5" x2="-35" y2="7" stroke="#000" stroke-width="1"></line>
<line x1="-20" y1="10" x2="-35" y2="14" stroke="#000" stroke-width="1"></line>
```

### 3. 目のアニメーションの実装
SVGのアニメーション機能を使用して、目の表情変化を実装します。

```svg
<!-- 左目 -->
<path id="left-eye" d="M -20 -5 L -10 -5" stroke="#000" stroke-width="2" fill="none">
  <animate 
    attributeName="d" 
    values="
      M -20 -5 A 5 5 0 1 1 -10 -5;
      M -18 -8 L -12 -2 L -18 4;
      M -20 -8 Q -15 -3 -10 -8;
      M -20 -5 L -10 -5;
      M -20 -5 A 5 5 0 1 1 -10 -5"
    dur="4s"
    repeatCount="indefinite"
    keyTimes="0;0.25;0.5;0.75;1" />
</path>
```

#### 目のアニメーションの解説
- `values`属性で各表情のパスデータを定義
  1. 丸い目：円弧を描くパス
  2. 「>」の目：2本の線で形成
  3. 笑顔の目：上向きのカーブ
  4. 横線の目：シンプルな直線

### 4. 口のアニメーションの実装
目の表情に合わせて口も動くようにアニメーションを追加します。

```svg
<!-- 口 -->
<path id="mouth" d="M -5 5 Q 0 10 5 5" stroke="#000" stroke-width="1" fill="none">
  <animate 
    attributeName="d"
    values="
      M -5 5 Q 0 10 5 5;
      M -5 5 Q 0 0 5 5;
      M -5 5 Q 0 12 5 5;
      M -5 7 Q 0 3 5 7;
      M -5 5 Q 0 10 5 5"
    dur="4s"
    repeatCount="indefinite"
    keyTimes="0;0.25;0.5;0.75;1" />
</path>
```

## アニメーションの調整のポイント

### タイミングの制御
- `dur`属性：アニメーションの1サイクルの時間を設定
- `keyTimes`属性：各表情の表示タイミングを制御
- `repeatCount="indefinite"`：アニメーションを無限に繰り返し

### パスデータの作成のコツ
1. 基準点を明確に決める
2. 対称性を意識した座標設定
3. 滑らかな変化のために中間点を適切に配置

## カスタマイズのポイント

### 1. 表情の追加
```svg
<!-- values属性に新しい表情のパスデータを追加 -->
values="
  既存の表情1;
  既存の表情2;
  新しい表情;
  既存の表情3"
```

### 2. アニメーション速度の調整
```svg
<!-- durの値を変更してスピードを調整 -->
dur="3s"  <!-- 速く -->
dur="6s"  <!-- ゆっくり -->
```

### 3. 色やサイズの変更
```svg
<!-- 色の変更例 -->
fill="#新しい色コード"
stroke="#新しい色コード"

<!-- サイズの変更例 -->
rx="新しい値" ry="新しい値"
```

## まとめ
SVGのアニメーション機能を使うことで、JavaScriptを使わずとも豊かな表現が可能です。特に：
- パスデータを使った形状の変化
- アニメーションタイミングの制御
- 複数のパーツの連携

これらの要素を組み合わせることで、よりインタラクティブなキャラクターを作成できます。

## 参考資料
- [SVG Animation（MDN）](https://developer.mozilla.org/ja/docs/Web/SVG/SVG_animation_with_SMIL)
- [SVG Path（MDN）](https://developer.mozilla.org/ja/docs/Web/SVG/Tutorial/Paths)

## 最後に
本記事で紹介したテクニックをベースに、さらに複雑なアニメーションや独自のキャラクターを作成してみてください。SVGは非常に柔軟で、様々な表現が可能です。

## 実装例

htmlで保存してブラウザで表示するとアニメーションを確認することができます。

```xml
<svg width="200" height="200" viewBox="-100 -100 200 200" xmlns="http://www.w3.org/2000/svg">
  <g id="character">
    <!-- 本体(緑色) -->
    <ellipse cx="0" cy="0" rx="50" ry="45" fill="#4CAF50"></ellipse>

    <!-- 顔部分(クリーム色の緑部分) -->
    <ellipse cx="0" cy="0" rx="30" ry="25" fill="#FDF1D2"></ellipse>

    <!-- 左葉 -->
    <path d="M -20 -32 C -30 -50, -10 -60, -15 -40 C -18 -35, -18 -35, -20 -32 Z" fill="#4CAF50" />

    <!-- 左葉内装 -->
    <path d="M -20 -34 C -27 -47, -13 -52, -16 -40 C -18 -37, -18 -37, -20 -34 Z" fill="#FFD83D" />

    <!-- 右葉 -->
    <path d="M 20 -32 C 30 -50, 10 -60, 15 -40 C 18 -35, 18 -35, 20 -32 Z" fill="#4CAF50" />

    <!-- 右葉内装 -->
    <path d="M 20 -34 C 27 -47, 13 -52, 16 -40 C 18 -37, 18 -37, 20 -34 Z" fill="#FFD83D" />

    <!-- 左目 -->
    <path id="left-eye" d="M -20 -5 L -10 -5" stroke="#000" stroke-width="2" fill="none">
      <animate 
        attributeName="d" 
        values="
          M -20 -5 A 5 5 0 1 1 -10 -5;
          M -18 -8 L -12 -2 L -18 4;
          M -20 -8 Q -15 -3 -10 -8;
          M -20 -5 L -10 -5;
          M -20 -5 A 5 5 0 1 1 -10 -5"
        dur="4s"
        repeatCount="indefinite"
        keyTimes="0;0.25;0.5;0.75;1" />
    </path>

    <!-- 右目 -->
    <path id="right-eye" d="M 10 -5 L 20 -5" stroke="#000" stroke-width="2" fill="none">
      <animate 
        attributeName="d" 
        values="
          M 10 -5 A 5 5 0 1 1 20 -5;
          M 18 -8 L 12 -2 L 18 4;
          M 10 -8 Q 15 -3 20 -8;
          M 10 -5 L 20 -5;
          M 10 -5 A 5 5 0 1 1 20 -5"
        dur="4s"
        repeatCount="indefinite"
        keyTimes="0;0.25;0.5;0.75;1" />
    </path>

    <!-- 口 -->
    <path id="mouth" d="M -5 5 Q 0 10 5 5" stroke="#000" stroke-width="1" fill="none">
      <animate 
        attributeName="d"
        values="
          M -5 5 Q 0 10 5 5;
          M -5 5 Q 0 0 5 5;
          M -5 5 Q 0 12 5 5;
          M -5 7 Q 0 3 5 7;
          M -5 5 Q 0 10 5 5"
        dur="4s"
        repeatCount="indefinite"
        keyTimes="0;0.25;0.5;0.75;1" />
    </path>

    <!-- ヒゲ（直線） -->
    <!-- 左側のヒゲ -->
    <line x1="-20" y1="0" x2="-35" y2="0" stroke="#000" stroke-width="1"></line>
    <line x1="-20" y1="5" x2="-35" y2="7" stroke="#000" stroke-width="1"></line>
    <line x1="-20" y1="10" x2="-35" y2="14" stroke="#000" stroke-width="1"></line>

    <!-- 右側のヒゲ -->
    <line x1="20" y1="0" x2="35" y2="0" stroke="#000" stroke-width="1"></line>
    <line x1="20" y1="5" x2="35" y2="7" stroke="#000" stroke-width="1"></line>
    <line x1="20" y1="10" x2="35" y2="14" stroke="#000" stroke-width="1"></line>

    <!-- しっぽ -->
    <path d="M 35 30 C 45 40, 60 35, 50 20 C 45 10, 40 20, 35 30 Z" fill="#4CAF50" />
  </g>
</svg>
```