HTMLのsvgタグを使うとサイトに描画できる。色も塗れるし、線や丸や四角や三角や弧を繋げて簡単なアイコンから非常に複雑な絵まで作成できる。マークアップは座標系の数値を入力して行われる。
SVGはScalable Vect Graphics(スケーラブルベクターグラフィックス)の略語で、画像データを格納するファイル形式の一つなんだ。たとえ拡大縮小しても他の一般的なjpgやpngやgifの画像のように画質が変わらない特徴を持っている。サイトではアイコンに使われる場合が多い。画像のサイズが小さくても劣化しないし、輪郭も崩れないから見映えに相当に優れる。
サイトにSVGファイルの画像を表示するにはimgタグで<img src="画像URL">
とマークアップするけど、しかしもう一つの方法としてsvgタグでも可能なんだ。
画像データを、直接、マークアップする。SVGのインライン用法と呼ばれる。imgタグだけではなくてsvgタグでもサイトにSVG画像は表示できる。
インラインSVGの基本的なマークアップ
サイトにsvgタグで描画するためには主に三つの条件がある。
- xmlns_名前空間
- widthとheight_縦横のサイズ
- viewBox_ビューボックス/座標系
svgタグの枠組みのソースコード
<svg xmlns="http://www.w3.org/2000/svg" width="横幅" height="縦幅" viewBox="横の最小点 縦の最小点 横の長さ 縦の長さ">
画像データ
</svg>
※横と縦の最小点は描画する開始点に等しいけれども横と縦の長さはそれぞれの描画する終了点と等しいとはかぎらない。
HTMLのバージョン5ではsvgタグの名前空間(描画するタグを識別するための指定)はブラウザがもう既に識別できる場合が殆どだから省略して構わないけど、ただしそれ以外のアプリで画像データの読み取りに影響するかも知れないからなるべく付けておくのが無難かも知れない。
widthとheightがviewBoxの大きさ(横と縦の長さで決まる)と同じだと省略しても変化しない。前者の二つはサイトに表示する画像の大きさ、後者は画像自体の座標系を示している。同じでないと拡大縮小される。widthとheightがviewBoxの大きさよりも広ければSVG画像は拡大されて反対に狭ければ縮小される。
そしてviewBoxは画像データに対して十分かどうか、指定される大きさによってサイトに表示されるSVG画像が途中で切り取られたり、周りに余白を増やしたりするようになる。
いい換えるとインラインSVGで画像を完全に表示するためには何よりもviewBoxの座標系に収まる範囲内に描画しなければならない。
混乱し易いけれどもwidthとheightは画像自体の内容には影響しなくてサイトに表示される大きさだけを左右する。しかしviewBoxは画像自体の内容とサイトに表示される大きさの両方に影響するし、インラインSVGで描画するために欠かせない座標系を確保していて省略できない。
widthとheightは省略しても構わない。するとレスポンシブデザインで役立つんだ。デバイス毎の画面幅にsvgタグでマークアップした画像を合わせるためには「width="100%" height="auto"」などで少なくとも横幅を画面幅以下に指定するか、または記載しないでおいても対応できる。
svgタグにwidthとheightを固定値で指定するとサイトに表示される画像のサイズを制御するのが大変になってしまう。というのはCSSのmax-width(最大幅)が利かないせいなんだ。アイコンなどの小さな画像ははみ出さないから大丈夫だけれども大きな画像の場合はwidthとheightに100%とautoの値を使うか、敢えて記載しないでおくと画面幅に収まるようになる。
画像のサイズは割合で指定すると画面幅に対して小さな画像が大きくなる場合も出て来るからおよそはみ出さないような画像のサイズには固定値を指定するのが相応しい。
svgタグの画像はCSSで位置取りが変えられないようだけれども親要素にtext-alignなどをかけると中寄せや右寄せも可能になる。
描画するviewBoxの座標系は左上から右下に大きさの分だけ加算して捉える仕組みだ。
かりに開始点の左上を「0 0」とすると縦横の長さが320×320の場合の座標系の終了点の右下は「320 320」となる。
座標系というと左下から右上へ加算して捉えるのが一般的だから注意しておきたい。
viewBoxの縦横の最小点の値はマイナスでも大丈夫なので、「0 0」の原点を中心とした四方への座標系が使える。
縦横の長さがマイナスだとエラーになって適切に描画されなくなる。
線を描く
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<line x1="20" y1="20" x2="140" y2="220" stroke-width="2" stroke="#dc143c"/>
<line x1="180" y1="220" x2="300" y2="20" stroke-width="2" stroke="#dc143c" stroke-linecap="round" stroke-dasharray="4, 6"/>
</svg>
線を描くにはlineタグを使う。
lineタグに必要な四つの属性
- x1_横の開始点
- y1_縦の開始点
- x2_横の終了点
- y2_縦の終了点
デザインを変えるには線の属性を追加する。
線のデザインの主な属性
- stroke_線の色
- stroke-width_線の太さ
- stroke-opacity_線の濃さ
- stroke-linecap_線の端
- butt_切り出し/真っ直ぐ
- round_丸い
- square_平ら
- stroke-linejoin_線の角
- miter_留め継ぎ/鋭い
- round_丸い
- bevel_傾斜/緩い
- stroke-miterlimit_線の角の制限
初期値は「4」で、線の角が鋭過ぎると自動的に緩くなる限界を指定する。角度に対して大きな値は尖った、小さな値は平らな角を作る。 - stroke-dasharray_波状
値は線の長さを指定するけど、半角コンマで区切って複数を指定した場合、次が空白の長さとして扱われる。以降、線の長さと繰り返される。空白の長さで止めた複数の値は通常のパターンの後に線の長さと空白の長さが入れ替わったパターンが加わって表示される。 - stroke-dashoffset_埋め合わせ
波状の最初の長さを縮める。
線を太く指定した場合、viewBoxにぴったりのデザインでは端が切り落とされて全て入り切らない可能性がある。太さも含めて線を完全に表示するためにはviewBoxよりも小さめに描画しなくてはならない。
svgタグのデザインの属性と値はCSSの要素と値としても使える。
丸を描いて色を塗る
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<circle cx="80" cy="120" r="60" stroke-width="2" stroke="#dc143c" fill="none"/>
<circle cx="240" cy="120" r="60" stroke-width="2" stroke="#dc143c" fill="#00bfff"/>
</svg>
丸を描くにはcircleタグを使う。
circleタグの三つの属性
- cx_横の中心点
- cy_縦の中心点
- r_半径の長さ
デザインを変えるには線の属性や面の属性を追加する。
面のデザインの主な属性
- fill_面の色
- fill-opacity_面の濃さ
- fill-rule_色を塗る領域/内側の判定
- nonezero_一つの面が同方向に小さく囲まれた他の面を含む/くり貫かない(初期値)
任意の点から線へ射線を引いて左から右へ交差すると一つ足して右から左へ交差すると一つ引くアルゴリズムから全体の合計が零でなければ内側の色を塗る領域と捉える。 - evenodd_一つの面が同軸上に小さく囲まれた他の面を含まない/くり貫かれる
任意の点から線へ射線を引いて左から右へ交差すると一つ足して右から左へ交差すると一つ引くアルゴリズムから全体の合計が偶数でなければ内側の色を塗る領域と捉える。
nonezeroは描画する方向が反対でないかぎりは全体を塗り潰してくり貫かず、evenoddは普通にくり貫くけれども幾重か囲まれる場合は断続的に塗り潰すようになる。
別々のタグから線や面を重ねて表示する図形はfill-rule属性は関係なくて上が下よりも優先される。マークアップで指定される座標系が被った複数の図形は前よりも後に描画する方がブラウザに反映する。 - nonezero_一つの面が同方向に小さく囲まれた他の面を含む/くり貫かない(初期値)
面の色の値の無色は「none」、透明は「transparent」を使う。どちらも表示は同じだけれどもサイトではクリック可能かどうかが違う。前者はクリックできず、後者はクリックできるので、SVG画像にリンクのaタグを付ける場合などに使い分けると良いと思う。
svgタグのデザインの属性と値はCSSの要素と値としても使える。
楕円を描いて色を塗る
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<ellipse cx="80" cy="120" rx="60" ry="40" stroke-width="2" stroke="#dc143c" fill="none"/>
<ellipse cx="240" cy="120" rx="40" ry="60" stroke-width="2" stroke="#dc143c" fill="#00bfff"/>
</svg>
楕円を描くにはellipseタグを使う。
ellipseタグに必要な四つの属性
- cx_横の中心点
- cy_縦の中心点
- rx_横の半径の長さ
- ry_縦の半径の長さ
四角を描いて色を塗る
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<rect x="20" y="60" width="120" height="120" stroke-width="2" stroke="#dc143c" fill="none"/>
<rect x="190" y="85" width="100" height="70" rx="2%" ry="2%" stroke-width="2" stroke="#dc143c" fill="#00bfff"/>
</svg>
四角を描くにはrectタグを使う。
rectタグに必要な四つの属性
- x_横の開始点
- y_縦の開始点
- width_横の長さ
- height_縦の長さ
オプションで角の丸みを指定できる。
- rx_角の横方向の丸み
- ry_角の縦方向の丸み
三角などの多角形を描いて色を塗る
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<polygon points="20 180, 80 60, 140 180" stroke-width="2" stroke="#dc143c" fill="none"/>
<polygon points="180 40, 240 200, 300 40" stroke-width="2" stroke="#dc143c" fill="#00bfff"/>
</svg>
三角などの多角形を描くにはpolygonタグを使う。
polygonタグに必要な一つの属性
- points_頂点の横と縦
各々の値は半角スペースや半角コンマで区切って記載する。
pointsを、三組以上、指定すると三角よりも頂点の多い多角形を描画できる。
複数の直線を繋げて描く
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<polyline points="20 20, 140 20, 140 220, 20 220, 140 20" stroke-width="2" stroke="#dc143c" fill="none"/>
<polyline points="300 220, 180 220, 180 20, 300 20, 180 220" stroke-width="2" stroke="#dc143c" fill="#00bfff"/>
</svg>
複数の直線を繋げて描くにはpolylineタグを使う。
polylineタグに必要な一つの属性
- points_頂点の横と縦
各々の値は半角スペースや半角コンマで区切って記載する。
線を座標から描く
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<path d="M20 120 L50 220, 110 20, 140 120" stroke-width="2" stroke="#dc143c" fill="none"/>
<path d="M240 20 L180 70, 300 180, 240 220 Z" stroke-width="2" stroke="#dc143c" fill="#00bfff"/>
</svg>
線を座標から描くにはpathタグを使う。
pathタグに必要な一つの属性
- d_頂点の横と縦
各々の値は半角スペースや半角コンマで区切って記載する。
開始点を「M」か「m」のコマンドで縦横に決める。前者は座標系の点、後者は前の点からの距離になる。
さらにコマンドで、直線を「L」か「l」で、水平線を「H」か「h」で、垂直線を「V」か「v」で、それぞれに縦と横の終了点を指定して描画する。何れも英語の大文字と小文字の違いは開始点のコマンドと同様に座標系の点と前の点からの距離を示している。終了点の指定は直線は普通に縦横の二つだけれども水平線は横、垂直線は縦の一つだけで構わない。
値の最後に「Z」か「z」のコマンドをかけると終了点が開始点と自動的に繋がる。
弧を描く/曲線を座標から描く
直線を座標から描くためのpathタグは弧を描く/曲線を座標から描くのにも使える。
開始点に続いて「C」か「c」の三次ペジェ曲線、「Q」か「q」の二次ペジェ曲線、「A」か「a」の円弧曲線のコマンドをかける。他にも連続で曲線を表示するショートカットコマンドがあるけれども何れも英語の大文字と小文字の違いは開始点のコマンドと同様に座標系の点と前の点からの距離を示している。各々の値は半角スペースや半角コンマで区切って記載する。
三次ペジェ曲線は弧の入出の方向を二つの制御点で決めて個々の角度で描画する。二次ペジェ曲線は弧の先端を一つ制御点で決めて入出の角度を等しく描画する。なので前者は後者よりも複雑な曲線に向いていてマークアップの手順が多く、後者は前者よりも簡素な曲線に向いていてマークアップの手順が少ない。円弧曲線は想定される円から切り出して描画する。マークアップは開始点と終了点を通過する円弧のタイプ:四つに分かれる部分(両側に二つの円が可能で、各々が二つの弧を持つため)から一つ選択して指定する。
弧を描くと線だけではなくて面も形成される。flll属性で無色や透明を同時に指定しないとデフォルトの黒で塗り潰されて表示される。
三次ペジェ曲線を使う
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<path d="M20 120 C55 20, 150 20, 160 120 S265 200, 300 120" stroke-width="2" stroke="#dc143c" fill="none"/>
</svg>
C x1 y1, x2 y2, x y / c dx1 dy1, dx2 dy2, dx dy
C / c 横の第一制御点 縦の第一制御点, 横の第二制御点 縦の第二制御点, 横の終了点 縦の終了点
pathタグの三次ペジェ曲線にショートカットコマンドの「S」か「s」を追加すると対向する曲線が描ける。前者は座標系の点、後者は前の点からの距離になる。
S x2 y2, x y / s dx2 dy2, dx dy
S / s 横の第二制御点 縦の第二制御点 横の終了点 縦の終了点
他の「S」か「s」に追加した場合も描画する仕方は同じだ。
開始点から先頭に「S」か「s」のショートカットコマンドを使った場合は三次ペジェ曲線の二つの制御点が一つに合わさって表示される。
値の最後に「Z」か「z」のコマンドをかけると終了点が開始点と自動的に繋がる。
二次ペジェ曲線を使う
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 240">
<path d="M20 120 Q90 220, 160 120 T300 120" stroke-width="2" stroke="#dc143c" fill="none"/>
</svg>
Q x1 y1, x y / q dx1 dy1, dx dy
Q / q 横の制御点 縦の制御点, 横の終了点 縦の終了点
pathタグの二次ペジェ曲線にショートカットコマンドの「T」か「t」を追加すると対向する曲線が描ける。前者は座標系の点、後者は前の点からの距離になる。
T x y / t dx dy
T / t 横の終了点 縦の終了点
他の「T」か「t」に追加した場合も描画する仕方は同じだ。
開始点から先頭に「T」か「t」のショートカットコマンドを使った場合は参照する制御点がないために終了点への直線が描画される。
値の最後に「Z」か「z」のコマンドをかけると終了点が開始点と自動的に繋がる。
円弧曲線を使う
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="auto" viewBox="0 0 320 480">
<path d="M40 120 A60 60, 0 0 0, 120 120 M200 120 A60 60, 0 1 0, 280 120" stroke-width="2" stroke="#dc143c" fill="none"/>
<path d="M40 360 A60 60, 0 0 1, 120 360 M200 360 A60 60, 0 1 1, 280 360" stroke-width="2" stroke="#dc143c" fill="none"/>
</svg>
A rx ry, x-axis-rotation large-arc-flag sweep-flag, x y / a rx ry, x-axis-rotation large-arc-flag sweep-flag, dx dy
A / a 横の半径 縦の半径, 傾き 大小 正負, 横の終了点 縦の終了点
大小は開始点と終了点を通り得る二つの円の弧が180°よりも広いか狭いか、正負は描画する方向へ右回りか左回りかをそれぞれに1か0で記載する。
円弧曲線の大小と正負の四通りの組み合わせ
- 0 0_小さな弧を左回りに描く
- 1 0_大きな弧を左回りに描く
- 0 1_小さな弧を右回りに描く
- 1 1_大きな弧を右回りに描く
弧のタイプは求める大きさと描画して回る向きの四通りの組み合わせから選択する。
値の最後に「Z」か「z」のコマンドをかけると終了点が開始点と自動的に繋がる。
svgタグは描画する諸々のタグを使って図形を表現できる。幾つも入れられるし、座標系を合わせて重ねられもする。複雑な画像は創作アプリを使って描画するのが手早いかも知れないけれどもアイコンや簡素な画像ならば大差がない。座標系での画像データの扱いに慣れればマークアップも直ぐにできるし、インラインSVGは面白い。
コメント