SVGを使おう!

2589 0
みなさまはもう使ってらっしゃいますか?SVG(Scalable Vector Graphics-スケーラブル・ベクター・グラフィックス)。

SVGはWEB上にベクターグラフィックスを描く技術で、ベクターグラフィックという性質上どれだけ拡大しようと、常に鮮明なグラフィックを描画できます。当然Retinaディスプレイなど高解像度ディスプレイでもボケない。 そして、Illustratorで作成したベクターデータを直接書き出せるという、グラフィックデザイナーにこそ使ってほしい技術であり、Webデザイナーさんにとっても慣れれば作業を大きく効率化してくれる助けになります。
今回はSVGのおもしろさとSVGを使ったいろいろなテクニックを紹介しつつ、ちょっと慣れ親しんでいただければと思います。

まずはじめに

SVGには
・「画像」として読み込むスタンドアロンSVG(<img>要素で記述)と
・xml文章として埋め込むインラインSVG(<svg>要素で記述)があります。

スタンドアロンSVGは手軽に使える為、よく使われていますが 個人的にはスタンドアロンではSVGのいちばんのおいしいところが使えないので旨味が少ないかな・・と考えています。 そこで、こちらではインラインSVGの扱いについてお話ししていきます。

SVGを用いてできること

  • 解像度に左右されない均一な表示
  • SVGスプライト
  • cssによるスタイル変更
  • ラインモーション、バリエーションに富んだアニメーション
  • 描画要素のグルーピング

解像度に左右されない均一な表示

vector-and-bitmap

「ベクターグラフィック」と言えばデザイナー諸氏ならお分かりになるでしょうが、「拡大縮小、変形しても解像度に見合った画質が維持される」形式ですね。

jpgなどの「ビットマップ」画像はディスプレイ解像度に依存します。その為、従来の4倍のピクセル密度を持つRetinaディスプレイをはじめとする、昨今の高解像度ディスプレイ(最近のスマートフォンやタブレットのディスプレイはほとんどこちらになっています。)では解像度が足りず、にじんだようにボケます。

そんな見づらく、不細工なものを表示させたくありませんよね?
実際、見づらい(画像内の文字などは判別不能になるケースもある)ので、ユーザビリティの観点からも高解像度ディスプレイへの対応はしっかりしておくべき。
jpgなどのビットマップ画像で対応させようとした場合、サイズが倍の画像を縮尺して表示させる・・といった方法になります。サイズも大きくなってしまいますし、「2種類の画像を出し分ける」という面倒な設定も必要だったりします。しかし、「ベクターグラフィックス」であれば解像度(ピクセル密度)に左右されず画質は維持されます。つまり、SVGはこれからのWeb・・特にモバイルを意識した制作には大変効果的なものであると考えられています。

SVGスプライト + cssによるスタイル変更

SVGをとても使いやすいものにしてくれるテクニックが、この「SVGスプライト」です。

「cssスプライト」という沢山の画像を一つの画像にして、リクエスト回数を減らす(=ページの表示速度向上)テクニックがありますね。
先のWebクリエーターボックスさんの記事で書かれていましたが、SVGでも似たようなことができます。
ただ、SVGのスプライトはcssスプライトより使い勝手が良く思います。 個人的には、慣れれば圧倒的にこちらのほうが便利で楽。(あれこれ計算する必要もほとんど無いですし・・)

このブログでも記事下のソーシャルボタンやブログタイトル部分(※現在はStory Tellingのテーマのみ)にSVGスプライトを使用しています。
下記に並べたアイコンもすべて記事下のソーシャルボタンと同じスプライトから読みだしていますが、このように必要に応じてスタイルを変更することができます。
変更もcssで指定するだけで可能という大変便利な仕様です。(※グラデーション、ドロップシャドウはcssで指定できません。SVGの「filter」で。)

facebookアイコン facebookアイコンType2 facebookアイコンType3 facebookアイコンType4
<!--あらかじめ読み込んでおく(WordPressならbody直下)-->
<svg class="defs" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
  <symbol id="icon-facebook" viewBox="0 0 32 32">
	<path class="path1" d="M24 6.606h-4.57c-0.541 0-1.144 0.71-1.144 1.662v3.299h5.714v4.704h-5.714v14.128h-5.395v-14.126h-4.891v-4.706h4.891v-2.768c0-3.97 2.755-7.2 6.538-7.2h4.571v5.006z"></path>
  </symbol>
</defs>
</svg>

<!--使用する際は以下のように。Html,php内の任意の場所へ-->
<svg class="icon">
  <title>facebookアイコンType1</title>
  <use xlink:href="#icon-facebook"></use>
</svg>

<svg class="icon radius">
  <title>facebookアイコンType2</title>
  <use xlink:href="#icon-facebook"></use>
</svg>

<svg class="icon blue">
 <linearGradient id="grad"  gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop stop-color="#3B5998" offset="0"/><stop stop-color="#1d2c4c" offset="1"/>
  </linearGradient>
  <title>facebookアイコンType3</title>
  <use xlink:href="#icon-facebook"></use>
</svg>

<svg class="icon grad">
  <title>facebookアイコンType4</title>
  <use xlink:href="#icon-facebook"></use>
</svg>

See the Pen ブログ用-SVGスプライトサンプル by Manabu (@Manabu-Fukai) on CodePen.

SVGは少し記述の仕方にクセがあるので、最初の頃は難しそうに感じると思います。 とはいえ構文のルールさえ分かってしまえばHtmlとさほど変わらず、「ただ専用のタグを使うだけ」のことなのですぐに慣れると思います。

SVGスプライトを使用する際は<body>の直下などであらかじめスプライトファイルを読み込んでおきます。そして、使用したい箇所で

<svg>タグを用いて<use />要素で利用します。

違うスタイルで使用したい際は、svgタグなどに個別のid,classを付与しスタイルを設定すればOKです。

これをjpgやpng、gifなどで行おうとすると、違う色を用いたい分だけ画像をつくる必要がありました。 それをたった一つのファイルで行えるということです。
このように、一つのデータをケースに応じて様々なパターンに使いまわせるのがSVGスプライトの魅力です。

※スプライトやグラフィックの使いまわし、後述の「応用」に関する詳しくは、また改めて記事にいたします。 (スプライト導入の方法は同記事をご覧いただくと難なくできると思いますので、今回は割愛させていただきます。)

svg-instance

こちらのロゴ部分もSVGで作成したものです。こちらはページによってロゴの一部の色が変わるという仕様になっていますが、こうしたものも一つのSVGデータに対しcssだけで切替えを設定できます。

このようなケースの場合、jpg他ではこの「4枚の画像をスプライトにする」などたった一か所・わずかな部分の違いでも新たにもう一つ全体の画像を用意する必要がありました。
また、少し変更を加えたい際はたった一か所の変更ですら新たに画像を作り直す+cssの変更など、非常に冗長な作業が多くありました。 パターンが増えれば5枚、6枚・・と増えていくためデータサイズもどんどん肥大化しますね。
加えて、あちこちのデータファイルを行き来する必要もある為、時間ロスも大きいものでした。

svg-using-example
「SVGなら、簡単・早い!」

これをSVGで行うと驚くほど作業ロスが軽減されます。
こちらの画像のように、変更箇所にidやクラスを付与し、ページによってスタイルを変更する・・という設定をcssで行うだけでOK。 ちょっとした変更ならcssの値をいじるだけで対応できますし、何かしら追加があった場合もパーツに新たにid,classを付与すれば対応可能になったりします。

  • ※注: 後付けのスタイル指定などはインラインSVGでのみ使用できます。スタンドアロンSVGでは利用できません。
  • ※実物を見ていただこうと思ったら・・・すみません・・参考用のサイト、まだオープンしていませんでした。。苦笑 たぶんもうすぐオープンするとは思うのですが、またオープンしたらこちらにリンクを追加いたします。

また、これらの性質からSVGでは一つのアートワークを複数の「パーツ」に分け、パーツ単位で呼び出すことができます(かつ、使う場所によってスタイルを都度変更もできる)。

例えば、こちらのロゴの「シンボルマーク」と「テキスト部分」を別々のパーツに分けることで 使用する箇所によってシンボルマークのみを呼び出したり、フルセットで呼び出したりを切替えつつ、都度スタイルの変更も可能です。

一つのファイルで行え、cssの指定で変更可能ということは、サイト全体のデータサイズダウンができる。 SVGのほうが(単体では)一般的な画像よりサイズがやや重くなりがちとはいえ複数枚の画像を使うより各段に軽くなります。 また、同じアートワークのカラーバリエーションやほんの少しの違いのバリエーションが複数必要になる際なども、一つのアートワーク作成でまかなえる為、作業効率も格段に上がります

ラインモーション、バリエーションに富んだアニメーション

※この項目は基本的にcss3に対応しているブラウザ用です。IE9以下のオールドブラウザではこの項目で述べているアニメーションには対応していません。

前述の「応用」の箇所でも少し触れましたが、SVGではラインモーション・ラインアニメーションなども比較的容易に作成できます。

もちろん、直線に限らず、曲線・多角形の線でも可能です。

こちらもロゴの箇所で触れたサイトで使ったものですが、

  • stroke-dasharray(線の長さ)
  • stroke-dashoffset(塗りの始点)

という2つのプロパティとtransitionやanimationなどを使うことで様々なアニメーションが可能です。

そして、冒頭のアイキャッチ画像がいつもと比べてかなりにぎやかなものになっていたかと思います。
こちらはスタンドアロンSVG(画像として表示させるSVG)用に作成したモーショングラフィック(?)です。 (スタンドアロンSVGではインラインSVGに比べ、制限が非常に大きくなります。)

その「制限が大きい」状態でもこれくらいの表現ができますよ・・というところをご覧いただいたうえで 「同じSVGファイルをスタンドアロンとインラインでどれだけ表現を変えられるか」・・を見ていただこうと思ったのですが・・

冒頭のスタンドアロンSVGで最初の4秒ほどのキーフレームがすっ飛んで「ループ部分」だけの表示になってしまいます。。。 (キーフレームアニメーションが表示される時もあり・・スタンドアロンは不安定ですね。。※閲覧時のブラウザにもよります)
ということで、今回は予定を変えて下記にフル状態でご覧いただけるものを公開させていただくことにします。

See the Pen For Inline svg. animation DEMO by Manabu (@Manabu-Fukai) on CodePen.

こちらにカーソルオンすると左下に「RERUN」のボタンが表示されますので、そちらをクリックするとフル状態で閲覧できます。
追記:※モバイルではパスのアニメーションに対応していないっぽいので多角形のパスアニメーションが表示されない模様です・・(アニメーションで表示/非表示を切り替えたので3つの多角形オブジェクトそのものが表示されない状態。。)

・・まぁ、ライブラリ使わなかったらこんなもんですかね。。
SVG単体で稼働させるように、内包されている<animate>要素(SMIL)のみで動かしていますが、SMILの記述方式に慣れていないのと、ソースそのものはお見せする予定ではなかったので、ちょっとグダグダな記述がちらほらありますが・・苦笑
参考までに・・。

スタンドアロンSVGでは(SVGから見て)外部のJavaScriptやcssでのアクセスはできないうえ、画像などの外部ファイルをSVG内に読み込ませるケースもほとんど対応していません。(※一部ブラウザでのみ表示可能)
基本的に、「すべてSVG(に用意されている要素)の中だけで処理しなさい」という状態です。

JavaScriptやcssも埋め込んで使うことができますが、画像として読み込ませた場合、その多くが無視されてしまう為、今回はスクリプトを埋め込まず純粋なSVG要素+<animate>要素のみで構成しています。
しかしながら、それでもSVGそのものに用意されているアニメーション要素も一部無視されたりします。(今回のループしないキーフレームアニメーションなども)

ちなみに、これだけのアニメーションを含ませたSVGファイルですが、ファイルサイズはたったの33kバイトです。 アニメーションgifで同様のものをつくるよりはるかに軽量になります。

インラインSVGとして使用する場合、今回のソースのような面倒かつ視認性の悪い記述をする必要はありません。
インラインSVGではjQueryやCreateJSをはじめ、様々なJavaScriptライブラリやcss3との親和性も高く、SVGそのものの描画をサポートするsnap.svgなどのライブラリも組み合わせて使うことができます。 これらのリソースと組み合わせて使うことで更に表現力は広がり、かつ記述の負担軽減など使い勝手の良いものになります。

まとめ

このように、SVGには高い表現力と機能性を持つ、機能的なものです。
グラフィックそのものの描画能力はcanvasのほうが高いとはいえ、それを補えるだけの様々な機能性もあります。 今回紹介しきれなかった特徴(要素のグルーピングも)も多々ありますが、追ってそれらについてもお話しさせていただきたく思います。

SVGを使用する利点

グラフィックのモジュール化

  • 一つのアートワークやグラフィックの部分部分をモジュール(部品)として再利用できる。
    色を変更したい、部分的に削りたいといった時はcssでスタイルを変更するだけで簡単に変更できる
  • 拡大縮小時も均一な画質で表示可能。(縮小しすぎは潰れるので限界はあります)

メンテナンス性の向上

  • 高解像度ディスプレイも同一ファイルで対応可能。
  • グラフィックに変更があった場合にもほとんどがcssで対応できる。
  • テキストエディタでも編集可能。グラフィックソフト無しでも内容を書き変えれば後からいくらでも変更可能。(パスの形状もなれればテキストエディタ上で修正可能)
    簡単なところでいえばグループの追加・削除。パーツ分けを後から指定しなおすことも容易。
  • いくつものファイルを修正する必要なく、一つのファイルの修正のみで対応できる為時間と労力のロスが少なくなる。

読み込みファイルの数が減る=リクエスト回数が減る

サイトやページの表示速度は全体のデータ「サイズ」とファイル「数」が大きく影響します。 同時に読み込めるファイル数には上限がある為、その上限数読みこんでいる最中は 他のファイルは読み込まれない。=結果ページ表示までの時間が延びる

一つのファイルで多くをまかなえる為、全体のファイル数ダイエットにも大変効果的。

まだSVGを使ったことがない方も、これを機に「ちょっとやってみようかな・・?」と思っていただけると幸いです。

Comments

Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

認証コード * Time limit is exhausted. Please reload CAPTCHA.