LightBox タイプフォトギャラリー(送りボタン付き)

LightBoxt タイプのギャラリーで、サムネイルクリックで拡大写真がフェイドインで登場し(transitionによる)、画面マウスオーバーで左右の送りボタンが表示され、そのクリックで左右に写真がスライドして次の写真が登場する(animationによる)。フェイドインの登場は、width/height の特性を使えば、拡大して登場するタイプに変更できる。 cssで作ると、各写真毎のスクリプトを記述しなければならないし、各ブラウザに対応させる記述も必要となるなど、コードが膨大になるが、作りはシンプルだし、ほとんどはコピペで対応できるので、見た目よりはずっと楽である。

サンプル

1/5   朝焼けの焼岳
2/5   針ノ木岳、スバリ岳を背に岩小屋沢岳への登り
3/5   剣岳を真近に望む
4/5   鹿島槍ヶ岳、後立山連峰
5/5   岩小屋沢、鳴沢岳を背に岳爺ヶ岳への登り


本サンプル表示用HTML

<input type="radio" id="r1" name="gal">
<input type="radio" id="r2" name="gal">
<input type="radio" id="r3" name="gal">
<input type="radio" id="r4" name="gal">
<input type="radio" id="r5" name="gal">
<input type="radio" id="r6" name="gal">
<input type="radio" id="r7" name="gal">
<input type="radio" id="n1" name="gal">
<input type="radio" id="n2" name="gal">
<input type="radio" id="n3" name="gal">
<input type="radio" id="n4" name="gal">
<input type="radio" id="b2" name="gal">
<input type="radio" id="b3" name="gal">
<input type="radio" id="b4" name="gal">
<input type="radio" id="b5" name="gal">
<div id="thumbs">
  <label for="r1"><img src="img2/s1.jpg"></label>
  <label for="r2"><img src="img2/s2.jpg"></label>
  <label for="r3"><img src="img2/s3.jpg"></label>
  <label for="r4"><img src="img2/s4.jpg"></label>
  <label for="r5"><img src="img2/s5.jpg"></label>
</div>
<div id="frame">
</div>
<label for="r7">
	<div id="darkscreen"></div>
</label>
<div id="stage">
  <div id="close_btn">
    <label for="r6">? 閉じる</label>
  </div>
  <div id="photos">
  	<div id="photo1">
    	<img src="img2/m1.jpg">
        <span class="title">1/5   朝焼けの焼岳</span>
        <label for="n1"><div id="right1" class="cover_right"><span>></span></div></label>
    </div>
  	<div id="photo2">
    	<img src="img2/m2.jpg">
        <span class="title">2/5   針ノ木岳、スバリ岳を背に岩小屋沢岳への登り</span>
        <label for="n2"><div id="right2" class="cover_right"><span>></span></div></label>
        <label for="b2"><div id="left2" class="cover_left"><span><</span></div></label>
    </div>
  	<div id="photo3">
    	<img src="img2/m3.jpg">
        <span class="title">3/5   剣岳を真近に望む</span>
        <label for="n3"><div id="right3" class="cover_right"><span>></span></div></label>
        <label for="b3"><div id="left3" class="cover_left"><span><</span></div></label>
    </div>
  	<div id="photo4">
    	<img src="img2/m4.jpg">
    	<span class="title">4/5   鹿島槍ヶ岳、後立山連峰</span>
        <label for="n4"><div id="right4" class="cover_right"><span>></span></div></label>
        <label for="b4"><div id="left4" class="cover_left"><span><</span></div></label>
    </div>
  	<div id="photo5">
    	<img src="img2/m5.jpg">
        <span class="title">5/5   岩小屋沢、鳴沢岳を背に岳爺ヶ岳への登り</span>
        <label for="b5"><div id="left5" class="cover_left"><span><</span></div></label>
    </div>
  </div>
</div>

HTMLの概要説明


・各写真に対応するラジオボタン(r1-r5)、閉じるボタン(r6)、darkscreen 非表示用(r7)、写真送り用左右ボタンに対応(n1-n4,b2-b5)するラジオボタンを定義する。これらは、CSSで非表示にする。
・サムネイル写真(ここでは5枚)は、#thumbs 内に表示させる。
・大きな写真の下に#frame(白い矩形で写真より少し大きいサイズにして枠取りと文字表示に使う)を配置する。
・大きな写真は、div #photos の中の隙間なく横並びに並んだ#photo1-#photo5 のdivにそれぞれ入れるが、同時に各photo divにはそれぞれの表題と、左右送りボタン領域を入れ込む。
 (#photo1-#photo5は、photosがアニメーションで移動すると、表題、送りボタン領域と一緒に移動する)
・送りボタン領域は、写真の上層に、左右に非表示で2箇所配置し、そのマウスオーバーで領域内の"<"と">"が表示されるようにする(CSS)。
・写真表示用領域の#stageを親divとして配置し、サイズを写真サイズに合わせ、CSSのoverflow:none; として枠外を非表示にする。
・#frameの下層に、#darkcreen (画面者併用半透明黒色スクリーン)を配置し、大きなサイズ写真表示時に表示させる。

本サンプル表示用CSS

/*全サムネイルのコンテナー*/
#thumbs {
	position: relative;
	width: 630px;
	left: 20px;
	margin:0 auto;
}
/*サムネイルのマウスオーバーでポインターを手のひら*/
#thumbs label img {
	cursor: pointer;
}
/*ラジオボタンを非表示に*/
#r1, #r2, #r3, #r4, #r5, #r6, #r7,#n1,#n2,#n3,#n4,#b2,#b3,#b4,#b5 {
	display: none;
}
/* 写真表示領域 */
#stage {
	position:fixed !important;
	position:absolute;
	width:1000px;
	height:590px;
	left:50%;
	top:50%;
	margin-left:-500px;
	margin-top:-270px;
	overflow:hidden;
	opacity:0;
	z-index:-20;
}
/* 写真を横並びに格納する帯状DIV */
#photos {
	position:absolute;
	opacity:0;
	width:5000px;
	left:-2000px;
	-webkit-transition: opacity 0.8s ease;
	-moz-transition: opacity 0.8s ease;
	-o-transition: opacity 0.8s ease;
	transition: opacity 0.8s ease;
}
/*表示写真の初期配置(全部透明に)*/
#photo1, #photo2, #photo3, #photo4, #photo5 {
	position:relative;
	float:left;
}
/* 写真表示の白い台紙となるDIV */
#frame {
	position:fixed !important;
	position:absolute;
	background:#fff;
	width:1010px;
	height:600px;
	left:50%;
	top:50%;
	margin-left:-505px;
	margin-top:-275px;
	opacity:0;
	z-index:-11;
}
/* 写真の表題 */
.title {
	position:absolute;
	left:10px;
	top:575px;
	font-size:12px;
}
/* 閉じるボタン */
#close_btn label {
	position:absolute;
	left:900px;
	top:570px;
	font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
	font-size:14px;
	font-weight:bold;
	background:#fff;
	cursor:pointer;
}
/*写真表示時の画面遮蔽スクリーン*/
#darkscreen {
	position:fixed !important;
	position:absolute;
	width:100%;
	height:100%;
	top:0;
	left:0;
	background:#000;
	opacity:0;
	z-index:-5;
}

/*ボタン領域の設定*/
.cover_left, .cover_right {
	position:absolute;
	top:0;
	width:400px;
	height:563px;
	cursor:pointer;
	z-index:1000;
}
.cover_left {
	left:0;
}
.cover_right {
	left:600px;
}
/*ボタン領域内のボタン文字(<、>)の設定*/
.cover_left span, .cover_right span {
	position: absolute;
	font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", "メイリオ", Meiryo, Osaka, "MS Pゴシック", "MS PGothic", sans-serif;
	font-size: 40px;
	font-weight: bold;
	opacity:0;
	top: 260px;
}
.cover_left span {
	left: 20px;
}
.cover_right span {
	left: 330px
}
/*ボタン領域hover時文字の設定*/
.cover_right:hover > span, .cover_left:hover > span {
	opacity:1;
	color:#EEE;
}
/*サムネイル、送りボタンチェックで#frameを表示*/
#r1:checked ~ #frame, #r2:checked ~ #frame, #r3:checked ~ #frame, #r4:checked ~ #frame, #r5:checked ~ #frame, #n1:checked ~ #frame, #n2:checked ~ #frame, #n3:checked ~ #frame, #n4:checked ~ #frame, #b2:checked ~ #frame, #b3:checked ~ #frame, #b4:checked ~ #frame, #b5:checked ~ #frame {
 z-index:95;
 opacity:1;
}
/* サムネイル、送りボタンチェックで#stageを表示 */
#r1:checked ~ #stage,#r2:checked ~ #stage,#r3:checked ~ #stage,#r4:checked ~ #stage,#r5:checked ~ #stage, #n1:checked ~ #stage, #n2:checked ~ #stage, #n3:checked ~ #stage, #n4:checked ~ #stage, #b2:checked ~ #stage, #b3:checked ~ #stage, #b4:checked ~ #stage, #b5:checked ~ #stage {
	z-index:100;
	opacity:1;
}
/* サムネイル、送りボタンチェックで#photosを表示 */
#r1:checked ~ #stage #photos,#r2:checked ~ #stage #photos,#r3:checked ~ #stage #photos,#r4:checked ~ #stage #photos,#r5:checked ~ #stage #photos, #n1:checked ~ #stage #photos, #n2:checked ~ #stage #photos, #n3:checked ~ #stage #photos, #n4:checked ~ #stage #photos, #b2:checked ~ #stage #photos, #b3:checked ~ #stage #photos, #b4:checked ~ #stage #photos, #b5:checked ~ #stage #photos {
	opacity:1;
}
/* サムネイル、送りボタンチェックで#darkscreenを表示 */
#r1:checked ~ label #darkscreen, #r2:checked ~ label #darkscreen, #r3:checked ~ label #darkscreen, #r4:checked ~ label #darkscreen, #r5:checked ~ label #darkscreen, #n1:checked ~ label #darkscreen, #n2:checked ~ label #darkscreen, #n3:checked ~ label #darkscreen, #n4:checked ~ label #darkscreen, #b2:checked ~ label #darkscreen, #b3:checked ~ label #darkscreen, #b4:checked ~ label #darkscreen, #b5:checked ~ label #darkscreen {
 opacity:0.6;
 z-index:90;
}
/* 各サムネイルがチェックされた時の#photos の位置 */
#r1:checked ~ #stage #photos {
	margin-left:2000px;
}
#r2:checked ~ #stage #photos {
	margin-left:1000px;	
}
#r3:checked ~ #stage #photos {
	margin-left:0px;	
}
#r4:checked ~ #stage #photos {
	margin-left:-1000px;	
}
#r5:checked ~ #stage #photos {
	margin-left:-2000px;	
}
/* 各送りボタンがクリックされた時のスライド送りのanimationの設定とanimationの定義 */
#n1:checked ~ #stage #photos {
	margin-left:2000px;
	-webkit-animation:passphotos2 1s ease;
	-moz-animation:passphotos2 1s ease;
	animation:passphotos2 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#n2:checked ~ #stage #photos {
	margin-left:1000px;
	-webkit-animation:passphotos3 1s ease;
	-moz-animation:passphotos3 1s ease;
	animation:passphotos3 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#n3:checked ~ #stage #photos {
	margin-left:0px;
	-webkit-animation:passphotos4 1s ease;
	-moz-animation:passphotos4 1s ease;
	animation:passphotos4 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#n4:checked ~ #stage #photos {
	margin-left:-1000px;
	-webkit-animation:passphotos5 1s ease;
	-moz-animation:passphotos5 1s ease;
	animation:passphotos5 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#b2:checked ~ #stage #photos {
	margin-left:1000px;
	-webkit-animation:passphotos1 1s ease;
	-moz-animation:passphotos1 1s ease;
	animation:passphotos1 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#b3:checked ~ #stage #photos {
	margin-left:0px;
	-webkit-animation:passphotos2 1s ease;
	-moz-animation:passphotos2 1s ease;
	animation:passphotos2 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#b4:checked ~ #stage #photos {
	margin-left:-1000px;
	-webkit-animation:passphotos3 1s ease;
	-moz-animation:passphotos3 1s ease;
	animation:passphotos3 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
#b5:checked ~ #stage #photos {
	margin-left:-2000px;
	-webkit-animation:passphotos4 1s ease;
	-moz-animation:passphotos4 1s ease;
	animation:passphotos4 1s ease;
	-webkit-animation-fill-mode: forwards;
	-moz-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}
@-webkit-keyframes passphotos1 {
	100% { margin-left:2000px; }
}
@-moz-keyframes passphotos1 {
	100% { margin-left:2000px; }
}
@keyframes passphotos1 {
	100% { margin-left:2000px; }
}
@-webkit-keyframes passphotos2 {	
	100% { margin-left:1000px; }
}
@-moz-keyframes passphotos2 {	
	100% { margin-left:1000px; }
}
@keyframes passphotos2 {	
	100% { margin-left:1000px; }
}
@-webkit-keyframes passphotos3 {
	100% { margin-left:0px; }
}
@-moz-keyframes passphotos3 {
	100% { margin-left:0px; }
}
@keyframes passphotos3 {
	100% { margin-left:0px; }
}
@-webkit-keyframes passphotos4 {	
	100% { margin-left:-1000px; }
}
@-moz-keyframes passphotos4 {	
	100% { margin-left:-1000px; }
}
@keyframes passphotos4 {	
	100% { margin-left:-1000px; }
}
@-webkit-keyframes passphotos5 {
	100% { margin-left:-2000px; }
}
@-moz-keyframes passphotos5 {
	100% { margin-left:-2000px; }
}
@keyframes passphotos5 {
	100% { margin-left:-2000px; }
}

CSSのポイント説明

・初期画面は、#thumbs に横並びに格納されたサムネイル写真を表示し、大きなサイズ表示用の、台紙・枠(#frame)、写真表示領域(#stage)、横並び写真帯(#photos)、写真など格納DIV(#photo1-photo5)は、所定の位置に配置して非表示にする(opacity:0)。
・表示重ね順は、下層から、サムネイルを含む本文 -> #darkscreen(本文遮蔽スクリーン) -> #frame -> #stage -> #photos -> #photo1-#photo5 で、さらに、#photo1-#photo5 にはそれぞれの表題(.title)とそれぞれの送りボタン領域(cover_left,cover_right)が含まれている。送りボタン領域が最上層となる。
・#frame,#stage などのサイズはサンプルの写真サイズ(幅:1000px)に合わせて設定しているので、使う写真のサイズによって値を変える必要がある。
・サムネイルがクリックされると、#r1 - #r5 のラジオボタンがチェックされたことになり、#darkscreen、#frame、#stage、#photos、#photo1-#photo5 などを一斉に表示させるようにする。
 例えば、#frame の場合は、#r1:checked ~ #frame { opacity:1; z-index:95; }
・サムネイルがクリックされると同時に、そのサムネイルに該当する拡大写真が画面中央の #stage に収まるように photos の位置を定め、transitionを使って、0 だった opacity を 1 にしてフェイド・インさせる。
 例えば、#r1:checked ~ #stage #photos { opacity:1.0; margin-left:2000px; } とすれば、#photos に初期設定された transition: opacity 0.8s ease; の効果があらわれ、フェイドインとなる。
・写真が表示されると、送りボタン領域(cover_left,cover_right)が最上層に来るので、写真右部分のマウスオーバーで右矢印が、左部分のマウスオーバーで左矢印が表示される。
・左右ボタン領域をクリックすると、右ボタンでは右側に位置する写真がスライドインし、表示されていた写真は左にスライドアウトして写真が切り替わる。この動きは、animationを使っている(transitionを使うとサムネイルクリックの動きと区別できない)。
 例えば、一枚目の写真表示時に、右送りボタン領域をクリックした場合、
  #n1:checked ~ #stage #photos {
	margin-left:2000px;
	animation:passphotos2 1s ease;
	animation-fill-mode: forwards;
  }
  @keyframes passphotos2 {	
	100% { margin-left:1000px; }
  }
 とすれば、#photos の margin-left が 1 秒の間に 2000px から 1000px に変わるので、写真が移動して切り替わる。なお、animation-fill-mode: forwards; は、animation が100% の時点で停止し、その状態を保つ。
・閉じるボタン(#close_btn)、#darkscreen は#r6,#r7に関連付けているが、何も役割を与えていないので、そのクリックで自然に初期状態に戻る。

 説明文の中では、-webkit-などのブラウザ対応の記述は省略している。本スクリプト中でも、-o- は省略しているので、気になる方は付け加えてほしい。


コメント

LightBox タイプフォトギャラリー(送りボタン付き) — 8件のコメント

  1. いつも参考にさせていただいております。

    今回は100枚のフォトギャラリー(送りボタン付き)を作成しています。

    /* 写真を横並びに格納する帯状DIV */
    の部分のwidthを100枚分のサイズにしてその他の要素を写真の枚数に合わせたのですが
    5枚目から6枚目にスライドできず止まってしまいます。

    サンプルソースでは3枚目にmargin-left:0px; を設定しておりますが
    100枚の場合はmargin-left:0px;
    を50枚目に設定するような流れでしょうか?

    ご教示いただければ幸いです。

    • 100枚とは壮大ですね。100枚のサムネイルを表示させるんですね。
      さて、#photosのwidthを100枚分にします。もし、1枚のスライドが1000pxなら、100000pxになりますね。そして、1枚目の位置(margin-left)が、-50000pxで50枚目が0となります。これを100枚分記述します。
      この帯を、左右に移動させて、目的のスライドがleft:0となるようにすればいいわけです。
      r,n,bなどの記述も100枚分必要ですし、animationのpassphotoも100通り必要になります。
      大変ですが、丁寧に記述して見て下さい。

  2. 再度質問させていただきます。

    100枚のフォトギャラリーを作成し
    ChromeやMicrosoft Edgeでは表示も左右の送りボタンも正常に実装できました。

    ところがIE(ver.11)では拡大画像が開かない状況で
    おそらく左右の送りボタンもきいていないと思われます。

    -webkit-などブラウザ対応の記述の部分に
    -ms-を追加して試してみたのですが、改善されません。

    ブラウザの互換表示の設定も試してみましたがだめでした。

    その他考えられることはありますでしょうか。
    ご教示いただければ幸いです。

  3. 拡大画像が開かないということは、#photoが正常に認識されていないとか、サムネイルチェックでopacity:1が効いていないとかが考えられますね。
    IeでCssAnimationがうまく動作しないという事例は結構あるみたいですが、ここのDEMOでは正常に動作しますので、maruさんの方で違った記述を加えていないとすれば、なにか、数が多くなると障害が出るということでしょうか。
    Ieに何かバグがあると考えられるます。いくつ以上の数になればうまく動作しなくなるのかなどの疑問は残るのですが、これ以上私にはわかりかねますので、ご了承ください。

    • 98枚に減らすと正常に動作しました。
      IEのバグなのか、なぜ98枚なのか不明のままですが
      ご対応いただきまして、ありがとうございました。

      • 98枚ですか。
        不思議な気がしますね。
        私にもわかりかねますが、一応の成果として、おめでとうございます。

コメントを残す

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