SVGアニメーションを用いると、さまざまなサイズのディスプレイで印象的なマイクロインタラクションを実現できます。マイクロインタラクションはUI改善にも役立ちます(参考記事『SVGで始めるマイクロインタラクション入門』)。実装方法にはCSS、JavaScript、動画作成ソフトなど、さまざまなアプローチがあります。
本記事では、HTMLコーダー、フロントエンドエンジニア、デザイナーの分野別に、SVGアニメーションの具体的な実装方法を紹介します。
【コーダー向け】CSSでSVGアニメーションを実現する方法

SVGはCSSプロパティによってグラフィックの見た目や形状を変更できます。次のコードでは、HTMLに記述した円のスタイルをCSSで更新しています。
<circle id="myCircle" r="50" cx="270" cy="270" />
▲ index.html
#myCircle {
fill: blue;
}
▲ style.css
この性質を利用し、CSSのTransitionsやAnimationsでプロパティを徐々に変化させることで、SVGアニメーションを実現します。たとえば円(#myCircle)の塗り(fillプロパティ)の色を、1秒かけて赤色にするCSSは次のとおりです。
#myCircle {
transition: fill 1s;
&:hover {
fill: red;
}
}
▲ style.css
コーディングの様子は次のとおりです。
CSSによるアニメーションの実例1:ハンバーガーメニュー
次のデモは、CSSだけで実装したハンバーガーメニューです。ボタンをホバーすると、[とじる]ボタンへ変化します。
3本の線を移動・回転させ、中央の線を透明にするCSSは次のとおりです。ホバー時の変化にはTransitionsを使います。
.menu {
cursor: pointer;
.border {
stroke: #fff;
stroke-width: 45px;
stroke-linecap: round;
transition: var(--time);
transform-origin: center center;
}
/* 初期位置 */
.border1 {
transform: translateY(-100px);
}
.border3 {
transform: translateY(100px);
}
&:hover {
/* 1本目のボーダーは、ホバー時に回転させる */
.border1 {
transform: translateY(0px) rotate(45deg);
}
/* 2本目のボーダーは、ホバー時に透明にする */
.border2 {
opacity: 0;
}
/* 3本目のボーダーは、ホバー時に回転させる */
.border3 {
transform: translateY(0px) rotate(-45deg);
}
}
}
CSSによるアニメーションの実例2:いいねボタン
次のデモでは、円、パーティクル、ハートを組み合わせたアニメーションを確認できます。ボタンをクリックして再生してください。Xのいいねボタンのようなアニメーションとなります。

爆発では、stroke-widthプロパティ(線の太さ)とscale()関数(拡大率)を変化させ、円が広がる動きを表現します。
/* クリックされたら、爆発のアニメーションを開始 */
.likeButton.clicked .explosion {
animation: explosionAnime var(--animate-time);
animation-fill-mode: forwards;
}
/* 爆発のアニメーション内容 */
@keyframes explosionAnime {
0% {
opacity: 0;
transform: scale(0.01);
}
1% {
opacity: 1;
transform: scale(0.01);
}
5% {
stroke-width: 200;
}
20% {
stroke-width: 300;
}
50% {
stroke: #cc8ef5;
transform: scale(1.1);
stroke-width: 1;
}
50.1% {
stroke-width: 0;
}
/* 中略 */
}
ハートでは、縦方向・横方向のスケールを不規則に変化させて有機的な動きを作ります。こうした表現は、記事『CSS Animationだけで実現するキャラクターアニメーション』も参照ください。
/* クリックされたら、ハートのアニメーションを開始 */
.likeButton.clicked .heart {
animation: heartAnime var(--animate-time);
animation-fill-mode: forwards;
}
/* ハートのアニメーション内容 */
@keyframes heartAnime {
0% {
transform: scale(0);
}
/* 中略 */
75% {
transform: scale(1.1, 0.9) translate(0%, 5%);
}
80% {
transform: scale(0.95, 1.05) translate(0%, -3%);
}
100% {
transform: scale(1, 1) translate(0%, 0%);
}
}
パーティクルでは、sibling-index()関数で14個の円の並び順を取得し、CSSのcos()関数とsin()関数で移動先を計算します。円ごとに角度と半径をずらし、不規則な広がりを作ります。
CSSのアニメーションのメリットとデメリット
CSSによるSVGアニメーションのメリットは、JavaScriptによるプログラミングがほとんど不要なことです。CSSプロパティでアクセスできる塗りや線、拡縮・回転・移動であれば、手軽にアニメーションを実現できます。モーションパスのoffset-pathプロパティを使えば、指定したパスに沿った移動も可能です。
【コーダー向け】SMILでSVGアニメーションを実現する方法

SVGには、SMILにもとづくアニメーション要素が用意されています。CSSやJavaScriptを使わず、SVGのマークアップ内にコードを書くだけでアニメーションを実現できます。
円の塗りを1秒かけて赤色にする例は、次のとおりです。
<circle>
<animate attributeName="fill" to="red" dur="1s"></animate>
</circle>
▲ index.html
開始時と終了時のパスコマンドの構成をそろえてd属性を変化させれば、形状が徐々に変わる「モーフィング」も実現できます。
属性値の変化には<animate>タグ、回転・移動・拡縮などの変形には<animateTransform>タグ、パスに沿った移動には<animateMotion>タグをそれぞれ用います。
SMILの特徴
SMILはSVGのマークアップ内でアニメーションを完結できることが魅力です。塗りと線の変化、拡縮・回転・移動に加えて、パスの変形やパスに沿ったアニメーションも実現できます。
【エンジニア向け】JavaScriptでSVGアニメーション

SVG要素はDOMとして扱えるため、JavaScriptから属性やスタイルを変更できます。アニメーションには、ブラウザー標準のWeb Animations APIが利用できます。
たとえば、円の塗りを1秒かけて青色から赤色へ変化させるコードは次のとおりです。
const myCircle = document.querySelector("#myCircle");
const animation = myCircle.animate(
[
{ fill: "blue" },
{ fill: "red" },
],
{
duration: 1000,
fill: "forwards",
},
);
animate()メソッドでは、CSSアニメーションと同様にキーフレームと再生時間を指定します。戻り値のAnimationオブジェクトから、pause()、reverse()、cancel()などで再生を制御できます。
JavaScriptのメリットは、ユーザー操作やアプリケーションの状態に応じて、値やタイミングを動的に変えられることです。単純な状態変化にはCSS、再生制御やデータにもとづく処理にはJavaScriptというように、目的に応じて使い分けるとよいでしょう。
JavaScriptライブラリを使うと、タイムライン制御や複雑なイージングも効率的に実装できます。代表的なライブラリは、記事『現場で使えるアニメーション系JSライブラリまとめ』で紹介しています。
【応用編】CSSで線画アニメーションを実現する方法
応用例として、不動産のウェブサイトをイメージしたデモを用意しました。建物や街並みの線が少しずつ描かれ、最後に地図のピンが上から落下します。
stroke-dashoffsetで線を描く
SVGの各図形にpathLength="1"属性を指定し、ブラウザーが扱うパスの長さを1に正規化します。
<path pathLength="1" d="M57.4 528.1h1003.3" />
CSSではstroke-dasharrayプロパティとstroke-dashoffsetプロパティの初期値を1にし、stroke-dashoffsetを0まで変化させます。sibling-index()関数でSVG要素の並び順を取得し、線ごとに開始時間をずらします。
#city > :is(path, circle),
#map > path,
#mapPin > path {
stroke-dasharray: 1;
stroke-dashoffset: 1;
animation: drawLine var(--draw-duration) ease var(--draw-delay, 0s) forwards;
}
#city > :is(path, circle),
#map > path {
--draw-delay: calc((sibling-index() - 1) * var(--draw-delay-step));
}
@keyframes drawLine {
to {
stroke-dashoffset: 0;
}
}
モーションパスとlinear()関数でピンを落とす
地図のピンには、offset-pathプロパティで縦方向の移動経路を設定しています。offset-distanceプロパティを変化させると、その経路に沿ってピンが移動します。
イージングにはCSSのlinear()関数を使います。進行度が1を超えてから戻る値を指定することで、着地後に弾むような動きを表現できます。
#mapPin {
offset-path: path("M 462.5 -206.7 V 258.3");
offset-distance: 0%;
offset-rotate: 0deg;
offset-anchor: 463px 193px;
transform-origin: 463px 382px;
animation:
dropMapPin
0.7s
/* 座標の行き過ぎと縦横比の反動を作る */
linear(0, 0.189, 0.557, 0.89, 1.092, 1.162, 1.141, 1.083, 1.026, 0.989, 0.974, 0.976, 0.985, 0.994, 1.001, 1.004, 1.004, 1.003, 1.001, 1, 1)
1s
both;
}
@keyframes dropMapPin {
from {
offset-distance: 0%;
scale: 0.4 1.6;
}
to {
offset-distance: 86.02%;
scale: 1;
}
}
CSSモーションパスの詳しい使い方は、記事『CSSのoffsetプロパティで、楽しいパスアニメーションを作ろう』も参照ください。
【デザイナー向け】動画作成ソフトを使ってSVGアニメーションを実現する方法
Adobe After Effectsを使えば、コードを書かずにアニメーションを制作できます。
After EffectsでSVGアニメーションを書き出す(Bodymovin)
After Effectsと拡張機能「Bodymovin」を組み合わせると、アニメーションをJSON形式で書き出せます。ウェブページではLottieのJavaScriptライブラリがJSONデータを読み込み、SVGまたは<canvas>要素として描画します。

詳しい作り方は、記事『最新版! Lottieアニメーションの作り方 - After Effects編』も参照ください。
LottieによるSVGアニメーションの特徴
Lottieの魅力は、デザイナーがAfter Effectsで動きを調整できることです。JSONデータを手作業で変更するのは難しいため、基本的にはAfter Effects側で調整して再度書き出します。
はじめよう、SVGアニメーション
高解像度なディスプレイが主流になり、フラットデザインとも相性のよいSVGアニメーションは活躍の場面が多いです。ぜひ、この機会にSVGアニメーションに挑戦しましょう。
※この記事が公開されたのは9年前ですが、今月7月に内容をメンテナンスしています。

