まずベースとなるサンプルを用意しておきます
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>
基本的なこと
まず外側の<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>
そのまま座標をずらし(数学で言う)第一象限を表示してみる
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>
では問題です。以下のソースはどうなるでしょうか?
viewBox="0 0 100 200"
としました。xy座標は最初に戻しました。
ボックスが正方形ではありません。100200の長方形です。外側の枠は変わらず200200の正方形です。
<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>
どうなるのでしょうか?
僕は全然わかりませんでした。
正解と要因
上記の問題ですが、こうなります。
僕は最初これでちんぷんかんぷんになりました。
なぜこうなるのかは、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>
真ん中に枠があります。こういうことですね。
どういうことか?初期設定に依存しています。
ポイントは、ビューポートのエリアと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>
以上ありがとうございました。