元Webデザイナー兼コーダーの備忘録

HTML,CSSの入門記事やブログのカスタマイズについてアウトプットしています。

 メニュー

【SVG】サンプルアニメーション:円

SVGでできる簡単なサンプルアニメーションを書きます。今回は、円のアニメーションです。さらに柔軟な表現ができるように、JavaScriptと絡めていきます。SVGJavaScriptで、表現の幅が広がることを感じられたら幸いです。

円のアニメーションのサンプル

今までやってきた内容を組み合わせると、様々な図形のアニメーションが作れます。アイデア次第では色々と作れるので、面白いと思います。一例として、以下に円のアニメーションのコードとデモを示します。

コード

<svg version="1.1" width="300px" height="300px" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<g>
  <circle cx="150" cy="75" r="10"/>
  <circle cx="225" cy="150" r="10"/>
  <circle cx="150" cy="225" r="10"/>
  <circle cx="75" cy="150" r="10"/>
  <animateTransform attributeName="transform" type="rotate" from="0,150,150" to="360,150,150" dur="3s" repeatCount="indefinite" />
</g>
</svg>

デモ

以下は、上記のコードのデモです。円が回転するアニメーションです。

JavaScriptSVGの要素を生成する

JavaScriptが使えると、手動では難しい表現が可能になります。SVGのタグをJavaScriptで生成し、パラメータを与えたり、動きを制御できると、表現の可能性が広がるのではないでしょうか。

上記のデモでは、円を4つ用意しました。4つくらいなら手動で書けるかもしれません。しかし、10個、20個、それ以上の円が必要な場合を考えると手動で用意するのは難しいです。また、個数の増減があるとその都度パラメータ(ここでは、cxやcyなど)を手動で計算して、与えないといけません。これは、現実的ではありません。

コード

JavaScriptを使って円を生成するようにすると、沢山の円を用意することができます。

<svg version="1.1" id="svg" width="300px" height="300px" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">

<g id="loadingIcon"></g>

<script type="text/ecmascript"><![CDATA[

const SVG = 'http://www.w3.org/2000/svg';
const svg = document.getElementById('svg');
//文字列を分割して、数字部分を取得。文字列から数値に変換(ex.100px→100)
const svgWidth = (svg.getAttribute('width').split("px")[0]) - 0;
const svgHeight = (svg.getAttribute('height').split("px")[0]) - 0;
const loadingIcon = document.getElementById('loadingIcon');

//svg要素オブジェクトのデータ
const canvas = {
  width: svgWidth,  //svgの領域の幅
  height: svgHeight,  //svgの領域の高さ
  cx: svgWidth/2,  //svgの領域の中心座標:x
  cy: svgHeight/2,  //svgの領域の中心座標:y
  getCx: function(){ return this.cx; },
  getCy: function(){ return this.cy; },
};

//circleオブジェクトのパラメータ
const circleParam = { cx: 150, cy: 75, r: 10, size: 8 };

//円の生成
function Circle(){
  const circle =  document.createElementNS(SVG, 'circle'); //circle要素の生成
  circle.setAttribute('cx', circleParam.cx);
  circle.setAttribute('cy', circleParam.cy);
  circle.setAttribute('r', circleParam.r);
  loadingIcon.appendChild(circle);
}

//円を複数生成
function createCircle(){
  for(let i = 0; i < circleParam.size; i++){
    Circle(); //circle要素の生成
  }
}

//円に色を付ける
function grayScale(circlesElem){
  let l = 0;
  const diff = parseInt(100 / circleParam.size);
  for(var i = 0; i < circlesElem.length; i++){
    circlesElem[i].setAttribute('fill', `hsl(120, 0%, ${l}%)`);
    l += diff;
  }
}

//円を環状に配置する
function rotate(circlesElem){
  let a = 0;
  const deg = parseInt(360 / circleParam.size);
  for(var i = 0; i < circlesElem.length; i++){
    circlesElem[i].setAttribute('transform', `rotate(${a} ${canvas.getCx()} ${canvas.getCy()})`); //キャンバスの中心が基準
    a += deg;
  }
}

function setup(){
  createCircle(); //円の生成
  const circles = document.getElementsByTagName('circle'); //円の取得
  grayScale(circles);  //円に色を付ける
  rotate(circles); //円を環状に配置する
}
setup();

]]></script>
</svg>

デモ

以下の画像は、上記のコードで円を生成したときの例です。円の数が8個、24個、100個の場合を用意しました。また円の色が、黒から白にグラデーションするようなコードを追記しました。

このように、JavaScriptが書けると好きな数だけ円を生成できるようになります。今回は用意していませんが、JavaScriptでアニメーションの指定もできます。JavaScriptを使うと、SVGのアニメーションだけでは難しかった表現ができるのではないでしょうか。

余談

大変お恥ずかしいのですが、今回、コードを載せました。JavaScriptを勉強しているのですが、今の実力だと本記事に掲載のようなコードが精一杯です。もっと良い書き方が他にあると思うので、引き続き勉強していきます。