SVGにアニメーションを設定する方法(SMIL, CSS, JS)

SVGにアニメーションを設定する方法として、「SMILを利用した方法」「CSSを利用した方法」「JavaScriptを利用した方法」があります。それぞれ動作確認してみます。

SMILでアニメーションを定義

SMIL(Synchronized Multimedia Integration Language) を用いたアニメーションの実現方法について確認します。SMIL では、アニメーションさせる SVG 要素の中に animate要素animateMotion要素 を定義してアニメーションを実装します。

animate要素で変化を定義

animate要素 の利用例を示します。

<svg xmlns="http://www.w3.org/2000/svg"
     width="200" height="200"
     viewBox="0 0 200 200"
     style="background-color: #ccc">

  <!-- blue -->
  <circle cx="0" cy="50" r="15" fill="blue" stroke="blue" stroke-width="1">
    <animate attributeName="cx" from="0" to="200" dur="2s" repeatCount="5"/>
  </circle>

  <!-- red -->
  <circle cx="0" cy="150" r="15" fill="red" stroke="red" stroke-width="1">
    <animate attributeName="cx" from="0" to="200" dur="5s" repeatCount="indefinite"/>
  </circle>

  <!-- green -->
  <circle cx="0" cy="0" r="15" fill="green" stroke="green" stroke-width="1">
    <animate attributeName="cx" from="0" to="200" dur="3s" repeatCount="indefinite"/>
    <animate attributeName="cy" from="0" to="200" dur="3s" repeatCount="indefinite"/>
    <animate attributeName="fill" from="green" to="yellow" dur="3s" repeatCount="indefinite"/>
    <animate attributeName="stroke" from="green" to="yellow" dur="3s" repeatCount="indefinite"/>
  </circle>
</svg>

animate要素の各属性の役割は以下のようになります。

属性 概要
attributeName アニメーションの対象となる属性名を指定します。
from アニメーションの開始時の属性値を指定します。
to アニメーションの終了時の属性値を指定します。
dur アニメーションの実行時間を指定します。
repeatCount アニメーションの実行回数を指定します。
青丸は repeatCount="5" としているので5回実行された時点で終了します。

animateMotion要素で変化を定義

animateMotion要素 を利用するとpathに従うアニメーションを実装できます。利用例を示します。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100"
     style="background-color: #ccc">
  <path d="M20,50 Q60,80 100,50 T180,50" fill="none" stroke="#000" stroke-width="2"/>
  <circle cx="0" cy="0" r="5" fill="red">
    <animateMotion path="M20,50 Q60,80 100,50 T180,50" dur="3s" repeatCount="indefinite"/>
  </circle>
</svg>

注意点

非常に簡単に実装できますが、IE Edge でサポートされていません(2019年3月時点)。

https://caniuse.com/#feat=svg-smil

「利用用途(モバイルのみなど)」と「サポートブラウザの状況」から利用するか判断する必要があります。

CSSでアニメーションを定義

transitionsプロパティで変化を定義

transitionsプロパティ は、hover のタイミングでアニメーションを実行したいケースに利用できます。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100" style="background-color: #ccc">
  <circle cx="100" cy="50" r="30" class="circle"/>
</svg>

<style>
.circle {
  fill: red;
  transition: fill, 0s, 3s;
}

.circle:hover {
  fill: green;
}
</style>

circleにマウスをあてると、3秒かけて緑色に変化します。

animationsプロパティで変化を定義

連続してアニメーションを実行したい場合、animationsプロパティ を利用します。

<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100" viewBox="0 0 200 100" style="background-color: #ccc">
  <!-- red -->
  <line x1="0" y1="25" x2="200" y2="25" style="stroke:#fff;stroke-width:5"/>
  <line x1="0" y1="25" x2="200" y2="25" class="line line-red"/>

  <!-- blue -->
  <line x1="0" y1="50" x2="200" y2="50" style="stroke:#fff;stroke-width:5;"/>
  <line x1="0" y1="50" x2="200" y2="50" class="line line-blue"/>

  <!-- green -->
  <line x1="0" y1="75" x2="200" y2="75" style="stroke:#fff;stroke-width:5;"/>
  <line x1="0" y1="75" x2="200" y2="75" class="line line-green"/>
</svg>


<style>
.line {
  stroke-dasharray: 100;
  stroke-width: 5;
}

.line-red {
  stroke: red;
  animation: key-line-red 1s linear 0s infinite;
}

.line-blue {
  stroke: blue;
  animation: key-line-blue 3s linear 0s infinite;
}

.line-green {
  stroke: green;
  animation: key-line-green 1s steps(5, end) 0s infinite alternate;
}

@keyframes key-line-red {
  0% {
    stroke-dashoffset: 0;
  }

  100% {
    stroke-dashoffset: 200;
  }
}

@keyframes key-line-blue {
  0% {
    stroke-dashoffset: 200;
  }

  100% {
    stroke-dashoffset: 0;
  }
}

@keyframes key-line-green {
  0% {
    stroke-dashoffset: 25;
  }

  100% {
    stroke-dashoffset: 75;
  }
}
</style>

キーフレーム でアニメーションの流れを定義しています。

animationプロパティアニメーションさせたい要素キーフレーム を紐づけています。
animationプロパティ では、下記プロパティをまとめて指定しています。

プロパティ 概要
animation-name キーフレーム を指定します。
animation-duration アニメーションの実行時間を指定します。
animation-timing-function アニメーションの進め方を指定します。
animation-delay アニメーションを始めるまでの遅延時間を指定します。
animation-iteration-count アニメーションの実行回数を指定します。
animation-direction アニメーション完了後、逆方向に実行するか指定します。

JavaScriptでアニメーションを定義

<svg xmlns="http://www.w3.org/2000/svg"
     width="200" height="100"
     viewBox="0 0 200 100" style="background-color: #ccc">
  <line x1="0" y1="100" x2="200" y2="0" style="stroke:#fff;stroke-width:5" />
  <line x1="0" y1="100" x2="200" y2="0" class="line" id="targetLine" />
</svg>

<style>
.line {
  stroke-dasharray: 100;
  stroke-width: 5;
  stroke: red;
  animation: key-line-red 1s linear 0s infinite;
}
</style>

<script>
let offset = 0
const millisecond = 10
const line = document.querySelector("#targetLine")
setInterval(() => {
  offset += 1
  line.style['stroke-dashoffset'] = offset
}, millisecond)
</script>

JavaScriptでDOM操作しています。

GreenSockTimelineMax」や「vivus」などのライブラリを活用すると実装が楽になるケースもあると思います。

参考