【SVG】SVGファイルを編集して、SVGアニメーションに挑戦する

## はじめに
みなさんは、SVGアニメーションに挑戦したいと思ったことはありますか？

SVGってどういう作りをしているかパッとわからないし、その上アニメーションって難しさを感じると思います。

この記事では、SVGアニメーションについてまとめようと思います！

## SVGの事前知識
この記事では、SVG自体の解説はしません。
こちらの記事を参考にしてください！ 

https://qiita.com/takeshisakuma/items/6bd2b4cc9fb4edf61288

https://qiita.com/takeshisakuma/items/a6a06902e955acad5c99

https://qiita.com/takeshisakuma/items/777e3cb0a54ea7b1dbe7




## SVG アニメーションとは？
SVGアニメーションは、SVG画像をベースに、SVGファイルを編集したり、CSSやJavaScriptで動きを加える表現手法の一つになります。

この記事では、SVGファイルを直接編集する SVGアニメーションに挑戦します！

イメージはこちらです！
<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="yyBaqRB" data-pen-title="immersive" data-editable="true" data-user="sp_degu" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/yyBaqRB">
  immersive</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## SVG アニメーション

### 種類

### ◯ animate
`<animate/>` は、親要素を時間の経過に応じて、要素の属性を変化させます！


```html
<rect>
  <animate />
</rect>
```

+ アニメーションタイミング属性
    + **begin**：アニメーションを開始するタイミング
        + `begin="2s"`：2秒後にスタート
        + `begin="click"`：クリックしたらスタート
    + **dur**：1回のアニメーションする時間
    + **end**：アニメーションを終了する時間
        + `end="2s"`：2秒後に終了
    + **min**：アニメーションの継続時間の最小値
    + **max**：アニメーションの継続時間の最大値
    + **restart**：
    + **repeatCount**：アニメーションを繰り返す回数
    + **repeatDur**：アニメーションを開始してからrepeatCount分繰り返した合計時間の範囲でのアニメーション時間
    + **fill**：アニメーション終了後の状態
        + `fill="freeze"`：停止時に停止時の状態を維持する
        + `fill="remove"`：停止時にアニメーションする前の状態に戻る
+ アニメーション値属性
    + **calcMode**：アニメーションの補完モード
        + `calcMode="discrete"`：補完なし
        + `calcMode="linear"`：単純な線形補完
        + `calcMode="paced"`：アニメーション全体で変化のペースを均一にするための補間
        + `calcMode="spline"`：3 次ベジェ スプラインによって定義された時間関数に従って、リスト内のある値から補完
    + **values**：アニメーションの過程を定義する
    + **keyTimes**：アニメーションのペースを制御するために使用される時間値のリスト
    + **keySplines**：eyTimesリストに関連するベジエ曲線制御点のセットを定義し、間隔ペーシングを制御する3次ベジエ関数を定義
    + **from**：attributeNameで指定した属性のアニメーションを開始する値
    + **to**：attributeNameで指定した属性のアニメーションを終了する値
    + **by**：アニメーション中に変更される属性の相対オフセット値
+ その他のアニメーション属性
    + **attributeName**：アニメーションする対象の属性名
    + **attributeType**：`attributeName` で指定した属性名とその属性値が定義される名前空間
        + `attributeType="CSS"`：属性がCSSプロパティ名
        + `attributeType="XML"`：属性がXML
        + `attributeType="auto"`：CSSかXMLかを自動判別（デフォルト）
    + **additive**：アニメーションを加算するか制御する
    + **accumulate**：アニメーションを累積するか制御する

<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="qEWaMpY" data-pen-title="SVG animation" data-editable="true" data-user="sp_degu" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/qEWaMpY">
  SVG animation</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ◯ animateMotion
`<animateMotion/>` は、親要素をパスに従ってアニメーションさせます！

```html
<rect>
  <animateMotion />
</rect>
```

+ 特有の属性
    + **keyPoints**：[0,1] の範囲で、それぞれの keyTimes に関連付けられた値に対して、パスに沿ってオブジェクトがどのくらいの距離にあるかを示す 
    + **path**：モーションパスを定義する
    + **rotate**：パスに沿ってアニメーションされた要素に適用される回転を定義する

+ アニメーションタイミング属性
    + **begin**：アニメーションを開始するタイミング
        + `begin="2s"`：2秒後にスタート
        + `begin="click"`：クリックしたらスタート
    + **dur**：1回のアニメーションする時間
    + **end**：アニメーションを終了する時間
        + `end="2s"`：2秒後に終了
    + **min**：アニメーションの継続時間の最小値
    + **max**：アニメーションの継続時間の最大値
    + **restart**：
    + **repeatCount**：アニメーションを繰り返す回数
    + **repeatDur**：アニメーションを開始してからrepeatCount分繰り返した合計時間の範囲でのアニメーション時間
    + **fill**：アニメーション終了後の状態
        + `fill="freeze"`：停止時に停止時の状態を維持する
        + `fill="remove"`：停止時にアニメーションする前の状態に戻る
+ アニメーション値属性
    + **calcMode**：アニメーションの補完モード
        + `calcMode="discrete"`：補完なし
        + `calcMode="linear"`：単純な線形補完
        + `calcMode="paced"`：アニメーション全体で変化のペースを均一にするための補間
        + `calcMode="spline"`：3 次ベジェ スプラインによって定義された時間関数に従って、リスト内のある値から補完
    + **values**：アニメーションの過程を定義する
    + **keyTimes**：アニメーションのペースを制御するために使用される時間値のリスト
    + **keySplines**：eyTimesリストに関連するベジエ曲線制御点のセットを定義し、間隔ペーシングを制御する3次ベジエ関数を定義
    + **from**：attributeNameで指定した属性のアニメーションを開始する値
    + **to**：attributeNameで指定した属性のアニメーションを終了する値
    + **by**：アニメーション中に変更される属性の相対オフセット値
+ その他のアニメーション属性
    + **attributeName**：アニメーションする対象の属性名
    + **attributeType**：`attributeName` で指定した属性名とその属性値が定義される名前空間
        + `attributeType="CSS"`：属性がCSSプロパティ名
        + `attributeType="XML"`：属性がXML
        + `attributeType="auto"`：CSSかXMLかを自動判別（デフォルト）
    + **additive**：アニメーションを加算するか制御する
    + **accumulate**：アニメーションを累積するか制御する

<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="RNbGYBd" data-pen-title="SVG animation - sample 1" data-editable="true" data-user="sp_degu" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/RNbGYBd">
  SVG animation - sample 1</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ◯ animateTransform
`<animateTransform/>` は、親要素の座標変換属性をアニメーションさせ、これにより平行移動、拡大縮小、回転、ゆがみなどのアニメーションを制御できます！

```html
<rect>
  <animateTransform />
</rect>
```

+ アニメーションタイミング属性
    + **begin**：アニメーションを開始するタイミング
        + `begin="2s"`：2秒後にスタート
        + `begin="click"`：クリックしたらスタート
    + **dur**：1回のアニメーションする時間
    + **end**：アニメーションを終了する時間
        + `end="2s"`：2秒後に終了
    + **min**：アニメーションの継続時間の最小値
    + **max**：アニメーションの継続時間の最大値
    + **restart**：
    + **repeatCount**：アニメーションを繰り返す回数
    + **repeatDur**：アニメーションを開始してからrepeatCount分繰り返した合計時間の範囲でのアニメーション時間
    + **fill**：アニメーション終了後の状態
        + `fill="freeze"`：停止時に停止時の状態を維持する
        + `fill="remove"`：停止時にアニメーションする前の状態に戻る
+ アニメーション値属性
    + **calcMode**：アニメーションの補完モード
        + `calcMode="discrete"`：補完なし
        + `calcMode="linear"`：単純な線形補完
        + `calcMode="paced"`：アニメーション全体で変化のペースを均一にするための補間
        + `calcMode="spline"`：3 次ベジェ スプラインによって定義された時間関数に従って、リスト内のある値から補完
    + **values**：アニメーションの過程を定義する
    + **keyTimes**：アニメーションのペースを制御するために使用される時間値のリスト
    + **keySplines**：eyTimesリストに関連するベジエ曲線制御点のセットを定義し、間隔ペーシングを制御する3次ベジエ関数を定義
    + **from**：attributeNameで指定した属性のアニメーションを開始する値
    + **to**：attributeNameで指定した属性のアニメーションを終了する値
    + **by**：アニメーション中に変更される属性の相対オフセット値
+ その他のアニメーション属性
    + **attributeName**：アニメーションする対象の属性名
    + **attributeType**：`attributeName` で指定した属性名とその属性値が定義される名前空間
        + `attributeType="CSS"`：属性がCSSプロパティ名
        + `attributeType="XML"`：属性がXML
        + `attributeType="auto"`：CSSかXMLかを自動判別（デフォルト）
    + **additive**：アニメーションを加算するか制御する
    + **accumulate**：アニメーションを累積するか制御する

<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="gbYwdqY" data-pen-title="SVG animation" data-editable="true" data-user="sp_degu" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/gbYwdqY">
  SVG animation</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## まとめ
この記事では、SVGアニメーションについてまとめました。

色々な属性を駆使すれば、できない表現な少なそうな印象を受けました。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510