[SVG] viewBoxについての考察

  • 17
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

まずベースとなるサンプルを用意しておきます

200*200のサイズで、背景をグレイにして真ん中にオレンジの円をおきます。芸術的です。
左上に青い円も添えます。

<svg width="200" height="200" viewBox="0 0 200 200" style="background: #ddd">
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

スクリーンショット 2015-10-06 21.11.38.png

基本的なこと

まず外側の<svg width="200" height="200"の部分の200*200がビューポート(描画エリア)のサイズです。

viewBox="0 0 200 200"が考察したいviewBoxですが、これの意味するところは。
「vievBox="x y width height"」

  • x: 左上のx座標
  • y: 左上のy座標
  • width: 幅
  • height: 高さ

と、書いたところで....分からないと思うので、以下事例を追って頂くのがよいと思います。

まずは拡大してみる

viewBox="0 0 100 100"として、拡大します。

<svg width="200" height="200" viewBox="0 0 100 100" style="background: #ddd">
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

スクリーンショット 2015-10-06 21.14.22.png

そのまま座標をずらし(数学で言う)第一象限を表示してみる

viewBox="100 0 100 100"という感じで、x座標を右に100ずらしました。

<svg width="200" height="200" viewBox="100 0 100 100" style="background: #ddd">
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

スクリーンショット 2015-10-06 21.17.24.png

では問題です。以下のソースはどうなるでしょうか?

viewBox="0 0 100 200"としました。xy座標は最初に戻しました。
ボックスが正方形ではありません。100*200の長方形です。外側の枠は変わらず200*200の正方形です。

<svg width="200" height="200" viewBox="100 0 100 200" style="background: #ddd">
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

どうなるのでしょうか?

僕は全然わかりませんでした。

正解と要因

上記の問題ですが、こうなります。

スクリーンショット 2015-10-06 21.22.21.png

僕は最初これでちんぷんかんぷんになりました。

なぜこうなるのかは、viewBoxと同じサイズ指定の枠を表示させることでわかりやすくなります。

<svg width="200" height="200" viewBox="0 0 100 200" style="background: #ddd">
  <rect x="0" y="0" width="100" height="200" stroke="black" fill="none"/>
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

スクリーンショット 2015-10-07 20.31.57.png

真ん中に枠があります。こういうことですね。

どういうことか?初期設定に依存しています。

ポイントは、ビューポートのエリアとviewBoxのエリアの縦横比がズレでいるとき、いったいどうなるのか?縦横比をキープするのか、それとも、どちらかに膨張したりするのか?ということが気になります。

その拡縮についての属性が、「preserveAspectRatio」という属性です。

デフォルトではこのようになっています。

<svg width="200" height="200" viewBox="0 0 100 200" style="background: #ddd" preserveAspectRatio="xMinYMin meet">
  <rect x="0" y="0" width="100" height="200" stroke="black" fill="none"/>
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

preserveAspectRatio="xMidYMid meet"←こいつです。

  • xMidYMid: 均等な拡縮を強制し、xyのそれぞれ真ん中に配置。
  • meet: 縦横比は維持し、veiwBoxを可能なかぎり大きく配置。

こんな感じです。なので、あえて均等を崩せば、以下のようにすることもできます。

<svg width="200" height="200" viewBox="0 0 100 200" style="background: #ddd" preserveAspectRatio="none">
  <rect x="0" y="0" width="100" height="200" stroke="black" fill="none"/>
  <circle cx="100" cy="100" r="50" fill="orange" />
  <circle cx="0" cy="0" r="10" fill="blue" />
</svg>

スクリーンショット 2015-10-07 20.58.43.png

以上ありがとうございました。