0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第11回 viewBox

Posted at

はじめに

今回は、viewBoxについてまとめたいと思います。
viewBoxはよくわからず、どういう動作なのか理解できていませんでしたが、色々と調べようやくわかってきたような気がしますので、それを整理していきたいと思います。

最初は、viewBoxの配下の要素にソースを書いていくため、viewBoxの範囲内に描画していくものと思っていましたが、それは誤りで、どちらかというと、描画したところから、viewBoxで特定の箇所を切り取るってことなんですよね。
今もしっくりこないところはあるのですが、整理していきたいと思います。

今回実施する内容

viewBoxは内容が色々ありますので、まずは基本的な部分をまとめたいと思います。
今回は、viewBoxとviewportの縦横比が同じ場合についてまとめたいと思います。

ソースコード(Git Hub)

環境

OS: Windows 11 JP (64bit)
Edge: バージョン 142.0.3595.53 (公式ビルド) (64 ビット)

参考

7 Coordinate Systems, Transformations and Units

用語

キャンバスとviewBoxとviewport

SVGのviewBox属性は、とても重要な属性です。これがわからないと少しの変更で、意図しないSVG画像になったりします。
よりよく理解するために、概念から整理します。まずはイメージを図示します。
image.png

  • 左側が「キャンバス」と呼ばれる「仮想の表示領域」。ここに描画したい内容を記載する。
  • 右側が実際のブラウザなどの画面。
  • SVGは、「キャンバス」に描画して、viewBoxで描画したい内容を切り取って、Edgeなどのブラウザ上に「実際の表示領域」にスケーリングして表示。
  • viewBoxは、「キャンバス」上の切り抜きたい(「実際の表示領域」に表示したい)場所を囲った矩形の領域。
  • viewportは、「実際の表示領域」の矩形。

したがって、上図では、「キャンバス」上に、「Build Mount」と描画しましたが、viewBoxで「Build Mo」までを囲っており、その結果、viewport( 「実際の表示領域」の矩形)では、「Build Mo」だけが表示されます。

SVGがとても難しいと思うのは、viewBoxの設定だったり、viewBoxviewportの矩形の形(縦横比)が違ったりして、思ったようにブラウザに表示されないところかなと思います。
まずはこの基本をしっかりおさえて、慣れていく必要があると思います。
といってもまだ慣れないのですけれど。

viewBoxの設定

viewBox属性のフォーマットは以下です。

viewBox="min-x, min-y, width, height"
  • min-x:「キャンバス」上のviewBoxの矩形の左上のX軸の値。
  • min-y:「キャンバス」上のviewBoxの矩形の左上のY軸の値。
  • width:「キャンバス」上のviewBoxの矩形の横幅。
  • height:「キャンバス」上のviewBoxの矩形の縦幅。
    image.png

特徴としては、ここには単位はないということです。
「キャンバス」上で記載するときの座標や幅などの値は単位はなく相対的なものであって、viewBoxviewportに割り当てるときに具体的な単位となります。

viewportの設定

viewportは属性ではありませんが、設定はwidthheightで設定します。

<svg width="width" height="height">
</svg>
  • widthviewportの横幅。pxとか%などで具体的な単位を持った値。
  • heightviewportの縦幅。pxとか%などで具体的な単位を持った値。
    image.png

viewBoxサンプル

ここからは、viewBoxを使ったサンプルを紹介します。

1. viewBox="0 0 300 200" width="300px" height="300px"

image.png

menu.htmlの抜粋
<svg class="border" viewBox="0 0 300 200" width="300px" height="200px">
    <circle cx="150" cy="100" r="50" fill="red" />
</svg>

viewBoxviewportwidthheightを設定します。
このときに、viewBoxwidthheightと、viewportwidthheightの数値は同じにします。
これが一番基本的でわかりやすいと思います。
viewBoxmin-xmin-yはそれぞれ0に設定します。これも最もシンプルでわかりやすいと思います。

class属性は、このSVG画像の枠を線で囲うためのCSSで、別途定義しています。viewBox自体には関係ありません。
<circle>では中心位置をcx="150" cy="100"で半径r="50"で赤色の円を記載します。

2. viewBox="100 50 300 200" width="300px" height="300px"

image.png

menu.htmlの抜粋
<svg class="border" viewBox="100 50 300 200" width="300px" height="200px">
    <circle cx="150" cy="100" r="50" fill="red" />
</svg>

1の例から、viewBoxmin-xを0⇒100、min-yを0から50に変更しました。
「キャンバス」上のviewBoxをずらして、赤色の円がギリギリ入るようにしました。

3. viewBox="150 100 300 200" width="300px" height="200px"

image.png

1の例から、viewBoxmin-xを0⇒150、min-yを0から100に変更しました。
「キャンバス」上のviewBoxをずらして、赤色の円の1/4部分が表示されるようにしました。
もともと円を描いていたはずなのに、1/4円になります。
こういう動作が理解が難しいですよね。

4. viewBox="0 0 600 400" width="300px" height="300px"

image.png

menu.htmlの抜粋
<svg class="border" viewBox="0 0 600 400" width="300px" height="200px">
    <circle cx="300" cy="150" r="100" fill="red" />
</svg>

1の例から、viewBoxwidthを300⇒600、heightを200⇒400に変更しました。
また、<circle>もサイズを変更し、位置も調整しました。
<circle cx="150" cy="100" r="50" fill="red" />

<circle cx="300" cy="150" r="100" fill="red" />
viewportの実際の表示領域は、1の例と同じです。
「キャンバス」上のwidthheightのサイズを大きくすることで、「キャンバス」上の解像度が上がったということです。今回はシンプルな円だけですので、実際の表示領域の見た目は1の例と全く同じです。
解像度を上げるということはそれだけ細かい描写ができるようになるということなので、どのくらいがよいのかは作成者次第とは思いますが、大きな値を設定しておいてもファイルサイズが極端に大きくなるわけではないため、余裕をもった大きさでもかまわないのかなと思います。

viewBoxviewportの設定なし時の動作

viewBoxviewportは任意であるため、設定しないこともできます。
そうした場合にどうなるかを示します。

viewBox viewportwidithheight viewBoxの動作 viewportの動作`
なし なし viewportに従う。viewBox="0 0 300 150"相当。 デフォルトのwidth="300px" height="150px"
なし あり viewportに従う。 設定値通り。
あり なし 設定値通り。 widthはブラウザの横幅。heightviewBoxの縦横比に従う。
あり あり 設定値通り。 設定値通り。縦横比の動作はpreserveAspectRatio属性に従う。

5. viewBoxなし、viewportなし

image.png

menu.htmlの抜粋
<svg class="border">
    <circle cx="150" cy="100" r="50" fill="red" />
</svg>

viewBoxviewportの値を持ってくるようになるため、viewBox="0 0 300 150"相当になります。
viewportはデフォルトのwidth="300px" height="150px"になります。

6. viewBoxなし、viewportあり

image.png

menu.htmlの抜粋
<svg class="border" width="300" height="200">
    <circle cx="150" cy="100" r="50" fill="red" />
</svg>

viewBoxは、viewportの値を持ってくるようになるため、この例ではviewBox="0 0 300 200"相当になります。
viewportは設定した通りです。

7. viewBoxあり、viewportなし

image.png

menu.htmlの抜粋
<svg class="border" viewBox="0 0 300 200">
    <circle cx="150" cy="100" r="50" fill="red" />
</svg>

viewBoxは設定した通りです。
viewportwidthはブラウザの横幅になり、heightは、viewBoxで設定した縦横比に応じて設定されます。

8. viewBoxあり、viewportあり

image.png

menu.htmlの抜粋
<svg class="border" viewBox="0 0 300 200" width="300px" height="100px">
    <circle cx="150" cy="100" r="50" fill="red" />
</svg>

viewBoxは設定した通りであり、viewportも設定した通りです。
しかし、この例では、あえてviewBoxviewportの縦横比を変更しており、縦横比がほかの例と違っていびつに見えるかと思います。
この辺の動作は、次回縦横比の比率が違う場合で取り上げたいと思います。

おわりに

今回はviewBoxviewportがどういったものか、および、その基本的な使い方とサンプルを示しました。
この辺は基本なところでありつつも、難解で、期待しない画像が出来上がることが何回もありました。
なかなか難しいですよね。
また、viewBoxviewportは、なるべく設定したほうがよさそうだなと思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?