【JavaScript/SVG】静的な図形を動かす!基本的な要素操作とアニメーション実装ガイド
※本ページのリンクにはプロモーションが含まれています。
こんにちは、Ryohei(@ityryohei)です!
SVG(Scalable Vector Graphics)は、Web上で高品質なベクターグラフィックを扱うためのXMLベースのフォーマットです。HTML内に直接記述できるため、JavaScriptによるDOM(Document Object Model)操作の対象となります。
静的なSVG図形に命を吹き込み、インタラクティブな Web 表現や高性能なアニメーションを実現するには、JavaScriptによるSVG要素の動的な操作が不可欠です。
本記事では、SVG要素の取得と属性の変更といった基本的なDOM操作から、SVG特有の座標系と変形の扱い、そしてJavaScriptを用いた滑らかなアニメーションの実装テクニックまでを、段階的に解説します。
SVGをJavaScriptで操作してみたいけど、HTML要素と同じように扱えるの?アニメーションの実装方法は?
上記の疑問にお答えします。
では、解説していきます。1. SVG要素の基本操作:DOMとしてのSVG
SVGの各要素(<circle>, <rect>, <path>など)は、HTMLの<div>や<span>と同じようにDOMノードとして存在します。したがって、標準のDOM APIを使って要素の取得や操作が可能です。
1.1. 要素の取得と属性の変更
JavaScriptからSVG要素を取得する方法は、HTML要素と全く同じです。
document.getElementById()document.querySelector()document.querySelectorAll()
そして、要素の描画を変更する場合、styleプロパティを使うこともできますが、SVGではsetAttribute()メソッドを使ってSVG固有の属性(fill, r, xなど)を変更することが一般的です。
HTML
<svg id="chart-svg" width="300" height="150">
<circle id="data-point" cx="50" cy="100" r="10" fill="teal" />
</svg>
JavaScript
const circle = document.getElementById('data-point');
// 属性の変更:色を青に、半径を20pxに拡大
circle.setAttribute('fill', 'blue');
circle.setAttribute('r', '20');
// 座標の変更
circle.setAttribute('cx', '150'); // X座標を50から150に移動
実行結果
See the Pen Untitled by ryohei (@intotheprogram) on CodePen.
1.2. 要素の動的な生成と追加
JavaScriptを使って新たなSVG要素を動的に生成し、既存のSVGコンテナ(<svg>タグ)に追加することで、データに基づくグラフなどを描画できます。
SVG要素を作成するには、document.createElementNS()を使います。通常のdocument.createElement()とは異なり、SVGの名前空間(Namespace)を指定する必要があります。
JavaScript
const svgNS = 'http://www.w3.org/2000/svg';
const svgContainer = document.getElementById('chart-svg');
// 新しい矩形(<rect>)要素をSVG名前空間で作成
const newRect = document.createElementNS(svgNS, 'rect');
newRect.setAttribute('x', '200');
newRect.setAttribute('y', '50');
newRect.setAttribute('width', '50');
newRect.setAttribute('height', '50');
newRect.setAttribute('fill', 'orange');
// SVGコンテナに追加
svgContainer.appendChild(newRect);
実行結果
See the Pen 8289-2 by ryohei (@intotheprogram) on CodePen.
2. SVG特有の変形:transform属性の操作
SVG要素の位置や回転、拡大縮小といった変形を行うには、CSSのtransformプロパティと似たSVG固有のtransform属性を使います。
2.1. 変形属性(transform)の基本構文
transform属性は、複数の変形関数をスペース区切りで記述します。
| 変形関数 | 意味 |
translate(x, y) | 要素をX方向にx、Y方向にyだけ平行移動させる。 |
scale(s) | 要素をs倍に拡大・縮小させる。 |
rotate(angle) | 要素をangle度回転させる。 |
JavaScript
const rect = document.getElementById('my-rect');
// 矩形をX軸に50px移動し、45度回転させる
rect.setAttribute('transform', 'translate(50, 0) rotate(45)');
実行結果
See the Pen Untitled by ryohei (@intotheprogram) on CodePen.
2.2. 動的な変形:座標と値の計算
SVG要素をユーザーの操作や計算結果に基づいて動かすには、JavaScriptで変形値を計算し、それをtransform属性に動的に適用します。
例えば、円をマウスの位置に合わせて移動させるには、イベントリスナー内で計算を行います。
JavaScript
const circle = document.getElementById('data-point');
// マウス移動イベントにリスナーを設定
document.addEventListener('mousemove', (event) => {
// 画面座標 (clientX, clientY) を取得
const newX = event.clientX;
const newY = event.clientY;
// SVGの属性を更新して円を移動
circle.setAttribute('cx', newX);
circle.setAttribute('cy', newY);
});
実行結果
See the Pen 8389-3 by ryohei (@intotheprogram) on CodePen.
- 補足:厳密には、画面座標をSVGのビューボックス座標に変換する処理が必要になる場合があります。
3. JavaScriptによる滑らかなSVGアニメーション
SVGアニメーションにはCSS AnimationやSMIL(非推奨)など複数の手法がありますが、JavaScriptを使うと、複雑なロジックやデータに基づいたより柔軟なアニメーション制御が可能です。
3.1. requestAnimationFrameの利用
滑らかなアニメーションを実現するための最善の方法は、ブラウザに最適化された描画サイクルに合わせて処理を行うrequestAnimationFrame (rAF) を利用することです。
rAFは、画面が更新される直前(通常は1秒間に60回、60fps)に関数を実行するため、ブラウザの負荷を抑え、カクつきのないアニメーションを実現します。
JavaScript
const rect = document.getElementById('my-rect');
let rotation = 0;
function animateRotation() {
rotation += 2; // 角度を2度ずつ増加
// transform属性を更新
rect.setAttribute('transform', `rotate(${rotation}, 50, 50)`); // 50,50を中心に回転
// 次のフレームで再度この関数を実行するようブラウザに要求
requestAnimationFrame(animateRotation);
}
// アニメーション開始
requestAnimationFrame(animateRotation);
実行結果
See the Pen 8389-4 by ryohei (@intotheprogram) on CodePen.
3.2. イージング(Easing)の実装
アニメーションにリアルさや魅力を加えるためには、動きに緩急(イージング)をつけることが重要です。JavaScriptでは、時間の経過を表す0から1までの値(線形)を、緩急を示す別の値(非線形)に変換する計算関数(イージング関数)を自作または利用します。
JavaScript
// 例: イーズアウト関数 (最初速く、徐々に遅くなる)
function easeOutQuad(t) {
return t * (2 - t);
}
// アニメーションループ内で使用
function animatePosition(timeFraction) {
// timeFraction (0から1) をイージング関数に通す
const progress = easeOutQuad(timeFraction);
// progressに基づいて位置を計算し、SVG属性に適用
// ...
}
最後に
SVGをJavaScriptで操作することは、モダンなWebアプリケーションで高性能なグラフィック表現を行うための基本です。
- 要素操作:
setAttribute()を使ってSVG固有の属性を操作しましょう。 - 変形:
transform属性を使って、位置(translate)や回転(rotate)を制御しましょう。 - アニメーション:
requestAnimationFrame(rAF) を利用し、ブラウザに優しい滑らかなアニメーションを実現しましょう。
これらの基本操作とテクニックを習得することで、静的な図形をユーザーと対話する動的な表現へと進化させることができるでしょう。
以上、SVGの基本的な要素操作とアニメーション実装ガイドのご紹介でした!