SVGでloaderをつくる

1. はじめに

こんにちは。エンジニアのミツモトです。
普段はTUNAGという社内SNSサービスのバックエンドを担当しています。
フロントエンドの業務も行いますが、触れる機会が少なく、たまには動くものを作ってみたい!と思い、今回はSVGでloaderを作りました。

2. つくったもの

See the Pen svg loader by mitsumoto (@mmoto) on CodePen.

3. SVGとは

  • Scalable Vector Graphicsの略
  • ベクター画像(JPEGやPNGなどのラスター画像と異なり、伸縮しても画質が劣化しない)を XML で記述するための言語
  • W3C(World Wide Web Consortium)により勧告
  • 図形(ex. 直線・曲線・円)、画像、 テキストを扱い、それらのオブジェクトをグループにまとめたり、スタイリングできる
  • onmouseover や onclick などの多彩な イベントハンドラ を、任意の SVG オブジェクトにあてることができる

Scalable Vector Graphics (SVG) 1.1 (第2版)概要

Can I Use
どのブラウザでも、最新のversionであればSVGに対応しています。

4. 図形を描画する

4-1. SVGタグ

svgタグは、他のXMLであるXHTMLやMathMLタグとの名前の衝突を避けるため、


xmlns="http://www.w3.org/2000/svg"

と記述します。

これにより名前空間を指定し、自分と子要素がsvgであることを示します。(HTML5では省略できます。)

SVGプロパティ 説明
width 描画領域の幅
height 描画領域の高さ
viewBox “x y width height” x:表示領域の左上角 x座標
y:表示領域の左上角 y座標
width:(描画領域に対する)表示領域の相対的な幅
height:(描画領域に対する)表示領域の相対的な高さ

viewBoxの設定は分かりづらいため、今回は表示領域の位置を(x,y)=(0,0)とし、描画領域と表示領域のサイズを合わせます。
数値に単位がない場合、SVGではpxになります。

4-2. 線の描画

線の起点と終点を座標で指定し、描画します。

See the Pen line by mitsumoto (@mmoto) on CodePen.

lineプロパティ 説明
x1 起点のx座標
y1 起点のy座標
x2 終点のx座標
y2 終点のy座標
stroke 線色の指定

4-3. 矩形の描画

矩形の幅や高さ、座標、角の丸みを指定して描画します。

See the Pen rect by mitsumoto (@mmoto) on CodePen.

rectプロパティ 説明
width
height 高さ
x 左上角 x座標
y 左上角 y座標
rx 角のx方向丸み
ry 角のy方向丸み
fill 塗りつぶし色の指定

4-4. 円の描画

See the Pen circle by mitsumoto (@mmoto) on CodePen.

circleプロパティ 説明
cx 円中心 x座標
cy 円中心 y座標
rx 円の半径

4-5. パスの描画

指定した座標を順番に線で結び、描画します。

See the Pen path by mitsumoto (@mmoto) on CodePen.

pathコマンド 説明
M x,y パスの起点 座標
h x 水平方向にx座標まで直線を描画
v x 鉛直方向にy座標まで直線を描画
l x,y x,y座標まで直線を描画
c x1,y1 x2,y2 x,y 3次ベジェ曲線を描画
x1,y1:曲線の起点に対する制御点の座標
x2,y2:曲線の終点に対する制御点の座標
x,y:終点の座標

コマンドは大文字だと絶対座標、小文字だと1つ前の座標からの相対座標になります。
上記以外にも、ベジェ曲線を描く q , t , sコマンドや、円弧を描く a といったコマンドがあります。

5. loaderをつくる

「2. つくったもの」の内、右側のドミノ倒しのようなloaderのつくり方を説明します。
はじめに矩形を描画します。

See the Pen domino1 by mitsumoto (@mmoto) on CodePen.

これにアニメーションをつけていきます。
まず水平方向に移動させます。


animate attributeName="x" values="10;100" dur="1.2s" begin="0.8s" repeatCount="indefinite"
animateプロパティ 説明
attributeName アニメーションの対象属性
values 変化させる属性値( ; で区切ります)
dur アニメーションの1ループにかける時間
begin アニメーションの開始時間
repeatCount 繰り返し回数(indefinite:無限に繰り返し)

0.8sec経過後にアニメーションが始まり、1.2secかけて水平方向にx=10から100へ移動するアニメーションが繰り返されます。

See the Pen domino2 by mitsumoto (@mmoto) on CodePen.

次に矩形を回転させ、不透明度を変化させます。


animateTransform attributeName="transform" type="rotate" from="0 10 70" to="-60 100 70" dur="1.2s" begin="0.8s" repeatCount="indefinite"
attributeName="opacity" values="0;1;0" dur="1.2s" begin="0.8s" repeatCount="indefinite"
animateTransformプロパティ 説明
type 変化の種類
from アニメーションの開始時の属性値
type:rotateの属性値(d, x, y)
d: 回転角
x: 回転の中心点x座標
y: 回転の中心点y座標
to アニメーションの終了時の属性値

不透明度はattributeNameプロパティを”opacity”とし、valuesを0〜1の間で指定します。

See the Pen domino3 by mitsumoto (@mmoto) on CodePen.

最後にアニメーションの開始時間をずらして複数表示させることで、ドミノが倒れているようなアニメーションにします。

See the Pen domino4 by mitsumoto (@mmoto) on CodePen.

6. おわりに

SVGを用いてloaderをつくりました。細かな部分へのこだわりがサービスへの愛着に繋がると思うので、デザインには一層気を配りたいと思います。スタメンではエンジニア、デザイナーを募集しています。興味がある方はこちらをご覧ください。