晴歩雨描

晴れた日は外に出て歩き、雨の日は部屋で絵を描く

JavaScript、jQuery、CSS)ポップアップ写真画像をブラウザのウインドウサイズに合わせて拡大縮小できるようにした。

以前、HTMLで写真サムネイルアルバム+ポップアップ画像ページを作成した。下はその時のブログ記事。

作成したサムネイルアルバムWebページは、以下。

https://ok2nd.sakura.ne.jp/album/kobe1-v.html

f:id:art2nd:20190902153738j:plain

このWebページのサムネイル画像をクリックすると、ポップアップ的に1枚の写真が拡大されたページを表示する。

f:id:art2nd:20190902154309j:plain

このポップアップページは、ウインドウの横幅のリサイズに合わせて写真画像がリサイズするようになっていたが、縦の高さのリサイズには対応していなかった。(現在の上のページは対応済みになっている。)

≪縦高のリサイズに対応していない版≫
https://ok2nd.sakura.ne.jp/album/photo-v01.php?photo=kobe1/800/20170929143935.jpg

今回、このポップアップ画像ページの写真をウインドウの縦方向のリサイズにも合わせて拡大縮小できるようにした。

しかし、この機能の実現は、このポップアップ画像ページの写真は<img>タグで表示しているだけではなく、<div>で影付き枠やビネット枠を付加していることもあって、簡単ではなかった。

以下、備忘録。

【ボックスの高さをブラウザの高さに合わせる基本的な手段】

まず、基本的な事。<img>や<div>等のボックスをブラウザの横幅に合わせるのは、"max-width: 100%;"で簡単にできるが、高さを合わせるのは簡単ではない。単純に"max-height: 100%;"で解決するわけではない。

とりあえずは、親要素のhtmlやbodyにも100%を設定するか、

html,body{
	height: 100%;
}
.box{
	height: 100%;
}

%でなく、"vh"を使って、

.box{
	height: 100vh;
}

としないといけない。

【縦の高さのリサイズに一部対応】

今回、写真画像の縦の高さはウインドウに対してパーセント指定ではなく、ウインドウの高さから一定のピクセル値を引いたサイズにしたかったので、各ボックスのheightを100%にした上で、JavaScriptを使って親ボックスの高さを変える事にした。

≪不完全版:縦高のリサイズに一部対応≫
https://ok2nd.sakura.ne.jp/album/photo-v02.php?photo=kobe1/800/20170929143935.jpg

<div class="page-box">
<div class="box-frame">
	<div class="vignette">
		<img id="photo" src="kobe1/800/20170929143935.jpg">
	</div>
</div>
</div>
<style>
.box-frame {
	height: 100%;
	...
}
.vignette {
	height: 100%;
	...
}
img {
	height: 100%;
	...
}
</style>
<script>
$(function(){
	photoResize();
});
// ブラウザ・ウインドウのリサイズ
$(window).on('resize',function(){
	photoResize();
});
function photoResize() {
	// ウインドウの高さから60px引いた値を設定
	$('.page-box').outerHeight($(window).height() - 60);
}
</script>

しかし、この方法では、ウインドウの縦横比率が写真画像の縦横比率に比べて縦長の場合に、縦方向に間延びした画像になってしまう。

f:id:art2nd:20190902172203j:plain

【縦の高さのリサイズに対応】

上記の問題をクリアするために、ウインドウと写真画像の縦横比率の比較をして、縦長の場合には、親ボックスも含めて、各ボックスの高さ(height)を全てautoにするようにした。しかし、これではまだ問題があることが判明。解決策は以下に。

≪未完成:縦高のリサイズに対応≫
https://ok2nd.sakura.ne.jp/album/photo-v03.php?photo=kobe1/800/20170929143935.jpg

<script>
var photoRatio;
$(function(){
	// 画像オリジナルの横幅・高さを得る
	var photoW = document.getElementById('photo').naturalWidth;
	var photoH = document.getElementById('photo').naturalHeight;
	photoRatio = photoH / photoW;
	photoResize(photoRatio);
});
// ブラウザ・ウインドウのリサイズ
$(window).on('resize',function(){
	photoResize(photoRatio);
});
function photoResize(photoRatio) {
	// ブラウザ・ウインドウの横幅・高さを得る
	var windowW = $(window).width();
	var windowH = $(window).height();
	var windowRatio = windowH / windowW;
	if (photoRatio > windowRatio) {	// ウインドウと画像の縦横比率の比較
		// 写真の高さをウインドウの高さに合わせる。
		$('.page-box').outerHeight($(window).height() - 60);
		$('#photo').height('100%');
		$('.box-frame').height('100%');
		$('.vignette').height('100%');
	} else {
		$('.page-box').height('auto');
		$('#photo').height('auto');
		$('.box-frame').height('auto');
		$('.vignette').height('auto');
	}
}
</script>

【後日追記】

しかし、これでは、写真画像がロードされる前にスクリプトが走ってしまい、写真画像の縦横サイズが取得できず、ブラウザウインドウが横長な時にリサイズ処理がうまくいかない事がある。

そこで、画像のロードを待ってから、画像サイズの取得を行うように修正。この場合、HTMLで<img>のsrcに画像のパスが指定されていると、やはり画像のロードが完了しないうちにスクリプトが走ってしまうので、src属性へのパス指定はスクリプトで行う。

≪完成版:画像ロード後に画像サイズを取得するように修正≫
https://ok2nd.sakura.ne.jp/album/photo.php?photo=kobe1/800/20170929143935.jpg

<div class="box-frame">
	<div class="vignette">
<!--	ここでsrcに画像のパスを指定しない -->
		<img id="photo" src="">
	</div>
</div>

<script>
var photoRatio;
$(function(){
	var img = $('#photo');
	img.attr('src', 'xxxxx.jpg');	// 画像ファイルを指定
	img.bind('load', function(){	// 画像のロードを待ってから処理
		// 画像オリジナルの横幅・高さを得る
		var photoW = document.getElementById('photo').naturalWidth;
		var photoH = document.getElementById('photo').naturalHeight;
		photoRatio = photoH / photoW;
		photoResize(photoRatio);
	});
});
// ブラウザ・ウインドウのリサイズ
$(window).on('resize',function(){
	photoResize(photoRatio);
});
function photoResize(photoRatio) {
	// ブラウザ・ウインドウの横幅・高さを得る
	var windowW = $(window).width();
	var windowH = $(window).height();
	var windowRatio = windowH / windowW;
	if (photoRatio > windowRatio) {	// ウインドウと画像の縦横比率の比較
		// 写真の高さをウインドウの高さに合わせる。
		$('.page-box').outerHeight($(window).height() - 60);
		$('#photo').height('100%');
		$('.box-frame').height('100%');
		$('.vignette').height('100%');
	} else {
		$('.page-box').height('auto');
		$('#photo').height('auto');
		$('.box-frame').height('auto');
		$('.vignette').height('auto');
	}
}
</script>