はじめに
第14回の記事では、SVGファイル内にアニメーション動作を含み、そのSVGをuse要素で呼び出しても、アニメーションは動作しないことを紹介しました。
とはいえ、アニメーションを覚えたいなということで、今回は、SVGで作成した画像をSMIL、CSS、および、Java Scriptを使用してアニメーションしたいと思います。
今回実施する内容
SVGの円をSMIL、CSS、および、Java Scriptで拡大縮小します。
SMILでの円の拡大縮小
CSSでの円の拡大縮小
Java Scriptでの円の拡大縮小
ソースコード(Git Hub)
環境
OS: Windows 11 JP (64bit)
Edge: バージョン 150.0.4078.65 (公式ビルド) (64 ビット)
参考
用語
- SMIL
- Synchronized Multimedia Integration Language
- 同期マルチメディア統合言語
-
animate要素やanimateTransform要素でアニメーションを作る
1. SMILで円を拡大縮小
SMILのanimate要素を使って円の拡大縮小を実施します。
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="20" fill="#ff6b6b">
<animate attributeName="r" values="20;30;20" dur="1.4s" repeatCount="indefinite"></animate>
</circle>
</svg>
GitHub Copilotに「円を拡大縮小するSVGサンプルを作って」とお願いしたところ、こんなのができました。
animate要素の属性は、以下のような意味です。
| 要素 | 説明 | 今回の値 |
|---|---|---|
| attrbuteName | ターゲットの属性の名称。 | 「r」としましたので、circle要素のr属性がターゲットの属性ということです。 |
| values | アニメーションで適用される値のリスト。「;」で区切る。 | 「20;30;20」としましたので、circle要素のr属性である半径を20⇒30⇒20に変更するという意味です。 |
| dur | シンプルな間隔。mediaやindefiniteも設定可能。 |
「1.4s」で1.4秒を設定。 |
| repeatCount | 繰り返し数を設定。indefiniteも設定可能。 |
「indefinite」を設定し、無限に繰り返す。 |
上記はcircleの半径を20⇒30⇒20に1.4秒の間の拡大縮小し、それを無限に繰り返すという動作です。
animate要素で利用可能な属性は、たくさん存在しており、上記はそれのごく一部です。
詳しくは、4.1. The animate elementを参照。
CSSファイルも作成されましたが説明を割愛します。
2. CSSで円を拡大縮小
1と同じ内容をCSSを使用して、円を拡大縮小します。
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle id="myCircle" cx="50" cy="50" r="20" fill="#ff6b6b">
</circle>
</svg>
「1. SMILで円を拡大縮小」のソースで、circle要素からanimate要素を削除し、id="myCircle"属性を追加しました。
#myCircle {
animation: zoominout 1.4s infinite;
}
@keyframes zoominout {
0% {
transform: scale(1);
transform-origin: center center;
}
50% {
transform: scale(1.5);
transform-origin: center center;
}
100% {
transform: scale(1);
transform-origin: center center;
}
}
#myCircleは、circle要素に付与したid属性の値です。
animation: zoominout 1.4s infinite;で、zoominoutのキーフレームを1.4秒間隔で無限に繰り返すという内容です。
zoominoutは、別途@keyframesで定義しています。
0%、50%、100%のときのアニメーションを定義しています。SMILでは、keytimes属性で設定すると思いますが、記載しないと均等になるようですが、CSSではこのように記載しました。
transform: scale(1)は、拡大1倍を意味し、同じくtransform: scale(1.5)は拡大1.5倍を意味します。
SMILでは、values="20;30;20"に相当する部分です。
transform-origin: center centerは、拡大縮小の位置をX軸中心、Y軸中心としています。
SMILでは、rの拡大縮小を設定していただけですが、指定方法が違いますね。
「今回実施する内容」に動画を載せていますが、SMILと同じ程度の設定でも拡大縮小の動作は微妙に違いました。
CSSのほうが拡大しきった後少しだけ止まっているようにも見えます。
3. Java Scriptで円を拡大縮小
1と同じ内容をJava Scriptを使用して、円を拡大縮小します。
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle id="myCircle" cx="50" cy="50" r="20" fill="#ff6b6b">
</circle>
</svg>
「1. SMILで円を拡大縮小」のソースで、circle要素からanimate要素を削除し、id="myCircle"属性を追加しました。
let myCircle = document.getElementById("myCircle");
window.addEventListener("DOMContentLoaded", () => {
const animation = myCircle.animate(
[
//キーフレーム
{ offset:0,
transform: 'scale(1)',
transformOrigin: 'center center'
},
{ offset:0.5,
transform: 'scale(1.5)',
transformOrigin: 'center center'
},
{ offset:1,
transform: 'scale(1)',
transformOrigin: 'center center'
}
],
{
//タイミングオプション
duration: 1400,
iterations: Infinity
}
);
});
Java Scriptの記載内容は、ほとんどCSSと同じ内容です。
「今回実施する内容」に動画を載せていますが、SMILとJava Scriptの動きは同じように見えます。
SMIL、CSS、Java Script記載比較
厳密に同じではありませんが、設定方法を比較すると、以下の通りです。
| SMIL | CSS | Java Script |
|---|---|---|
| values="20;30;20" | 0% { transform: scale(1);}50%{ transform: scale(1.5)}100%{transform: scale(1) | { offset:0, transform: 'scale(1)'}, {offset:0.5, transform: 'scale(1.5)'}, {offset:1, transform: 'scale(1)'} |
| attributeName="r" | transform-origin: center center; | transformOrigin: 'center center' |
| dur="1.4s" | 1.4s | duration: 1400 |
| repeatCount="indefinite" | infinite | iterations: Infinity |
仕様的なこと
SVGのアニメーションは、SVG 1.1 (Second Edition) 19 Animation辺りを参考にしました。
19.1 Introductionでは
19.1 Introductionでは、SVGをアニメーションする方法が大まかに記載されています。
Because the Web is a dynamic medium, SVG supports the ability to change vector graphics over time. SVG content can be animated in the following ways:
- Using SVG's animation elements. SVG document fragments can describe time-based modifications to the document's elements. Using the various animation elements, you can define motion paths, fade-in or fade-out effects, and objects that grow, shrink, spin or change color.
- Using the SVG DOM. The SVG DOM conforms to key aspects of the Document Object Model (DOM) Level 1 [DOM1] and Document Object Model (DOM) Level 2 [DOM2] specifications. Every attribute and style sheet setting is accessible to scripting, and SVG offers a set of additional DOM interfaces to support efficient animation via scripting. As a result, virtually any kind of animation can be achieved. The timer facilities in scripting languages such as ECMAScript can be used to start up and control the animations [ECMA-262]. (See example below.)
- SVG has been designed to allow SMIL [SMIL] to use animated or static SVG content as media components.
1つ目のブレッドでは、モーションパス、フェードイン・フェードアウト、グロー、シュリンク、スピン、もしくは、色の変更ができるといっています。
2つ目のブレッドで、SVG DOMを使用してアニメーションすることと、ECMA Script、すなわち、JavaScriptで制御できると言っています。
3つ目のブレッドで、アニメーションや静的SVGを使用するために、SMILを許容すると記載されています。
要するに JavaScriptやSMILを使用してアニメーションができるということらしい。
ここで、CSSについては言及されていない。
CSSによるアニメーションはSVG 2に明記があるようです。
おわりに
今回は、SVGの円の拡大縮小をSMIL、CSS、および、Java Scriptで実施してみました。
SMILの文法は少し慣れないですが、CSSやJava Scriptのほうは、以前から知っていた内容と同じで、SVG内の要素に対して設定するというだけの違いでしたので、簡単にできました。
次はもう少し見栄えのよさそうなアニメーションをトライしようと思います。


