0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第12回 SVG viewBoxとpreserveAspectRatio

Posted at

はじめに

今回はviewBoxpreserveAspectRatioについてまとめたいと思います。
前回、viewBoxviewportの縦横比が同じ場合について記載しました。
viewBoxviewportの縦横比が同じ場合、viewportのサイズに応じて描画をしてくれます。
一方、viewBoxviewportの縦横比が異なる場合、どのように配置するかを調整できるのがpreserveAspectRatioです。
今回は、このpreserveAspectRatioの使い方をまとめたいと思います。preserveAspectRatioはほかの属性と一緒に使うこともできるようですが、今回はviewBoxとの組み合わせについてに特化して説明します。

また、後ほど説明しますが、今回は、meetOrSlicemeet相当を設定して説明します。

今回実施する内容

今回はviewBoxpreserveAspectRatioについてまとめたいと思います。

ソースコード(Git Hub)

環境

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

参考

7.8 The ‘preserveAspectRatio’ attribute

用語

特になし

preserveAspectRatioの説明

属性の名称から、「アスペクト比の保持」ということなので、viewBoxのアスペクト比を保持してどのように配置するのかを設定するためのものということがわかります。
アスペクト比を維持しない設定もできます。

preserveAspectRatioは、

preserveAspectRatio="[defer] <align> [<meetOrSlice>]"

と定義されています。
deferは今回おいておき、alignmeetOrSliceを扱っていきます。
alignは、viewBoxで切り取った部分をviewportのどこに配置するか(上、右、左、下など)を設定します。
image.png

meetOrSliceは、
meetviewBox<=viewportとなるように収めるか
sliceviewBox>=viewportとなるように収めるか(このときviewBoxは切り取られるため、画面の一部だけが表示される)
を設定します。
デフォルトはmeetです。
image.png

なお、preserveAspectRatioviewBoxの補助として使用する属性のため、viewBoxを設定しない場合、preserveAspectRatioは設定しても無効です。

alignの設定値

alignの値 動作
none 縦横比を維持せず、viewportに合わせる
xMinYMin X軸、Y軸とも最小値
xMidYMin X軸は中心、Y軸は最小値
xMaxYMin X軸は最大値、Y軸は最小値
xMinYMid X軸は最小値、Y軸は中心
xMidYMid X軸は中心、Y軸は中心
xMaxYMid X軸は最大値、Y軸は中心
xMinYMax X軸は最小値、Y軸は最大値
xMidYMax X軸は中心、Y軸は最大値
xMaxYMax X軸は最大値、Y軸は最大値

meetOrSliceの設定値

meetOrSliceの値 動作
meet viewBox<=viewportとなるように収める
slice viewBox>=viewportとなるように収める

設定サンプル

今回は、meetOrSlicemeetで説明します。

preserveAspectRatioなし

viewBoxありで、preserveAspectRatioなしの動作についてです。
image.png

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

今回は、viewBoxと同じサイズの薄黄色(#ffc)の矩形を設定し、viewBoxviewportpreserveAspectRatioの関係がわかりやすいようにしました。

preserveAspectRatioなしの場合、アスペクト比を維持しつつ、viewportのX軸方向、Y軸方向共に中心になるように動作します。
後述しますが、preserveAspectRatio=xMidYMid meet相当の動作です。

none

image.png

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

アスペクト比を維持しないで、縦、横をviewportに合わせます。
viewportを横長の矩形、および、縦長の矩形の例で示すと、円が縦横比によってつぶれているのがわかると思います。

xMinYMinmeetOrSlice設定なし

image.png

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

xMinYMin設定のため、viewport左上を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMidYMinmeetOrSlice設定なし

image.png

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

xMidYMin設定のため、viewport上中心を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMaxYMinmeetOrSlice設定なし

image.png

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

xMaxYMin設定のため、viewport右上を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMinYMidmeetOrSlice設定なし

image.png

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

xMinYMid設定のため、viewport左中心を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMidYMidmeetOrSlice設定なし

image.png

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

xMidYMid設定のため、viewport中心を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMaxYMidmeetOrSlice設定なし

image.png

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

xMaxYMid設定のため、viewport右中心を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMinYMaxmeetOrSlice設定なし

image.png

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

xMinYMax設定のため、viewport左下を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMidYMaxmeetOrSlice設定なし

image.png

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

xMidYMax設定のため、viewport下中心を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

xMaxYMaxmeetOrSlice設定なし

image.png

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

xMidYMax設定のため、viewport右下を起点にして、viewBoxviewport上に設定されます。
また、meetOrSliceは未設定の場合、meetになるため、viewBox<=viewportとなるようにviewBoxが設定されます。
その結果、横長の矩形、縦長の矩形で図の通りになります。

おわりに

今回は、preserveAspectRatioalignの設定(meetOrSliceは未設定で、meet相当)について説明しました。
次回は、meetOrSlicesliceに設定した場合について説明します。

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?