画像の縦横比(アスペクト比)を保ったまま、サイズを変更したい。「印刷対応が必要な場合」「常にwindowサイズ-150pxで拡大表示したい場合」など、訳ありでとあるサイズにjsで拡大縮小する処理を紹介します。
目次
下準備
jQueryと、自分で作ったjavascriptのファイル(今回は aspct.js とします)を読み込みます。
1 2 |
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" charset="utf-8"></script> <script type="text/javascript" src="aspct.js" charset="utf-8"></script> |
縦横比を調べるには?
画像の縦横比を調べるには、当たり前なのですが、画像の横幅と縦幅を取得して「横幅÷縦幅」の計算をすれば簡単に割り出すことができます。(横幅÷縦幅が1以上になれば、横長の画像と言うことになります。)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//img#sampleの縦横比を調べる $(function(){ var imgWidth = $('img#sample').width(); //img#sampleのwidthを調べてimgWidthに代入 var imgHeight = $('img#sample').height(); //img#sampleのheightを調べてimgHeightに代入 aspectRatio = imgWidth / imgHeight //横幅÷縦幅の値をaspectRatioに代入 if(aspectRatio >= 1){ //横長画像の場合の処理(横幅÷縦幅が1以上になる場合) }else{ //縦長画像の場合の処理 } }); |
上記の縦横比を調べる処理を使用して、ひとつ例の処理を書いてみましょう。
例1:background-size:cover;のような効果をimgで得る
background-size:cover;の一文が使えればどんなに楽か。しかし印刷対応で使用することができません、そんな時。divでimgを囲み、divにoverflow:hidden;をかけます。デモはこちら
▼HTML
div#sampleに、縦長のimgを表示させます。
1 |
<div class="sample"><img src="photo.jpg" alt=""></div> |
▼CSS
divにはwidthとheightを指定し、overflow:hidden;をかけ、imgのはみ出た部分が非表示になるように設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.sample{ display:block; width:300px; height:200px; text-align:center; position:relative; overflow:hidden; border:#CCC solid 2px; } .sample img{ position:absolute; top:0; left:0; } |
▼js
短い方の辺をdivのサイズに合わせるようにcssをつけます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$(function(){ var imgWidth = $('.sample img').width(); var imgHeight = $('.sample img').height(); aspectRatio = imgWidth / imgHeight if(aspectRatio >= 1){ //横長画像の場合 divのheightに数値を合わせる $('.sample img').css('height','200px'); }else{ //縦長画像の場合 divのwidthに数値を合わせる $('.sample img').css('width','300px'); //上下中央揃えにする場合は下記2行も var i = (imgHeight-200)/2 //はみ出た部分を計算して÷2し、ネガティブマージンをつける $(this).find('img').css('margin-top', '-'+i+'px'); } }); |
例2:例1を複数のdivに適用させたい場合
imgを複数並べて一覧にしたい。その場合は、jsの処理が少々複雑になります。例1のままだと、一番最初に取得したimgの値が他の画像にも適用されてしまうため、大きさがちぐはぐになってしまいます。.eachを使用すれば、div毎に同じ処理を走らせることができます。失敗デモはこちら
成功デモはこちら
▼js
jsに手を加えます。下記のように「each」で挟むと、全てのdiv.sampleに同じ処理が走ります。「$(‘.sample img’)」を全て「$(this).find(‘img’)」に書き換えます。thisを使うと、処理中の要素という意味になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$(function(){ $('.sample').each(function(){ var imgWidth = $(this).find('img').width(); var imgHeight = $(this).find('img').height(); aspectRatio = imgWidth / imgHeight if(aspectRatio >= 1){ //横長画像の場合 divのheightに数値を合わせる $(this).find('img').css('height','200px'); }else{ //縦長画像の場合 divのwidthに数値を合わせる $(this).find('img').css('width','300px'); //上下中央揃えにする場合はこれも var iHeight = $(this).find('img').height(); var i = (iHeight-200)/2 $(this).find('img').css('margin-top', '-'+i+'px'); } }); }); |