Jqueryでlightbox風モーダルウィンドウを作ってみた

ノンプラグインで簡単なギャラリー表示

プラグインで広く利用されているlightboxですが、ちょっとした用途にプラグイン導入は重かったり、カスタマイズが簡単にできるようにと思い、jqueryの理解を深める一環として自分なりにコードを組んでみました。

ギャラリーでの使用を前提にしてありますので、画像のタテヨコ比が変わっても対応出来るように作ったら意外にソースが長くなってしまいました・・・

ソース解説

ソース自体はサンプルを参照して下さい。
それではいくつかポイントを挙げて解説していきます。

初期設定

		var modal = $('#modal'); 		//モーダルウィンドウID
		var cont = $('.modalContent');	//モーダルウィンドウ内部class
		var pSize = 1200;				//画像の長辺サイズ
		var pPadding = 10;				//モーダルウィンドウpadding
		var cMargin = 50;				//モーダルウィンドウmargin

モーダルに関するid・classは任意で。
残りは表示したい縦・横の最大長辺サイズと、モーダルウィンドウ周りのpadding・marginを設定します。

モーダルオープンイベント

イベント自体は単純なクリックイベントです。

背景タグ挿入

$("body").append('<div class="js-modalBack"></div>');	//背景タグ挿入

背景部分はイベント発生時にjqueryで書き込みます。

画像src取得

var imgSrc = $(this).attr('src');	//サムネイル画像src取得
			imgSrc = imgSrc.replace(/-thumb/g,"");	//-thumbを削除して画像urlに変換

画像サムネイルはxxx-thumb.jpg、表示画像はxxx.jpgとしてます。

クリック時にサムネイル画像urlを取得し、-thumbを削除して表示画像urlに変換します。

モーダルウィンドウサイズ計算

サイズが固定されたものならばこの部分はいらないのですが、横長・縦長などタテヨコ比の違うものでも対応できるよう計算しています。
ここが一番苦労しました。

画像サイズ取得

function modalSizeA(imgSrc){
		var img = new Image();
		img.src = imgSrc;

		img.onload = function() {
			var cWidth  = img.width;
			var cHeight = img.height;

			sizeChange(cWidth,cHeight);
		};

};

さて、画像サイズを取得するのですが、画像が読み込まれた後でないと数値を取得できません。
ですので.onloadで読み込み完了後にサイズ取得を行います。

尚、ブラウザリサイズ時は既に読み込まれているのでこの工程はキャンセルしてあります。

サイズ計算

//モーダルウィンドウサイズ計算
function sizeChange(cWidth,cHeight){

	var setWidth = 0;
	var setHeight = 0;
	var left = 0;
	var top = 0;

	var wWidth = $(window).width();
	var wHeight = $(window).height();
	var ratio = cHeight/cWidth;

	if( cWidth >= cHeight){
		if( wWidth < (pSize + pPadding*2 + cMargin*2) ){
			setWidth = wWidth*0.9;
			left = wWidth*0.05;

		}else{
			setWidth = pSize + pPadding*2;
			left = (wWidth - (pSize + pPadding*2))/2;
		};

		setHeight = setWidth*ratio;
		top = (wHeight - setHeight)/2;

		if( wHeight < setHeight ){
			setHeight = wHeight*0.9;
			setWidth = setHeight/ratio;
			top = wHeight*0.05;
			left = (wWidth - setWidth)/2;
		}
	};

	if( cWidth <= cHeight){
		if( wHeight < (pSize + pPadding*2 + cMargin*2) ){
			setHeight = wHeight*0.9;
			top = wHeight*0.05;
		}else{
			setHeight = pSize + pPadding*2;
			top = (wHeight - (pSize + pPadding*2))/2;
		};

		setWidth = setHeight/ratio;
		left = (wWidth - setWidth)/2;

		if( wWidth < setWidth ){
			setWidth = wWidth*0.9;
			setHeight = setWidth*ratio;
			top = wHeight*0.05;
			left = (wWidth - setWidth)/2;
		}
	};

	modal.css({
		'width' : setWidth,
		'heigt' : setHeight,
		'top' : top,
		'left' : left
	});
};

先ほど取得した画像サイズとブラウザサイズ、あと画像のタテヨコ比を使って計算します。

ざっくり説明すると、画像の長辺が横なのか縦なのかで分岐。
長辺とブラウザサイズを比較してモーダルの長辺サイズを算出した後、タテヨコ比を使って短辺サイズを算出しています。

ブラウザサイズが画像(maragin+padding)より小さい場合

・モーダルウィンドウ長辺をブラウザサイズの90%
・marginを5%
・短辺は長辺にタテヨコ比を乗算(除算)して算出。

ブラウザサイズが画像(maragin+padding)より大きい場合

・モーダルウィンドウ横幅を初期設定値の最大サイズ(pSizeで設定した値)
・モーダルウィンドウをセンター寄せ
・短辺は長辺にタテヨコ比を乗算(除算)して算出。

モーダルクローズイベント

//モーダルクローズイベント
$(function(){
	$(document).on('click' , '.js-closeBtn , .js-modalBack' , function(){
		modal.fadeOut(300 , function(){
			$('.js-modalBack').remove();	//背景フェードアウト・タグ除去
		});
	});
});

閉じるボタンかモーダル背景をクリックでモーダルウィンドウをフェードアウト、あわせてモーダル背景を除去します。

作成時にハマッたポイント

画像ローディングのタイミング

最初.onloadを使わず画像取得→サイズ取得のフローで作成したのですが、値が0になってしまい機能しませんでした。
調べてみると画像のロードまでタイムラグがあるので.onloadでロード完了後にサイズを取得することで解決しました。

モーダルウィンドウサイズの算出

今回は主に写真のギャラリー前提で作成したのでモーダルウィンドウのサイズを算出するのに苦労しました。

ブラウザサイズに合わせて可変や比率固定されたものならここまで面倒な計算は必要なかったのですが、表示画像にあわせて、さらにブラウザサイズで可変する仕様にしたため、計算式が長くなってしまいました。

とはいえまだまだ勉強中の身なので、分かる人が組めばもっとシンプルになるのかも知れません。

ちなみにサンプルはサムネイル画像を別比率で用意していますが、表示画像と同比率の画像をサムネイルにあてることも可能です。

まとめ

ということでjqueryの練習も兼ねてlightbox風モーダルウィンドウを作成してみました。

なんとなく「こうやればできる」的な考えで実践してみると、あちこちに落とし穴があって都度勉強になって良いですね。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA