【SVG】viewBoxの解説

SVG
動点P
動点P

viewBox意味が分からん。サイズはもう決めたのにこれいるの??

動点Qちゃん
動点Qちゃん

viewBoxはSVG画像をWebページに表示させる際、レスポンシブ対応になるような重要な属性なのです・・・

viewBoxとビューポート

まずSVGが描画される空間とはどういうものなのでしょうか?どのように表示する領域を決定しているのでしょうか?

SVG1.1仕様書より

メディアを問わず、 SVG キャンバス とは「 SVG 内容が描画される空間」を意味する。 キャンバスとは、どの方向にも無限の広がりを持つ空間である一方,描画についてはその有界な矩形領域に対し相対的になされるものである。 この有界な矩形領域を SVG ビューポート と呼ぶ。 視覚メディア【訳】 ([CSS2], 7.3.1 節) においては、 SVG ビューポートとは,利用者から見える SVG 内容の表示領域のことである。

SVG 1.1 仕様 (第2版) 日本語訳 ーーー7 座標系, 変換, 単位

とあります。

つまりまずSVGが描画されうる無限に広い空間があります。それがSVGキャンバスです。

動点P
動点P

SVG画像が描き放題の無限のキャンバス、やったぜ!!

しかし∞のキャンバスをそのまま表示することはできないので width=”●●px” height=” ●● px” など、サイズを決めて表示します。そうやってサイズを決めたこの領域を SVG ビューポート  と言います。このサイズは単位があり、絶対的で、違うパソコンで見たときも画面を縮めて見たときも仮に5pxと決めたらいつでも5pxで表示されるものです。

これが私たちが画面を見るときに表示されたSVG画像の領域やサイズということになります。

対してviewBox

viewBox 属性

一連のグラフィックを特定のコンテナ要素にぴったり収まるように拡縮させたい場面は多々ある。 viewBox 属性は、そのような機能を提供する。

SVG 1.1 仕様 (第2版) 日本語訳 ーーー7 座標系, 変換, 単位

というわけで、レスポンシブ対応に適した属性だと言えるらしい。特定のコンテナ要素にぴったり収めるにはどうすればいいのかというのは他の記述で、以下のようにある。

SVG 文書片中の任意の場所において、 変換行列 あるいは,回転( rotation ), 斜傾( skewing ), 拡縮( scaling ), 並進( translation )などの単純変換の形式による 変換 を指定して、新たな利用空間(すなわち新たな現在の座標系)を確立させられる。 座標系変換 を通して新たな利用空間を確立することは,二次元グラフィックスにおいて基礎となる処理であり、グラフィックスオブジェクトの大きさ, 位置, 回転, 斜傾を制御する通例的方法を提供する。

新たなビューポートを確立することもできる。 新たなビューポートの確立 により、百分率の単位で表された値の意味を再定義し,グラフィックを特定の矩形領域に「ぴったり」はめ込むための規範となる矩形を新規に与えられるようになる。 (ここで「ぴったり」とは、与えられたグラフィックの利用空間における限界ボックスをビューポートの縁にぴったり揃えるように変換させることを意味する。)

SVG 1.1 仕様 (第2版) 日本語訳 ーーー7 座標系, 変換, 単位

とあります。これだけではよくわかりませんが、他の記述に、「ビューポート座標系 および初期の 利用座標系 」とあり、どうやらサイズが具体的な単位で決められたビューポート座標系と、それを新たな座標に変換した利用座標系・利用空間があるみたいです。これらは相対的なサイズと言えそうです。

そしてその変換された利用座標系・利用空間として利用できるのがviewBox属性なのですね。

動点P
動点P

書いてる人も絶対わかってないだろう…わからん

以下具体的に見ていかないとなかなか難しいと思います。実際描画してみましたので見てみてください。具体的に見てみるとカンタンです!

viewBox属性

以下は width=”400px” height=”400px” の領域(ビューポート)の中に

cx=”100″ cy=”100″ r=”100″(x座標100、y座標100、半径100)で描いた青い円を

様々なviewboxのサイズで表示したものです。

赤い背景の高さはビューポートの 高さ400px です。ビューポートの大きさは絶対的なのでどれも高さは同じです。(幅は背景色を塗っただけなので表示画面いっぱいになっており、ビューポートの幅を示しているわけではありません)

See the Pen circle-demo by inu (@tenp) on CodePen.

一番上の円は

viewbox=”0 0 400 400″

左上の基点 x座標0 y座標0 幅400 高さ400

でビューポートに表示するという指定です。(SVGキャンバス空間は左上が起点になり、右と下方向に広がった空間です。)

最初に設定した領域ビューポートがviewBoxと等しいときはそのままの大きさで表示されます。


ビューポートの大きさは変わりませんが、2番目の円は大きく表示されています。

2番目のviewBoxは viewbox=”0 0 200 200″ で設定されています。

これは以下の図のように、viewBoxで指定した幅、高さ200の範囲を最初に設定したビューポート幅、高さ400の領域にぴったり合わせて表示しているから拡大されたのです。

どこの部分を切り取るのかviewBoxで指定し、それらの座標を、元のビューポートの座標に変換しなおしているのです。

つまり、青い正方形(viewBox)で切り取りたい図形を囲み、サイズはピンクの正方形に合わせなくてはいけないので、青い正方形がピンクの正方形に重なるまで囲んだ図形もろとも拡大しているのです。

反対にviewBoxのサイズを設定したビューポートより大きくすれば画像を縮小表示することができ、3番目の青い円のように表示されます。

ちなみにwidthやheightなど、ビューポートのサイズ設定をせずにviewBox属性だけ設定すると、相対的なサイズということになりレスポンシブ対応します。

以下一番目のものが viewBox属性 だけ設定してある円です。PC画面で見ている方は画面の左右幅を変えてみると、幅に合わせて拡大縮小されるのがわかるかと思います。

これはこのsvgタグが入っている親要素のサイズを100%としてviewBoxのサイズが変換され、さらにそれに合わせて描画している円の座標も相対的に変換されたということだと思います。(ただ、IEでは崩れるので、正式にサイト制作においてレスポンシブ対応させる方法はまた後に記します。)

See the Pen circle2 by inu (@tenp) on CodePen.

2番目の円はviewBoxをx軸上に-100ずらして表示している例です。以下の図のように左側半円だけが切り取られて表示されています。viewBox開始位置をずらすことによって描画された図を自由な位置で切り取ることができます。

切り取り位置は違いますが、ビューポートとviewBoxのサイズは同じなのでサイズは変化していません。

つまり、viewBoxとビューポートで大きさが違うとき、viewBoxで切り取った図形をビューポートの大きさに合わせるという作業をSVGはやっているわけですね。

動点Qちゃん
動点Qちゃん

絶対的サイズのビューポート、相対的サイズのviewBoxがあるということなのです・・・

動点P
動点P

レスポンシブにするなら相対的サイズのviewBox属性は大事なんだね

参考図書としたのはこちらの「Webで使える!SVGファーストガイド」です。

viewBoxとビューポートのサイズの比率が違う場合はpreserveAspectRatioという属性で制御することができます。以下の記事で解説しています。

興味のある方は読んでみてください。

コメント