画像の準備をしよう
ギャラリーページなので当然のことながら画像は準備しておきましょう。
小さい画像(サムネイル)と大きい画像を用意します。
小さい画像は100×67、大きい画像は画面いっぱいに表示するのでそこそこ大きいのにします。
画像サイズが変わっても基本的にcssを修正するだけで済むようにします。
html + cssを作成しよう
連番画像をjQueryで配置しても良かったのですが、今回はjavascriptOFFの環境にもやさしい親切設計でいきます。
サムネイルはidを「photo」としてリストでマークアップします。
「view」は大きな画像を表示するところです、とりあえず最初に表示される画像を入れておきます。
html
<div id="photo"> <ul> <li><a href="01b.jpg"><img src="01s.jpg" width="100" height="67" /></a></li> <li><a href="02b.jpg"><img src="02s.jpg" width="100" height="67" /></a></li> <li><a href="03b.jpg"><img src="03s.jpg" width="100" height="67" /></a></li> <li><a href="04b.jpg"><img src="04s.jpg" width="100" height="67" /></a></li> <li><a href="05b.jpg"><img src="05s.jpg" width="100" height="67" /></a></li> ・ ・ ・ </ul> </div> <div id="view"><img src="01b.jpg" width="1000" height="666" /></div>
cssは無駄なところが多いかもしれませんがこんな感じです。
css
*{ margin:0; padding:0; border:0; } html { overflow: hidden; } body { background: #666666; } #photo { width: 100%; height: 67px; padding: 10px; background: #000000; z-index: 1; position: absolute; overflow: hidden; } #photo ul li { float: left; list-style: none; margin-right: 10px; } #photo ul li img { vertical-align: bottom; } #view img { position:fixed; left: 0px; top: 0px; z-index: -1; }
サムネイルのdivである「#photo」に「z-index: 1」、大きい画像の「#view img」を「z-index: -1」に設定することで、サムネイルを常に前面に表示させます。
ちょっとめんどくさいのですが「#photo 」の「height」も指定しておいてください。
また、サンプルではサムネイルは下部に配置してありますが、この状態だと上部になります。
この辺りはcssでがんばるよりかはjQueryでやった方が簡単にできそうです。
大きい画像を全画面表示する
全画面表示は過去記事の「jQueryで背景画像を全画面表示する」を参考にしてください。
他のメソッドで共通の変数を使用するので一部違うところがありますが、基本は同じです。
「#view」の中になる画像を全画面表示するには次のようします。
js
$(function() { //ウィンドウサイズ var winW = 0; var winH = 0; //画像サイズ取得 var imgW = $('#view img').width(); var imgH = $('#view img').height(); fitImageSize(); //リサイズしたら実行 $(window).resize(function(){ fitImageSize(); }); //画像をウィンドウに合わせる function fitImageSize() { winW = $(window).width(); winH = $(window).height(); var scaleW = winW / imgW; var scaleH = winH / imgH; var fixScale = Math.max(scaleW, scaleH); var setW = imgW * fixScale; var setH = imgH * fixScale; var moveX = Math.floor((winW - setW) / 2); var moveY = Math.floor((winH - setH) / 2); $('#view img').css({ 'width': setW, 'height': setH, 'left' : moveX, 'top' : moveY }); } });
サムネイルを下部に配置する
今はサムネイルが上部に配置されていて、画像の合計サイズがウィンドウの幅より多いと折り返して何段かになって表示されていますので、これを折り返さないようにして下部に表示します。
javascript
var _thumWidth = 0; //サムネイル画像サイズ $('#photo') //サムネイルを画面下に配置 .css('top', winH - $('#photo').outerHeight()) //サムネイル全てのWidthを取得 .find('ul li').each(function(){ _thumWidth += $(this).outerWidth(true); }) .end() //サムネイルの全体のwidthをliの合計にする .find('ul').css('width', _thumWidth);
まじで何が言いたいのかわらない図になってますね。
ようは「ウィンドウ縦(winH)」-「サムネイルdivの縦(outerHeight)」でサムネイルを配置する縦の位置がわかるじゃないですか。
あとサムネイルのリストの数だけ横のサイズ(outerWidth)を足してそれをulのwidthにすれば、liの合計=ulのwidthにすることで画像が折り返さなくなります。
outerWidth()は引数にtrueを入れることでmarginも含むサイズになります。
下部に配置するコード部分「.css(‘top’, winH – $(‘#photo’).outerHeight())」は画面サイズが変更された場合、再配置する必要があるので、前述の「resize」イベントに追記しておきましょう。
javascript
$(window).resize(function(){ fitImageSize(); //サムネイルを画面下に配置 $('#photo').css('top', winH - $('#photo').outerHeight()); });
サムネイルクリックで大きな画像を切り替える
サムネイルをクリックして大きな画像(#view)が切り替わるようにしてみましょう。
javascript
$('#photo a').click(function(e) { //aリンクの動作を停止 e.preventDefault(); //次の画像URLを取得 var nextImg = $(this).attr('href'); $('#view') .empty() //子要素(現在の画像)の削除 .hide() //非表示 .append('<img src="'+nextImg+'" />') //新しい画像を配置 .fadeIn(); //フェードインで表示 //画像を画面サイズに合わせる imgW = $('#view img').width(); imgH = $('#view img').height(); fitImageSize(); });
この辺はコメントのを見て頂ければわかると思います。
新たに配置した画像は実寸ですので、最後にまたサイズを取得して再配置する必要があります。
マウスカーソルに合わせてサムネイルをスライドさせる
ここまでで基本的な動作をするフル画面ギャラリーになっていると思いますが、最後にマウスカーソルに合わせてサムネイルをスライドさせるという無駄でちょっと重いかもしれない機能を追加してみます。
基本動作として次ぎのようなことを行います。
- マウスが画面中心より左に位置していたら、サムネイルは右に移動して、マウスが右なら左に移動します。
- 移動速度は中心ほど遅く、画面端ほど速く移動します。
- 端の画像が表示されると、サムネイルの移動は停止してそれ以上は進まなくなります。
新たにグローバルな位置に次の変数を追加します。
javascript
//アニメーションスピード var _dx = 110; //画像の初期位置 var _posX = 0; //マウスの位置 var _mouseX = 0; //画面中央 var _winCenter = winW / 2; //移動方向 var _xvec = -0.15;
基本的にコメントの通りですが、またすごくわかりにくい図を描いてみました。
画面中央はウィンドウサイズが変われば当然変化しますので、前述のresizeメソッドにも追加しましょう。
javascript
$(window).resize(function(){ ... _winCenter = winW / 2; });
マウスの位置を取得する
マウスの位置を取得して、サムネイルの移動方向や速度の計算をします。
サムネイル上にマウスカーソルが来たときに動作する仕様ですので、前述の「$(‘#photo’)」にメソッドチェーンで「mousemove」イベントを追加します。
javascript
.end() .mousemove(function(e) { //マウスのX座標取得 _mouseX = e.pageX; //マウスがステージの中心より左だったらマイナス、右だったらプラス _xvec = (_winCenter - _mouseX) / _dx; });
「_winCenter(画面中央) – _mouseX(マウスのX座標)」で画面中心よりマウスは右にあればマイナスになり、左だったらプラスになります。
これで移動方向が決まりますね。
このままの数値では高すぎるので「_dx」で割ります。この数値を変更すればスピードの制御ができます。
アニメーション処理
取得した数値をもとにサムネイルを移動させます。
setIntervalは一定間隔ごとに処理を実行するメソッドです。
たとえばこのメソッドの中に「x += 2」と入れれば「2, 4, 6, 8, ……」と増えていき、この値を「margin」なんかに割り当てればあたかもアニメーションして移動しているようになるわけです。
で、この「2」の部分に実際何が入るかというと先ほど、速度やら移動方向を計算した「_xvec」ですね。
javascript
setInterval(function(){ //左方向に移動しているときは一番右の画像が見えたら止まる if (_xvec < 0) { if(_posX > (winW - _thumWidth) - 10 ) { $('#photo ul').css("margin-left",_posX+"px"); _posX += _xvec; } } //右方向に移動しているときは一番左の画像が見えたら止まる else { if(_posX < 0 ) { $('#photo ul').css("margin-left",_posX+"px"); _posX += _xvec; } } }, 1);
「_xvec」が0よりも小さい、つまり左方向に移動しているときは「_posX」(サムネイルの位置)が右端(winW – _thumWidth) – 10 )にくるまで移動します。
「else」(右方向に移動しているときは)場合はサムネイルの位置が0になるまで移動します。
ここに数値を書いてしまうのはあまりよくないと思うのですが「10」というのは「#photo」のpaddingです。
最終的なソースです。
ソースコード