Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

[SVG] viewBoxについての考察

More than 5 years have passed since last update.

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

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away