職業プログラマの休日出勤

職業プログラマによる日曜自宅プログラミングや思考実験の成果たち。リアル休日出勤が発生すると更新が滞りがちになる。記事の内容は個人の意見であり、所属している(いた)組織の意見ではない。

これぞネ申! #SVG 方眼紙

この記事は、SVG Advent Calendar 2017 の3日目の記事です。

SVG Advent Calendar には、過去にこのような記事も投稿しています。

さて、世の中にはExcel方眼紙(WikiPediaの記事)、俗に言う神Excel ネ申Excel が蔓延っています。批判も多いですが、使いどころさえ誤らなければ、方眼紙というものは極めて有益なものです。決して方眼紙そのものに敵意を抱いてはなりません。私は、適した使い方をしている方眼紙を心の底から愛しています。
今回は、同じく愛を注ぐ対象であるSVGで、方眼紙を具現化したいと思います。

崇拝の対象である、SVG方眼紙

SVGを見ることのできないブラウザでは表示されないでしょうけれども、そのような方は早急にブラウザを乗り換えて下さい。

一応、WindowsChromeで描画したときのスクリーンショットのラスタ画像も貼り付けておきましょう。
f:id:t_motooka:20171202104947p:plain

上記SVGのソースは、次の通りです。後で解説します。

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="400px" height="300px">
	<defs>
		<pattern id="thePattern" patternUnits="userSpaceOnUse" x="0" y="0" width="10" height="10" viewBox="0 0 10 10">
			<rect x="0" y="0" width="10" height="10" stroke="#000000" stroke-width="0.5" fill="none"/>
		</pattern>
	</defs>
	<rect x="0" y="0" width="400" height="300" fill="url(#thePattern)"/>
</svg>

そもそもSVGって何者?

上記SVGのソースのように、XML(テキストデータ)でベクタ画像を描くためのファイルフォーマットです。
PNGJPEG等のラスタ画像とは異なり、各ピクセルの情報を保管するのではなく、どのように作図するのかの定義を記述する方式になっているので、拡大してもキレイです(例外あり:SVGの中にもラスタ画像を埋め込むことができますので、それらは拡大しまくるとキレイじゃないです)。

どのようにして方眼紙を描いているのか?

SVGソースの中に pattern というものが見えますが、これは座標平面を敷き詰めるタイルの1枚分の模様を表現しています。
最後に出てくる rect 要素には fill="url(#thePattern)" というものが見えますが、これは、描画する矩形(くけい:長方形のこと)の中を pattern で定義したタイルを敷き詰めるように描画することを意味しています。

では pattern の中身、つまりタイル一枚の様子はどうなっているかと言いますと、正方形の枠線だけを描画しています。ここでいう「線」は、算数や数学の世界で理解しているような太さゼロの線ではありません。グラフィックの世界では線にも太さがあります。タイル一枚のサイズと正方形の概念上のサイズとは完全に一致させていますが、正方形の枠線の太さはゼロではないので、タイル一枚の少し内側に枠線が描かれます。これが隣接するタイルと並べて描かれたとき、あたかも「ふつうに」枠線が描画されているように見えるのです。

参考資料

参考図書

SVGエッセンシャルズ 第2版

SVGエッセンシャルズ 第2版

SVG Animations: From Common UX Implementations to Complex Responsive Animation

SVG Animations: From Common UX Implementations to Complex Responsive Animation

さいごに

進捗ダメでなければ、明日も SVG Advent Calendar に投稿する予定です。お楽しみに!