【SVG】描画領域と座標指定
描画領域
描画領域は、<svg>
要素の以下の属性によって設定します。
ビューポート
width
とheight
は、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)
となると考えてください。
viewBox
のwidth
、height
は具体的なサイズを示したものではないので、上の例は最大サイズで表示されます。
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
を省略した場合は、表示領域と描画領域が同じサイズになります。
つまりビューポートのwidth
、height
の値と、viewBox
のwidth
、height
の値が同じになります。
<svg width="100px" height="100px" viewBox="0 0 100 100">
<rect width="50" height="50" style="fill: blue" />
</svg>
preserveAspectRatio
上記のviewBox
の説明では、ビューポートとviewBox
の比率を同じにしていました。
では、以下のように異なる比率を指定するとどうなるでしょうか。
<svg width="100px" height="100px" viewBox="0 0 50 100">
<rect width="50" height="50" style="fill: blue" />
</svg>
<svg width="100px" height="100px" viewBox="0 0 100 50">
<rect width="50" height="50" style="fill: blue" />
</svg>
実は、ビューポートの比率になるようにviewBox
が自動で調整されます。
これをどのように調整するかを決めるのがpreserveAspectRatio
属性です。
指定のある描画領域をどの位置に配置するかを決めて調整を行います。 少しわかりにくいと思うので、以下を見てください。 下手に言葉で説明するよりはイメージできるのではないかと思います。
Min | Mid | Max | none | |
---|---|---|---|---|
x [例1] |
左上:(0, 0) |
左上:(-25, 0) |
左上:(-50, 0) |
左上:(0, 0) |
y [例2] |
左上:(0, 0) |
左上:(0, -25) |
左上:(0, -50) |
左上:(0, 0) |
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
にはmeet
とslice
というオプションがあります。
meet
がデフォルト値となっており、比率の大きな方に描画領域が調整されます。
つまり、上記はすべてmeet
の場合の解説です。
slice
は、比率の小さな方に描画領域が調整されます。
<svg width="100px" height="100px" viewBox="0 0 50 100" preserveAspectRatio="xMidYMid slice">
<rect width="50" height="50" style="fill: blue" />
</svg>
<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 が逆のため注意してください。
Min | Mid | Max | |
---|---|---|---|
y [例1] |
左上:(0, 0) |
左上:(0, 25) |
左上:(0, 50) |
x [例2] |
左上:(0, 0) |
左上:(25, 0) |
左上:(50, 0) |
単位について
表示領域を指定するwidth
、height
には単位を指定できます。
上の例ではpx
を指定していますが、em
、cm
、pt
なども指定できます。
単位を指定しなかった場合は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>