読者です 読者をやめる 読者になる 読者になる

UUUM攻殻機動隊

UUUMのエンジニアによる技術ブログです

SVGの基本的な仕組みについて

どうも、えんじにあのやまぐちです。

先日UUUMで社内運動会が行われ、攻殻機動隊も数名参加しました。 未だに筋肉痛がとれず日常生活に支障がでていますが、普段動かない仕事なだけに久しぶりにスポーツをして楽しかったです。 ちなみに我らのCTOは女性参加型のドッジボールで全力投球をかましていました。

さて、今回の記事ですが、SVGについて書かせていただこうと思います。
3年前ぐらいからよく目にしていたのですが、閲覧環境が整っていない感があったので取り敢えずスルーしていました。しかし、弊社のWebサイトでもSVGが使用されていたのを発見したので、この機会にどういう仕組なのか少し調べてみました。

SVGとは

SVGとはScalable Vector Graphicsの略です。一般的な画像はJPGやPNGといったラスタ形式(ビットマップ)ですが、SVGはベクタ形式で表現します。
ベクタ形式の特徴はアンカーと呼ばれる座標を複数指定し、そのアンカーを線で繋いだり、囲まれた範囲内を塗ることで描画します。

ベクタ形式とラスタ形式

ベクタ形式とラスタ形式の最大の特徴はリサイズによる画像の劣化があげられます。 ラスタ形式はドットが集合した画像なのでリサイズ時に画像が劣化する場合がありますが、ベクタ形式では先ほど説明したように座標を複数の点で指定して描画するため、リサイズ時に劣化がほとんどありません。

形式 利点
ベクタ 直線や曲線などで構成された図形
ラスタ 写真や風景など複雑なグラフィック

SVGはXMLベースの文書形式で作成されているため、テキストエディタで編集することが可能です。画像と違いテキスト形式なのでバージョン管理システムとの相性が良いとも言われています。 しかし、手軽に編集ができるため容易に改ざんすることも可能です。そのためセキュリティには気をつけなければなりません。

ブラウザのサポート状況

f:id:tky_ymgc:20161018195144p:plain

引用元: http://caniuse.com/#feat=svg-html5

モダンブラウザにはほぼ対応済みです。しかしIE8など一部のブラウザで対応できていないのでフォールバックする必要はあるかと思います。 例えば、ModernizrといったJSライブラリを用いてブラウザのSVGサポート状況を判別し、サポート外であった場合にPNG画像などで代替するといったことが必要となります。

Modernizr

HTML5やCSS3などの新しいWebの標準がWebブラウザに実装されているか、汎用的なインタフェースを通じて確認することができるJavaScriptライブラリ

SVGとCanvas

CanvasはHTNL5でグラフィックを表現するための要素です。特徴としてはラスタ形式(ビットマップ)で描画され、画像を別形式で保存しやすいことです。ここがSVGとの最大の違いです。
SVGとCanvasはそれぞれ適しているケースで使い分けると良いです。

SVGが適しているケース

  • 円や四角形などの図形の組み合わせで構成されている
  • ベクタ形式なので拡大、縮小で図形の劣化が少ない方が良い
  • 外部ファイルとして受け渡しを行い、別のHTML上でも表示させたい

Canvasの方が適しているケース

  • ビットマップ形式なのでピクセル単位での細かい描画を行いたい
  • 描画した画像を別形式の画像(PNGなど)で保存したい

SVGの埋め込み方法

SVGにはいくつかの埋め込み方法があります。 通常の画像ファイルのようにHTMLのimgタグやCSSのbackground-imageで読み込む方法や、SVG要素として埋め込む方法、外部メディアとして読み込む方法があります。

画像としてHTMLに埋め込む

<img src="assets/svg/image.svg" alt="" width="100" height="100">

画像としてCSSに埋め込む

.svg {
    background-image: url(assets/svg/image.svg);
}

外部メディアとして埋め込む

<object data="assets/svg/image.svg" width="300" height="300" codetype=“image/svg+xml"></object>

要素として埋め込む

<svg width="300" height="300">
    <line x1="0" y1="0" x2="300" y2="300" stroke="black" stroke-width="1" />
</svg>

基本的な図形

テキスト

<svg width="300px" height="300px">
    <text x="100" y="100">Hello World</text>
</svg>

テキストは<text>タグを使用します。左上が起点となり、X座標とY座標の指定した位置からテキストが描画されます。

直線

<svg width="300px" height="300px">
    <line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="1" />
</svg>

直線は<line>タグを使用します。X座標1、Y座標1からX座標2,Y座標2までを直線で結びます。属性にstrokeを記述することで線の色や太さを指定することができます。

四角形

<svg width="300px" height="300px">
    <rect x="10" y="10" width="100" height="100" stroke="black" stroke-width="1" fill="red" />
</svg>

四角形は<rect>タグを使用します。左上が起点となり、X座標とY座標の指定した位置から四角形が描画されます。widthとheightを使用して大きさを指定します。

円形

<svg width="300px" height="300px">
    <circle cx="100" cy="100" r="50" stroke="black" stroke-width="1" fill="blue" />
</svg>

円形は<circle>タグを使用します。CX座標とCY座標で円の中心地点を指定し、rで半径の大きさを指定します。

パス図形

<svg width="300px" height="300px">
  <path stroke="black" stroke-width="1" d="M20,70 h60l-30,60z"/>
</svg>

パス図形は<path>タグを使用します。任意の図形を描画することができるので自由度は高いですが、上記の図形よりも少し複雑になります。 パス図形ではd属性(パスデータ)を指定することで曲線を描画することができます。d属性にはパスコマンドをカンマやスペース区切りで複数記述し、前から順に実行していき、曲線で囲まれた領域がパス図形となります。

以下は基本的なパスコマンドの一覧です。

基本的なパスコマンド

コマンド 操作
M, m 初期位置
L, l 直線を引く
H, h 水平線を引く
V, v 垂直線を引く
C, c \ S, s \ Q, q \ T, t 曲線を引く
A, a 円弧を引く
Z, z 線を閉じる

※大文字は絶対位置を指定、小文字は相対位置を指定する