roomx.jp

Room No.1

JavaScript

Lightbox風 画像ビューワ

2013.09.26

jQueryプラグインの Lightbox を導入すれば手っ取り早いのですが、自分のサイトに合わせてカスタマイズしようとすると結構敷居が高いのも事実で・・・

もっと簡単に画像ビューワ(拡大表示)が出来ないものかとネットを漁ってみたのですが、どれもイマイチしっくりこないので自分でコードを書いてみました。

参考にさせて頂いたサイト ・・・ A Cool CSS Effect - Dashboard (英語)

上記のサイトのコードも1ヶ所のリンク、若しくは1枚のサムネイル画像に対して1枚の拡大画像となっており、複数の画像を表示する画像ギャラリー形式のページでそのまま使うにはコードが冗長的になり過ぎ、また各ブラウザに依存したCSSのアルファ効果(opacity等)を使っているので画像ビューワで使うには少々難があります。(後述)

なのでこのコードを元にしてゴニョゴニョと・・・

画像送りやズーム表示する際のアニメーション効果、プログレスバーなど凝ったギミックはありませんが、その分軽くて jQuery も必要無いので導入(?)やメンテも簡単だと思います。基本的にサイトの単独ページ向けに作ったのですが、コード自体が単純なので一工夫すればWordPressなどのCMSにも組み込めると思います。(流石にある程度のスキルは必要ですが…)

表示可能な画像形式はブラウザに依存し、ブラウザが対応している画像であれば全て表示可能です。
ただし、このバージョンでは画像の保存先(呼び出し先)にJPEG画像とPNG画像が混在している場合など、表示可能な画像形式はどれか1つの形式に限られます。しかし、それもPHPなどのSSIでサムネイル画像部分のHTMLを生成し、JavaScriptに渡すパラメータをサムネイルの画像形式に合わせて変化させれば解決できます。

今回はPHPのコードまで説明すると長くなるので、通常の HTML+CSS+JavaScript に絞って紹介したいと思います。

処理の流れ

大まかな処理の流れは以下のようになります。

サムネイル画像をdivでマークアップするのに手打ちで行うか、PHPを使って自動化するか…
画像枚数が少なければ手打ちでも良いのですが、10枚以上とかになるとPHPで自動化した方が現実的かもしれません。

・動作確認 → Lightbox風 画像ビューワ : like_lightbox_100.html

・サンプルダウンロード → like_lightbox_1.zip [417KB]

 


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Lightbox風 画像ビューワ</title>
<style>
.img_thm{
	display: inline;
	margin: 5px;
}

#imglay {
	text-align: center;
	display: none;
	position: absolute;
	width: 100%;
	z-index:100;
	background-image: url(img/img_bak64.png);   //背景透過PNG画像指定
	background-repeat: repeat;
	background-position: center top;
	padding-top: 30px;
	padding-bottom: 30px;
	overflow: auto;
	left: 0px;
	top: 0px;
}

#imglay p {
	color: #FFFFFF;
	text-align: center;
	width: 100%;
}
#imglay img {
	/*opacity: 1.0;               /* Safari, Opera */   //今回は未使用
	/*-moz-opacity:1.0;           /* FireFox */
	/*filter: alpha(opacity=100); /* IE */
	border: 20px solid #FFFFFF;
	overflow: auto;
}
#imglay #img_close {   //CLOSEボタン領域
	width: 100%;
}
#imglay #img_close a {
	text-decoration: none;
	width: 120px;
	padding-top: 15px;
	padding-bottom: 15px;
	margin-right: auto;
	margin-left: auto;
	display: block;
}
#imglay #img_close img {
	border: none;
}
</style>
</head>
 
<body>
 
<div class="img_thm" onclick="return Simg('01');">
<img src="img/sample/s01.jpg" width="200" height="150" alt="Flashlight">
</div>
<div class="img_thm" onclick="return Simg('03');">
<img src="img/sample/s03.jpg" width="200" height="150" alt="Flashlight">
</div>
<div class="img_thm" onclick="return Simg('07');">
<img src="img/sample/s07.jpg" width="200" height="150" alt="Flashlight">
</div>
 
<div id="imglay">
<p>UltraFire C1</p>
<div onclick="return Limg()"><img id="img_view" src=""></div>
<div id="img_close">
<a href="javascript:void(0)" onclick="return Limg()">
<img src="img/close.png" alt="CLOSE"></a>
</div> 
</div>
 
<script type="text/javascript">
<!--
function Simg(n){
    document.getElementById('imglay').style.display='block';
    /*var img_dir = 'http://hoge/img/img_file';*/
    var img_dir = 'img/sample/';   //画像ファイルのパス
    var img_num = n;               //連番画像の番号:画像ファイル名
    var img_ext = '.jpg';          //拡張子:JPEG画像
    document.getElementById('img_view').src = img_dir + img_num + img_ext;
}
function Limg(){
    document.getElementById('imglay').style.display='none';
}
//-->
</script>
 
</body>
</html>

 

解説・注意点

コードを書く際にアレだった点など・・・(´・ω・`)


#imglay {
	~
	display: none;
	position: absolute;
	width: 100%;
	z-index:100;
	background-image: url(img/img_bak64.png);   //背景透過PNG画像指定
	~
}

拡大画像の表示エリアに関するCSSですが、 display: none; とする事で通常時は非表示となります。
position: absolute; は表示エリアサイズ・座標の絶対表示、z-index:100; で重ね順を指定しています。

画像以外の背景部分を半透明にしたいので透過PNG画像を使っています。
これはCSSのアルファ値プロパティを設定すると、関連するdiv要素直下に含まれる全ての要素が半透明になってしまう仕様を回避する為です。画像部分を別のdivで括っても親要素に対してネスト(子要素)されている場合は半透明の呪縛からは逃れられず、かといって全く別のdiv要素で拡大画像部分を配置するのもアレなので、一番お手軽と思われる方法で済ませています。

 


#imglay img {
	/*opacity: 1.0;               /* Safari, Opera */   //今回は未使用
	/*-moz-opacity:1.0;           /* FireFox */
	/*filter: alpha(opacity=100); /* IE */
	border: 20px solid #FFFFFF;
	overflow: auto;
}

背景だけで無く前景(拡大画像)まで半透明になってしまうので今回は未使用。前述の方法で表示エリアの背景を半透明としています。

 


<div class="img_thm" onclick="return Simg('01');">
<img src="img/sample/s01.jpg" width="200" height="150" alt="Flashlight">
</div>

画像サムネイルのHTMLですが、onclick を使っているので<a>タグを使う必要は有りません。(onclick はdiv要素全てに有効となる)
しかし<a>タグを使って無いので、マウスカーソルが変化せずクリッカブルな要素か否かユーザーに伝わり難いという欠点があります。<a>タグを使った場合に【 a href="javascript:void(0)"】と記述が長くなるのがアレなので短く記述するようにしていますが、どちらにするかはお好みで・・・
(蛇足ですがマウスカーソルもCSSのcursor:で制御できます)

メインのJavaScriptに投げる部分は Simg( ) になりますが、パラメータ(引数)はサムネイル画像に対応したオリジナル画像の画像番号としています。このパラメータに拡張子や他の属性も含めれば拡大画像表示に必要な他の属性もコントロール可能になります。
JavaScriptだけでなくPHPも使って処理する場合も考え、便宜上ファイル名を連番としていますが、規則性の無いファイル名を扱う場合でも要領は同じです。

サムネイル画像は実体ファイルが必要となり常時表示する事になるので alt属性はきちんと設定した方が良いと思います。

 


<div id="imglay">     //拡大画像表示エリア
<p>UltraFire C1</p>   //画像キャプション
<div onclick="return Limg()"><img id="img_view" src=""></div>   //src部分は空
<div id="img_close">
<a href="javascript:void(0)" onclick="return Limg()">   //拡大画像非表示(ボタン画像使用)
<img src="img/close.png" alt="CLOSE"></a>
</div> 
</div>

<div id="imglay"> が拡大画像の表示エリアとなります。
ただしこの部分は通常非表示となっており、サムネイル画像をクリックした時にのみ src 部分にオリジナル画像をセットし表示される仕組みです。

<p>タグの画像キャプションは固定となっていますが、この部分を画像に応じて可変にする場合や短い説明文(テキスト)を表示する場合などはPHPやデータベースと連動させた方が現実的かもしれません。

今回は <div id="imglay"> が表示されている場合にエリアのどこをクリックしてもビューワが閉じる仕様ですが、操作が判り易いように【閉じるボタン】などを配置した方が良いと思います。単に閉じる為のリンクを文字で記述しても良いのですが表示画面が単調になりがちなのでボタンを画像化してみました。

 


<script type="text/javascript">
<!--
function Simg(n){
    document.getElementById('imglay').style.display='block';
    /*var img_dir = 'http://hoge/img/img_file';*/
    var img_dir = 'img/sample/';   //画像ファイルのパス
    var img_num = n;               //連番画像の番号:画像ファイル名
    var img_ext = '.jpg';          //拡張子:JPEG画像
    document.getElementById('img_view').src = img_dir + img_num + img_ext;
}
function Limg(){
    document.getElementById('imglay').style.display='none';
}
//-->
</script>

JavaScriptのメイン部分です。

function Simg(n) にサムネイルがクリックされた場合の処理を記述しています。
document.getElementById('imglay').style.display='block'; で非表示にしていたエリア(div要素)を表示し、パラメータ(n)を元にしてオリジナル画像を呼び出しています。実際にレンタルサーバーのWEBページ内で使う場合はファイルのパス名をサイト構造に応じて書き換えて下さい。(うまく画像が呼び出せない場合は http://hoge/~ など絶対パスで指定)

function Limg() は画像ビューワを閉じる処理です。(非表示はCSSで設定)
今回はdiv要素全体を指定していますが、特定の要素のみを対象にする場合は、document.getElementById('***') でピンポイント指定する必要があります。

jQuery + 本家Lightbox を使えばお洒落な画像ビューワを実現出来ますが、どうせ一時の流行ですから・・・と、負け惜しみを言ってみる…(´・ω・`)

▲BACK TO TOP