• Web

GIF画像不要!SVGで作成するローディングアニメーション

SVG Loader

SVGとは、XMLベースのベクターイメージ用の画像形式で、アニメーションなどをサポートしています。
Webで使われている一般的な画像(png、jpeg、gif)はビットマップ形式といって、拡大縮小すると劣化してしまうのですが、このベクター形式は画像が劣化しません。
昔からある技術ですが、スマホの普及などで高解像度のデバイスや、ディスプレイが出てきたことにより、少し前から注目され、Web上で使用されるようになってきました。

今回はこのSVGを使用して、今までgifで使用していたローディング画像を置き換えたいと思います!


1. デモ

SVG Loader

ベーシックな感じのローディング画像を用意しました。まずはデモをご覧ください。
IEでは動作しませんので、別のブラウザをお使いください。

2. SVGアニメーション対応のブラウザ

Can I Use SVG SMIL Animation

今回使用するSVGのアニメーションはIEが!なんと!!全滅です。
IEはいつまでたってもIEです。逆に格好良い。

3. SVGをIEに対応させるためには

Javascriptライブラリが必要になります。下記はその紹介ですが、今回は使用しません。

SIE

IE8〜の対応で静止画だけの場合は「SIE」という国産のJavascriptライブラリがあります。今回はアニメーションなので必要ないですが、アニメーションを使わない時には非常に便利です。

Raphaël.js

IE6〜対応したい場合は「Raphaël.js」というのがありますが、これをIE6で使うと非常に重い!
最近はIE8〜サポートのサイトばかりだと思うので、その辺にボーダーラインを置くなら、導入の余地はあるかもしれません。「Raphaël」はこれ以上の開発は期待できないので、それも踏まえて検討してください。

Snap svg

IE9からのサポートを考えているならAdobe社から提供されている「Snap.svg」が良いかと思います。作者は「Raphaël」と同じ方らしいです。これから覚えたい方はこちらがいいと思います。

4. Illustrator(イラストレーター)でSVGを作成する

イラレで変換

作りたいローディングの画像を探して、イラレでこんな感じにトレースしてしまいましょう!トレースが終わったら「別名で保存」→「ファイル形式」→「SVG」で保存してください。
ある程度綺麗にしていまいましたが、SVGのコードを見ると下記のような感じになっているかとおもいます。

<svg width="48px" height="48px" viewBox="0 0 48 48">
	<g fill="#FFFFFF">
		<rect x="22" y="1" width="4" height="12" transform="rotate(0,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.92" transform="rotate(330,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.84" transform="rotate(300,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.76" transform="rotate(270,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.68" transform="rotate(240,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.6" transform="rotate(210,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.52" transform="rotate(180,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.44" transform="rotate(150,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.36" transform="rotate(120,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.28" transform="rotate(90,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.2" transform="rotate(60,24,24)"/>
		<rect x="22" y="1" width="4" height="12" opacity="0.12" transform="rotate(30,24,24)"/>
	</g>
</svg>

「48×48」のボックス内に「幅4px」「高さ12px」の長方形をボックスの中央を起点として「30°」づつずらした長方形を12個作成しています。
「rect」は「長方形」、「transform=”rotate(0,24,24)”」は「transform=”回転(角度,X座標起点,Y座標起点)”」という意味です。

5. SVGにアニメーションをつける

まず「rect」にある「/」部分を削除し「/rect」を足します!その間にアニメーションを挿入していきます。

<rect x="22" y="1" width="4" height="12" transform="rotate(0,24,24)">
	<animateTransform
	attributeName="transform"
	repeatCount="indefinite"
	type="rotate"
	dur="1.2s"
	calcMode="discrete"
	values="0 24 24;
		30 24 24;
		60 24 24;
		90 24 24;
		120 24 24;
		150 24 24;
		180 24 24;
		210 24 24;
		240 24 24;
		270 24 24;
		300 24 24;
		330 24 24 "/>
</rect>

これで長方形が30°づつ一気に変化し、360°になったときに1.2s経っていることになります。
animateTransform要素の使い方はアニメーションさせたい要素の子要素として配置するか、今回は使用しませんが、idを指定することでアニメーションさせる方法があります。では属性をそれぞれ説明します。

attributeName

アニメーションの対象となる属性名を記述します。ここでは回転させたいので「transform」とします。

repeatCount

アニメーションの繰り返し回数の設定で、「回数」か「indefinite(ずっと繰り返す)」を指定できます。

type

変形の種類を設定できます。「rotate(回転)」「translate(移動)」「skewX(X座標の斜傾)」「skewY(Y座標の斜傾)」「scale(拡大・縮小)」を指定できます。

dur

アニメーションの時間を設定できます。ここでは「1.2s」としてますが、ミリ秒を使用したい場合は「800ms」と記述します。

calcMode

値の変化の関数で「discrete」「linear」「paced」「spline」を指定できます。それぞれ「一気に変化」「徐々に変化」「from値からto値に変化」「曲線による変化(values、keyTimes、keySplinesと一緒に使用する)」となってます。ここでは「discrete(一気に変化)」を適用しています。

values

変化の値のリストで、セミコロン(;)で区切ります。「type」によって設定する値が変わります。「rotate」を設定しているので「角度 X座標起点 Y座標起点」の値を入れています。

6. ローディング完成

他の「rect」にもアニメーションを挿入します。

<rect x="22" y="1" width="4" height="12" transform="rotate(0,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.92" transform="rotate(330,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.84" transform="rotate(300,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.76" transform="rotate(270,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.68" transform="rotate(240,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.6" transform="rotate(210,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.52" transform="rotate(180,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.44" transform="rotate(150,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24; 120 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.36" transform="rotate(120,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24; 90 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.28" transform="rotate(90,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24; 60 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.2" transform="rotate(60,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24; 30 24 24"/>
</rect>
<rect x="22" y="1" width="4" height="12" opacity="0.12" transform="rotate(30,24,24)">
	<animateTransform attributeName="transform" repeatCount="indefinite" type="rotate" dur="1.2s" calcMode="discrete" values="30 24 24; 60 24 24; 90 24 24; 120 24 24; 150 24 24; 180 24 24; 210 24 24; 240 24 24; 270 24 24; 300 24 24; 330 24 24; 0 24 24"/>
</rect>

「values」の値が「rect」ごとに若干変わるはずなので、注意してください。
わからないことや、もっと違うことをしたい方はこちらのサイトが参考になりますよ!

6. 最後に

SVGのローディングアニメーションは最近では素材としてもWeb上にあります。

自分の思い描いているものが見つからない場合は作ったほうが早いでしょうが、こだわりが無ければ素材を活用するのも時間短縮になりますし、良いかと思います。

  • このエントリーをはてなブックマークに追加

記事を書いた人

前川

Webディレクター / デザイナー

前川 洋輝

Hiroki Maekawa

高校生のとき、窓際の席でよく外をみてボーッとしてたら、友達から「いつもどこみてるの?」ときかれて「宇宙かな・・・」といったら「サイコ野郎」と言われてしまうくらい痛い青春時代を送りました。青春を取り戻すため、タイムマシンを作れる人を探す活動をしています。

コメント

コメントする

ブログカテゴリー

TOP