svg.svg

【SVG】描画領域と座標指定

SVG

描画領域

描画領域は、<svg>要素の以下の属性によって設定します。

ビューポート

widthheightは、SVG の表示領域のサイズを設定するための属性です。 SVG では表示領域のことをビューポートといいます。

以下の SVG は、縦 × 横 = 100px×100px のサイズのビューポートとなります。

<svg width="100px" height="100px">
  <rect width="50" height="50" style="fill: blue" />
</svg>

viewBox

viewBoxは、SVG の描画領域を設定するための属性です。 まずは以下の例を見てください。

<svg viewBox="0 0 100 100">
  <rect width="50" height="50" style="fill: blue" />
</svg>

viewBoxは、<min-x> <min-y> <width> <height>の 4 つの値を設定します。

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

上記の例は、左上の座標が(x, y) = (0, 0)、幅と高さが100の描画領域となります。 この幅と高さの100は、座標で考えた場合の値です。 つまり、右下の座標が(x, y) = (100, 100)となると考えてください。

viewBoxwidthheightは具体的なサイズを示したものではないので、上の例は最大サイズで表示されます。 SVG のサイズは上述したようにビューポートとして指定します。

<svg width="100px" height="100px" viewBox="0 0 100 100">
  <rect width="50" height="50" style="fill: blue" />
</svg>

ではビューポートはそのままに、viewBoxの値だけを変化させた例をいくつか見てもらいます。 矩形の左上の座標は(x, y) = (0, 0)と考えてください。

  • viewBox="0 0 50 50"
  • viewBox="0 0 200 200"
  • viewBox="-25 -25 100 100"
  • viewBox="-50 -50 100 100"

結局のところ、ビューポートの左上と右上の座標を決めるのがviewBox、と解釈するのが個人的には一番わかりやすいかと思います。 正確には、ビューポートとviewBoxの比率が同じ場合に限ります。 このことについては後述します。

viewBoxを省略した場合は、表示領域と描画領域が同じサイズになります。 つまりビューポートのwidthheightの値と、viewBoxwidthheightの値が同じになります。

<svg width="100px" height="100px" viewBox="0 0 100 100">
  <rect width="50" height="50" style="fill: blue" />
</svg>

preserveAspectRatio

上記のviewBoxの説明では、ビューポートとviewBoxの比率を同じにしていました。 では、以下のように異なる比率を指定するとどうなるでしょうか。

例1
<svg width="100px" height="100px" viewBox="0 0 50 100">
  <rect width="50" height="50" style="fill: blue" />
</svg>
例2
<svg width="100px" height="100px" viewBox="0 0 100 50">
  <rect width="50" height="50" style="fill: blue" />
</svg>

実は、ビューポートの比率になるようにviewBoxが自動で調整されます。 これをどのように調整するかを決めるのがpreserveAspectRatio属性です。

指定のある描画領域をどの位置に配置するかを決めて調整を行います。 少しわかりにくいと思うので、以下を見てください。 下手に言葉で説明するよりはイメージできるのではないかと思います。

MinMidMaxnone
x
[例1]

左上:(0, 0)
右下:(100, 100)

左上:(-25, 0)
右下:(75, 100)

左上:(-50, 0)
右下:(50, 100)

左上:(0, 0)
右下:(50, 100)

y
[例2]

左上:(0, 0)
右下:(100, 100)

左上:(0, -25)
右下:(100, 75)

左上:(0, -50)
右下:(100, 50)

左上:(0, 0)
右下:(100, 50)

preserveAspectRatioは以下のように、x, y, Min, Mid, Max を組み合わせて指定します。 デフォルト値はxMidYMidです。 noneを設定すると比率の調整は行われません。

<svg width="100px" height="100px" viewBox="0 0 50 100" preserveAspectRatio="xMinYMax">
  <rect width="50" height="50" style="fill: #3498db" />
</svg>

また、preserveAspectRatioにはmeetsliceというオプションがあります。

meetがデフォルト値となっており、比率の大きな方に描画領域が調整されます。 つまり、上記はすべてmeetの場合の解説です。

sliceは、比率の小さな方に描画領域が調整されます。

例1
<svg width="100px" height="100px" viewBox="0 0 50 100" preserveAspectRatio="xMidYMid slice">
  <rect width="50" height="50" style="fill: blue" />
</svg>
例2
<svg width="100px" height="100px" viewBox="0 0 100 50" preserveAspectRatio="xMidYMid slice">
  <rect width="50" height="50" style="fill: blue" />
</svg>

これも少しわかりにくいと思うので、meetと同じように比較します。 meetとは x と y が逆のため注意してください。

MinMidMax
y
[例1]

左上:(0, 0)
右下:(50, 50)

左上:(0, 25)
右下:(50, 75)

左上:(0, 50)
右下:(50, 100)

x
[例2]

左上:(0, 0)
右下:(50, 50)

左上:(25, 0)
右下:(75, 50)

左上:(50, 0)
右下:(100, 50)

単位について

表示領域を指定するwidthheightには単位を指定できます。 上の例ではpxを指定していますが、emcmptなども指定できます。 単位を指定しなかった場合はpxとなります。 単位についてはこちらの記事を参考にしてください。

viewBoxなどその他の属性には単位はつけません。 あくまで座標で考えた場合の位置や幅を指定するためです。

座標指定

SVG では、図形の位置や大きさを座標を使って指定します。 当然ですが、描画領域を超えた図形は表示されません。

以下は矩形(rect)の例です。 矩形の左上の座標(x, y)と幅、高さを指定します。

他の図形も座標を指定することで、位置や大きさ、形を決めます。 図形については、この記事では言及しません。

<svg width="100px" height="100px">
  <rect width="25" height="25" style="fill: blue" />
  <rect x="0" y="75" width="25" height="25" style="fill: red" />
  <rect x="75" y="0" width="25" height="25" style="fill: green" />
  <rect x="75" y="75" width="25" height="25" style="fill: yellow" />
</svg>

transform

transform属性を指定することで、移動や伸縮、回転などを行うことができます。

考え方は CSS のtransformとほぼ同じです。 CSS のtransformについてはこちらの記事を参照してください。

translate

translate(x, y)は、図形を移動させる x 座標、y 座標を指定します。

<div class="preview-html">
  <svg width="100px" height="100px">
    <rect width="25" height="25" style="fill: blue" />
    <rect width="25" height="25" style="fill: red" transform="translate(50, 0)" />
    <rect width="25" height="25" style="fill: green" transform="translate(0, 50)" />
    <rect width="25" height="25" style="fill: yellow" transform="translate(50, 50)" />
  </svg>
</div>

scale

scale(x, y)は図形の伸縮に用い、x 座標、y 座標に掛け合わせる倍率をそれぞれ指定します。 引数が 1 つの場合は x 座標、y 座標ともに同じ倍率を掛け合わせます。

<svg width="100px" height="100px" style="background: #ddd">
  <rect width="25" height="25" style="fill: yellow" transform="scale(3, 4)" />
  <rect width="25" height="25" style="fill: green" transform="scale(4, 1)" />
  <rect width="25" height="25" style="fill: red" transform="scale(2)" />
  <rect width="25" height="25" style="fill: blue" />
</svg>

座標に倍率を掛け合わせているので、図形の元の位置から移動したように見える場合があります。 具体的に、矩形の左上の座標が(2, 4)scale(2)とすれば、(4, 8)に変換されるため移動したように見えるということです。

図形の線の太さ(stroke)に倍率は掛かりません。

rotate

rotate(angle)は、原点(0, 0)を中心に時計回りに回転する角度を指定します。

<svg width="100px" height="100px" viewBox="-50 -50 100 100">
  <rect x="-25" y="-25" width="50" height="50" style="fill: blue" transform="rotate(30)" />
</svg>

rotate(angle, x, y)と引数を増やすことで、回転の中心を指定することができます。

<svg width="100px" height="100px">
  <rect x="25" y="25" width="50" height="50" style="fill: blue" transform="rotate(30, 50, 50)" />
</svg>

skew

skewX(angle)skewY(angle)は、それぞれ x 軸、y 軸の傾き角度を設定します。

<svg width="100px" height="100px">
  <rect width="50" height="50" style="fill: blue" transform="skewX(20)" />
</svg>

<svg width="100px" height="100px">
  <rect width="50" height="50" style="fill: blue" transform="skewY(20)" />
</svg>

組み合わせ

上記のプロパティは組み合わせることが可能です。 指定した順に処理される点に注意してください。 下記であれば、回転 → 移動 → 伸縮 → 傾斜の順で処理されます。

<svg width="100px" height="100px">
  <rect x="25" y="25" width="50" height="50" style="fill: blue"
    transform="rotate(30, 50, 50) translate(-10, -10) scale(0.75) skewY(35)" />
</svg>