当サイトではCookieを使用します。Cookieの使用に関する詳細は「プライバシーポリシー」をご覧ください。
OK
 
2019.10.15

コードで描くSVG 図形/テキスト編

10,029

10月の連休は大型台風に野球にラグビーにめまぐるしい3日間でしたね。
台風の被害に際し、心よりお見舞い申し上げます。

連休中はひきこもりライフを満喫させていただきました、梶原です。
絶好のカンヅメ機会なのでSVGについてまとめてみました。

目次

そもそもSVGとは?

SVG(Scalable Vecter Graphics)は画像のファイル形式の一つです。
最大の特徴はどんなに拡大しても画像が劣化しないことです。(ベクター形式)
JPEGやPNGなどの画像ファイルは色のついた小さな点が集まって画像になっています。(ラスター形式)
また、画像でありながら位置や色などの情報をテキストデータとして持っているのでJavaScriptやCSSを使って画像の内容を手軽に操作することができます。
WEBとの相性がよく、グラフィックのアニメーション表現でよく使われています。

SVGファイルの構造

SVGファイル自体はXMLベースで記述されています。
今回はHTMLファイル内にSVGタグを直接記述して図形やテキストの描き方をまとめてみました。

基本的にはsvgの領域をwidthとheightで指定をして、その中に表現したい要素を記述していきます。
要素は<●●● />でも<●●●><●●●/>でも、どちらでも構いません。

また、SVGのプロパティはCSSとして指定することもできます。
詳細はhttps://www.w3.org/TR/SVG2/propidx.htmlをご確認ください。

図形を描く

SVGはコードで座標を指定して図形を描くことができます。
教科書的で単調な流れにはなりますが大切な基本をまずは確認します。

線を描く〈line〉

直線を描くときはline要素を使います。
始点と終点の座標位置を指定し、様々な属性を追加することができます。

See the Pen SVG line by Airi Kajihara (@kajihara) on CodePen.


stroke-dasharray=”点線の長さ
間隔の長さ”stroke-dashoffset=”点線の開始位置”
点線の属性はアニメーション表現でも大活躍です。

四角形を描く〈rect〉

四角形はrect要素を使って描くことができます。
左上の頂点が基準の座標位置になり大きさはwidth属性、height属性で指定します。

See the Pen SVG rect by Airi Kajihara (@kajihara) on CodePen.

円を描く〈circle〉〈ellipse〉

円を描くときは、正円をcircle要素、楕円をellipse要素を使います。
円の中心座標をと半径を指定します。

See the Pen SVG circle ellipse by Airi Kajihara (@kajihara) on CodePen.


楕円はopacityで透過させています。

折れ線を描く〈polyline〉

折れ線はline要素を組み合わせることもできますが、polyline要素を使うと連続で座標を指定して描くことができます。
角の形状は鋭利なもの(miter)、角丸(round)、面取りしたもの(bevel)、3タイプがあります。

See the Pen RwbJwov by Airi Kajihara (@kajihara) on CodePen.

多角形を描く〈polygon〉

polygon要素を使えば先ほどのpolyline要素のように座標を指定して面を塗ることができます。
ポリゴン絵を究めるとかっこいい表現もできそうです。

角の形状については、pliylineでも同様ですが、角度が小さく鋭すぎると鋭利な角の形状(miter)を指定していても、面取りした角の形状(bevel)が表示される現象が起こります。
これを解決するには、stroke-miterlimitを属性に追加してください。miterの場合、初期値が4なので5以上を指定しましょう。

See the Pen SVG polygon by Airi Kajihara (@kajihara) on CodePen.

多角形は塗りのルールを指定できます。
fill-rule属性を追加すれば塗り方を変更することができます。
初期値のnonzero(図全体)とevenodd(一部くり抜き)の2パターンあります。
ただし、複雑な形の多角形は思い通りにならないケースもあるようです。

See the Pen SVG fill_rule by Airi Kajihara (@kajihara) on CodePen.

パスを描く〈path〉

パスを使うと滑らかな曲線を表現することができますね。
IllustratorやInkscapeで描かれたイラストをSVGにするとレイヤーごとにpathとして吐き出されます。

See the Pen SVG tiltilmitil by Airi Kajihara (@kajihara) on CodePen.


チルチルミチルの青い鳥をSVGにすると、ものすごい数字が並んでいます。
もう訳がわからないですね(´・ω・`)
ただ、基本的なルールを知れば解読できないことはありません。
そもそも解読する機会も無いですし、曲線をパスでコーディングするのは超人的な平面認識能力(?)が求められるので現実的ではありませんがルールだけさらりと確認します。

パスで直線・水平・垂直を描く

d属性の中にアルファベットのコマンドと座標を指定すれば直線、折れ線、多角形を表現することができます。

See the Pen SVG path by Airi Kajihara (@kajihara) on CodePen.


左の四角形は直線のコマンドのみで、右の四角形は水平と垂直のコマンドで描かれています。

パスで円弧を描く

パスで扇型の円弧を描くことができます。
扇型の弦の座標を指定して、Aコマンドに続けて扇型の半径と傾きを指定していきます。
扇型は同じ弦の座標位置でも4パターンの円弧ができます。
4パターンの円弧は、円弧の長さ(長いor短い)とどちら周り(時計回りor反時計回り)かで指定することができます。

See the Pen SVG path circle by Airi Kajihara (@kajihara) on CodePen.

パスで2次ベジェ曲線・3次ベジェ曲線を描く

現実的ではないですが、滑らかなベジェ曲線もコードで描くことができます。
Illustratorのペンツールでベジェ曲線を描くときに出てくる調節バーの座標を想像して数値を入れてみてくださいorz

See the Pen SVG bezier curve by Airi Kajihara (@kajihara) on CodePen.


▲気合いと根性で数値を入れましたo(`ω´ )o

テキストを描く〈text〉

SVGは画像ファイルでありながらテキストファイルです。
デザインフォントやグーグルフォントに装飾を加えた表現をすることができます。
text要素で表示したい文字を囲みます。

テキストの配置あれこれ〈tspan〉

text要素の配置基準は、左上ではなくテキストのベースラインになります。
つまり、テキストの左下がx座標、y座標の指定位置になります。
rotate属性で文字を傾けたり、x属性・y属性に複数の座標を指定すると左からそれぞれの文字の位置も個別に指定できます。

See the Pen SVG text by Airi Kajihara (@kajihara) on CodePen.

他にも縦書きや幅指定、一部指定など柔軟に文字の装飾ができます。

See the Pen SVG text2 by Airi Kajihara (@kajihara) on CodePen.


文字の配置は他にも細かく指定できますが割愛します。
もうすぐ東京オリンピックですね(〃ω〃)ポッ

テキストをパスに添わせる〈textPath〉〈defs〉

この表現はSVGならではでしょうか。
沿わせたいpath要素にidやclassを指定して、xlink:href=””属性でテキストとリンクさせます。
defs要素でpathを囲むとpathの線は非表示になります。
defs要素にはstyleやtitleなどの表示させなくない補足情報を入れることができます。

See the Pen SVG text path by Airi Kajihara (@kajihara) on CodePen.


▲ベジェ曲線の気合いと根性をここで流用するなど

テキストに輪郭をつける

テキストにもstroke属性で輪郭をつけることができます。

See the Pen SVG text3 by Airi Kajihara (@kajihara) on CodePen.

気になるSVGのアクセシビリティ

画像にテキスト情報を与えることができるということは、スクリーンリーダーでも読み上げてくれるのでは?と考え、初めてiPhoneのスクリーンリーダーで先ほどの「HAKATA」を確認してみました。
結論、text要素に入った文字情報はスクリーンリーダーでちゃんと読み上げてくれました!
感動*・゜゚・*:.。..。.:*・'(*゚▽゚*)’・*:.。. .。.:*・゜゚・*

調べてみるとSVGはしっかりとテキスト情報を指定することで、全ての人にアクセシブル、マシーンにとってもリーダブルな画像形式なりますね。
こちらのスライドにわかりやすくまとめられています。
HTML5 と SVG で考える、これからの画像アクセシビリティ

SVG × アニメーション〈animate〉

基本をおさえればアイディア次第でクリエイティブなアニメーションも表現できるようになってきますね。
SVGではanimate要素やanimateTransform要素に表現したいアニメーションの情報を追加できますが、CSSやJSでもアニメーションの指定をすることができます。

グラフのアニメーション

SVGを使うと便利なのがグラフの表現です。
数値データを差し替える時も画像加工ソフトを使わずコード上でサクッと編集できます。

See the Pen SVG bar graph by Airi Kajihara (@kajihara) on CodePen.


See the Pen SVG animation circle graph by Airi Kajihara (@kajihara) on CodePen.

頭を使ったのが円グラフです。
circle要素に塗りは無しで線の太さを半径の2倍にして表現しています。
点線の幅指定を利用して円グラフの比率を表現します。
半径から円周を求めて、表現したい円グラフの比率を乗算します。
円周×●%=”●%の円周の長さ”
stroke-dasharray: “●%の円周の長さ”,”円周-●%の円周の長さ”;
stroke-dashoffsetで上から始まるように調節しました。

<参考>
SVGで円グラフを描くシンプルな方法

パスに沿ってアニメーション〈animateMotion〉 〈mpath〉

パスにxlink:href属性でリンクさせれば、滑らかなカーブの動きも簡単にアニメーションでなぞることができます。

See the Pen SVG animation path by Airi Kajihara (@kajihara) on CodePen.

クリッピングパスをかけてアニメーション〈clipPath〉 〈image〉

SVGはjpg・png画像を読み込ませたり、好きな形状に切り抜いて表示させることもできます。
clipPath要素でマスクしたい形を囲み、clip-path=”url()”属性でid名、class名を指定します。

See the Pen SVG animation mask by Airi Kajihara (@kajihara) on CodePen.

手書き風アニメーション<mask>

See the Pen SVG text animation by Airi Kajihara (@kajihara) on CodePen.


最初にアウトライン化した「To Be continued」をimageで配置した上で、それを隠すマスク用のパスを重ねます。
点線の指定を利用してアニメーションさせます。
私のパスの雑さが目立ちますがあしからずご了承くださいm( __ __ )m

<参考>
SVGで手書き風アニメーションを実装する方法

マスクをかけなければパス自体で描いているようなアニメーション表現もできます。

ネオン風アニメーション

See the Pen SVG neon by Airi Kajihara (@kajihara) on CodePen.


こちらはSVGでなくとも表現できますが、のってきたので作ってみましたm( __ __ )m

基本からやりたいことを手当たり次第にやってみたら、ごちゃ混ぜのちゃんこ鍋のような記事になってしまいました。
まだ他にも手を出したい表現があります。それだけSVGは奥が深いです!
SVGをうまく活用して効果的に伝わる工夫をしていきたいです。

最後に参考にさせていただいた記事、書籍を書いてくださった方に感謝申し上げます。

<参考>
Webで使えるSVGファーストガイド

Contact