SVGに画像をぴったりと配置〜
preserveAspectRatio。

〽️preserveAspectRatio。 〽️alignment。 〽️meet/slice。 〽️実践してみる。 〽️お疲れ様でした。





⬆︎SVGついてのまとめページはこちら。

こんにちは、「ふ」です。
ここのところSVGアニメーションの記事では、画像を読み込んでのいろんなアニメーションを扱っていますが、SVG領域に対し縦横比の違う画像を貼ると、どのようになるのでしょうか。

縦横比4:3のSVG領域に、16:9の画像を配置してみます。

■ HTML

<svg viewBox = "0 0 400 300"> <image xlink:href = "fu.png"/> </svg>

■ CSS

image { width:100%; }

CSSでwidthだけ100%に指定しました。

結果がこちら。
画像がSVG領域の上部に揃えられ、下の部分が空いてしまっています。

本来ならこう⬆︎したいところ。高さいっぱいに表示して、SVG領域の形でトリミング。

実現するには、「preserveAspectRatio」という長〜い名前の属性を<image>に指定してやらなければいけません。
今回はこのpreserveAspectRatio属性の挙動と、それを理解することで画像をSVG領域にぴったりと配置する方法について紹介していきます。

preserveAspectRatio。


preserveAspectRatioは、Aspect Ratio(見た目の比率)をpreserve(保存する、維持する)という意味です。
元画像の縦横比を保ったまま、領域にぴったりと収めるための指定を行います。

preserveAspectRatio = "(照準) (処理)"

例:
<image preserveAspectRatio = "xMidYMid meet" ‥ />

値の前半はalignment(照準)を指定し、後半は処理の内容を指定します。それぞれの内容について、詳しくみていきましょう。

alignment。


alignment(照準)とは何のためにあるのでしょうか。

画像の縦横比を保ったまま拡大・縮小すると、元画像と領域はそもそも比率が違うので、必ず隙間もしくははみ出しが生じます。
そうすると「領域と元画像のどの部分を揃えてから、高さ若しくは幅を合わせるか」によって表示結果は変わってきます。

今、4:3の領域に16:9の元画像があります。
双方の左端を揃えた状態で、元画像の高さを領域いっぱいまで引き伸ばしてみます。

左端を揃えたまま高さを合わせると、画像の右側がはみ出す結果となりました。

今度は中央を揃えた状態で高さを合わせます。
そうすると画像の両側が均等にはみ出しました。

このように、「元画像と領域のどの部分を揃えてから処理を行うか」を指定するのが、「照準を指定する」という意味です。

値はx、y方向それぞれを指定します。

x : min/mid/max
y : min/mid/max

ここでいう「min/mid/max」は、座標的な意味での最小値、中間値、最大値を指します。
SVGの座標は左上を原点とし、右に向かってx軸、下に向かってy軸が伸びています。

仮に、

 x : min
 y : max

とすると、

元画像のxmin(左端)と領域のxmin(左端)、
元画像のymax(下端)と領域のymax(下端)

を揃えて照準とする、という意味に成増。

〜もう1つくらい例をあげてみます。

 xmid
 ymin

だと、

x方向は真ん中(中間値)、y方向は上端(最小値)で揃えられます。
イメージ掴めたでしょうか?

実際の表記はxの指定とyの指定を一撃で表現します。例えば「x-mid-y-max」であれば、

preserveAspectRatio = "「「1xMidYMax」」 (処理)"

のように記述します。
一見キャメルケースが複雑に感じるかもですが、

 x - mid - y - max

と分解してみれば納得できますね。

meet/slice。


指定値の後半部分は処理方法を記述します。値はmeetもしくはsliceのいずれかから選択します。

meet : 長いほうを領域に合わせる
slice : 短いほうを領域に合わせ、はみ出した部分はカット。

meetは、「元画像の長いほうを領域に合わせる」処理です。

領域が4:3、元画像が16:9で、領域よりも横長の元画像に「meet」を施した場合。

元画像の長いほう(ここでは横方向)を領域にフィットさせるので、縦方向に隙間が生じました。

今度は領域4:3、元画像はスマホ画面のような9:16のもので試してみます。
この場合「元画像の長いほう」は、縦方向ですね。

縦成分が揃えられて、横方向に隙間ができました。

「meet」を施すと、領域内に元画像の全体を収めることができます。が、領域との縦横比が異なる場合には隙間が生じます。

いっぽうsliceは「元画像の短いほうを領域に合わせる」処理で、そして領域からはみ出した部分はカットされます。

「meet」のはじめに使った領域4:3、元画像が16:9で、領域よりも横長の元画像。これに「slice」を施してみます。

元画像の短いほう = 縦方向が領域に揃えられ、はみ出た部分はカットされました。

「meet」のときと同じく、領域は4:3のまま、縦長9:16の元画像で「slice」を試してみます。

短い方の「横幅」が揃えられてはみ出し分がカットされました。

「slice」は領域に余計な空白を作らずに収めることができます。ただしはみ出した分はカットされてしまうので、照準を指定するときには配慮が必要です。

実践してみる。


では実際に、「照準」と「処理」を合わせて使ってみましょう。
4:3の領域に16:9の画像を配置するケースを考えます。

imageにおけるpreserveAspectRatio属性は、image自体の矩形に対して働きます。
従ってSVG領域の内部に、imageの表示領域を明確に指定してやる必要があります。

■ CSS

image { width:100%; 「「1height:100%;」」 }

ここでは親要素の<svg>領域と同じにするため、予め指定していたwidthに加え、heightも100%に指定しました(位置に関しては初期値の(0,0)のままで良いので省略しています)。

現在の状態です‥ん?
元画像がすでに横いっぱいに広がり、上下に隙間ができています。

実はimageの矩形を定義した時点で、preserveAspectRatioの初期値である、

preserveAspectRatio = "xMidYMid meet"

が適用されているんです。
実際の処理は瞬時に行われるのですが、あえて分解して見てみましょう。

「xMidYMid」ということは、縦横中心を照準に取っています。

「meet」で元画像の広いほう、即ち横幅を領域にフィット。
これが「xMidYMid meet」の結果です。

次は「slice」してみます。属性値を改めて記述する事で、初期値から変更します。

<image xlink:href = "fu.png" preserveAspectRatio = "「「1xMidYMid slice」」"/>

また動きを分解してみます。
照準は縦横ともに中心をそろえて・・



幅の狭いほう(縦方向)が領域に合わせられました。水平方向にはみ出た部分はカット。
これが通常の「中央トリミング」と言えますね。

普通じゃないっぽいのもやってみます。照準を「xMaxYMax」としてみました。
この状態でmeet/sliceを試してみます。






<image xlink:href = "fu.png" preserveAspectRatio = "「「1xMaxYMax meet」」"/>

「meet」を施すと、xMaxYMax(右下)を照準に横幅が広げられました。
元画像自体は領域の下部に接しています。





<image xlink:href = "fu.png" preserveAspectRatio = "「「1xMaxYMax slice」」"/>

「slice」では、右下を照準に高さがフィットされ、左にはみ出た部分がカットされました。元画像の右寄りにトリミングされた形ですね。

「照準」と「処理」を分解して考えれば、結果をある程度予測してのコーディングが可能です。
みなさんも色々試して、感触をつかんでくださいね。

お疲れ様でした。


最後までお読みいただき、ありがとうございました。
今回は「preserveAspectRatio」という、たった1つの属性について長々と紹介させていただきました。属性の名前からして長いですね💧

preserveAspectRatioについては「ふ」も、はじめは理解に苦しみました。
そのこともあり、「徹底解説」を目指して記事を書かせていただいた次第です。お役に立てれば幸いです。

扨(さて)SVG領域で画像を操るアニメーション、試してみたい事がまだまだあります。
調査完了次第、発信していきますのでまたお会いしましょう。ではまた〜 ♬



HTMLで画像を重ねる、便利な方法。

2021.01.20
positionやz-index指定なし。

SVGアニメーション01、画面内にフェードインさせる方法。

2020.05.10
〽️ 新シリーズはじめました。



ページめくりアニメーション 作り方。

2021.02.02
画像を読み込むだけで実装。












「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。