ブラウザの幅全体をメイングラフィックにするスライドショーを作成する【jQuery連載11】

前回は、クリックで開閉するスライドメニューを作成しましたが、今回はメイングラフィックスペースをグラフィカルにするスライダーを作成します。

ページ上部のメイングラフィックスペースに複数の情報を表示させるようにするスライドショーを作成する。今回は、メインの画像が中央に、その両側には前後のグラフィック画像に黒い半透明の画像が被さった状態で表示されるスライダーを作成します。
前後の画像が両側に表示されるため、ウィンドウサイズが変わっても横幅いっぱいに画像が表示され、よりグラフィカルなイメージを与えることができます。

今回作成したサンプル

【サンプル】ブラウザ一杯に広がったメイングラフィックに最適なスライドショーを作成する
http://www.html5-memo.com/sample/jq-books/08

スライドショーのHTML

ヘッダーエリアの上にスライドショーを設置するが、レイアウトによってはヘッダーの下など場所は自由に設定することができる。画像はli要素を使用して配置し、左右への移動ボタンをその下に配置させボタンでのスライドの移動と一定時間でアニメーションさせる昨日を追加させる。今回スライドさせる画像の幅と高さについてはモバイル対応させることを想定しサイズの記述はしていない。

<div id="slider">
<ul class="clearfix">
<li><a href="#"><img src="img/01.jpg" alt=""></a></li>
<li><a href="#"><img src="img/02.jpg" alt=""></a></li>
<li><a href="#"><img src="img/03.jpg" alt=""></a></li>
<li><a href="#"><img src="img/04.jpg" alt=""></a></li>
<li><a href="#"><img src="img/05.jpg" alt=""></a></li>
<li><a href="#"><img src="img/06.jpg" alt=""></a></li>
</ul>
<p id="prev"><img src="img/prev.png" alt="" width="64" height="64" class="rollover"></p>
<p id="next"><img src="img/next.png" alt="" width="64" height="64" class="rollover"></p>
</div>

CSSでの配置

スタイルシートにて画像を横に並べて配置してさせる。また中央に表示させる画像以外も同じ感じで表示させると主題が目立たなくなるので半透明のドット側の画像を左右のエリアに配置させることによって中央のグラフィックを目立たせつつも左右にもグラフィックイメージとしてインパクトのあるスライダーができあがる。

#slider{
	position: relative;
	width:100%;
	height: 480px;
	overflow: hidden;
	background: url(../img/loading.gif) no-repeat center center;
}
#slider ul{
	position: absolute;
	top: 0;
	left: 0;
}
#slider li{
	float: left;
}
#slider li img {
  width: 900px;
  height: auto;
}
#slider #prev,
#slider #next{
	position: absolute;
	top:220px;
	cursor: pointer;
}
#slider #prev{ left:20px;}
#slider #next{ right:20px;}

/* for script */
#slider ul,
#slider #next,
#slider #prev{
	visibility: hidden;
}
#slider .layer{
	width: 900px;
	height: 480px;
	position: absolute;
	top: 0;
	left: 0;
	background: url(../img/dot.gif) repeat 0 0 #666;
	opacity: 0.5;
	filter: alpha(opacity=50);
}


メイングラフィックの左右には半透明のグレーのドット柄を配置させメインを目立たせている。

スライダーを実装する

スライダーの作成によくある機能をまとめてみると、一定時間でのアニメーション移動、ボタンでの移動、1枚辺りの表示時間の設定などを考える必要があります。

また最後の枚数になった際の挙動としては、最後にしたら一枚目が表示させるようにするが、この際に再生方向とは逆の方向に一気に先頭に戻ってしまうやり方と、一定方向でループさせるやり方があります。今回は後者のほうで作成してみる。

メイングラフィックの左右には半透明のグレーのドット柄を配置させメインを目立たせている。

オプション管理やDOMや数値の変数

var options = {
	duration: 400,
	easing: 'easeOutCubic',
	auto: true,
	interval: 3000
};

オプションを管理する変数を用意します。
スライドの速度・イージング、自動スライドの有無・インターバルを簡単に変更出来るよう、スクリプトの最初で変数を定義します。

var $window = $(window),
	$container = $('#slider'),
	$element = $container.find('ul'),
	$list = $element.find('li'),
	$next = $container.find('#next'),
	$prev = $container.find('#prev'),
	shift = 2,
	lw = $list.find('img').width(),
	lh = $list.find('img').height(),
	len = $list.length,
	timer = '',
isNarrowScreen = (function(){
  return $(window).width()<767;
})();
&#91;/javascript&#93;

DOMや数値などを変数に入れ、キャッシュさせます。

<h2>スライダー内の画像を読み込んでいる間、ローダー画像を表示</h2>

スライダーに必要な画像がすべて読み込み終わるまでは、CSSでスライダーの背景に設定したローダー画像が表示される。このように処理すれば、この領域に何かを表示するために読み込み中であることをユーザーに伝える事ができる。

[css font_size="90%"]
#slider{
	position: relative;
	width:100%;
	height: 480px;
	overflow: hidden;
	background: url(../img/loading.gif) no-repeat center center;
}
[/css]

[javascript font_size="90%"]
function load(){
	var array = [$element, $next, $prev];
	for(var i = 0; i < array.length; i++) array&#91;i&#93;.css('visibility', 'visible');
	$container.css('background', 'none');
};
&#91;/javascript&#93;

<h2>関数の実行</h2>

windowのロードが完了された時に実行する関数を設定します。

[javascript font_size="90%"]
function initialize(){
	setup();
	rollover();
	$window.on('resize', resize);
	$next.on('click', function(){ slide(true); });
	$prev.on('click', function(){ slide(false); });
	load();
	if(options.auto) timer = setInterval(function(){ slide(true) }, options.interval);
}; 

スライダー画像の設定

次に、HTMLの操作を行っていきます。
li要素の先頭が、スライダー中央に来るようにli要素を並び替えます。
またスマートフォンなどで幅が狭い場合は左右のフェードスクリーンを配置しないようにする。

function setup(){
for(var i = shift; i > 0; i--) $element.find('li').eq(len-1).remove().prependTo($element)

if(!isNarrowScreen){
  for(var i = 0; i < 2; i++) $('<div class="layer"></div>').insertAfter($element);
  $leftlayer = $container.find('.layer').eq(0);
  $rightlayer = $container.find('.layer').eq(1);
} else {
  $container.height(lh);
}
resize();
}; 

画像を中央に配置

次に画像を中央に配置するための関数を作成します。ウィンドウの幅からli要素の幅を引いて半分にした値を、ulに設定すれば中央に表示されます。

ただし、そのままではulの左側に空白が出来てしまいますので、先ほどの値からli要素2つ分の幅を引きます。
※この時、li要素2つ分の幅を引いているため、「HTMLの操作」の際にli要素を2回並べ替えています。

function resize(){
	var _val = ($window.width() - lw) / 2 - lw * shift;

$element.css({
		'width': lw * len,
		'left': _val
	});

if(!isNarrowScreen){
  $leftlayer.css('left', _val + lw);
  $rightlayer.css('left', _val + lw * 3);
} else {
  $container.height(lh);
  $list.css({
  'width': lw,
  'height': lh
  });
}
}; 

アニメーションの仕組みを作成

アニメーションを管理する関数を作成します。
この関数では、自動スライドの停止・アニメーション・コールバック関数の呼び出しを行っています。この際、引数に入れた値によって右に動くか左に動くかを調整できるようにすることで、一つの関数で左右の動きを管理します。

function slide(direction){
	if($element.filter(':animated').length) return;
	if(options.auto) clearInterval(timer);
	val = (direction)? -lw: lw;
	$element.animate({
		'marginLeft': val
	}, options.duration, options.easing, callback);
};

先ほどの関数から呼び出されたコールバック関数では、先ほどの関数で動かしたmargin-leftをリセットするとともに、一番端のli要素を逆端に回りこませてループを行っています。その後自動スライドの再開を行っています。

function callback(){
	(0 > val)? $element.find('li').eq(0).remove().appendTo($element): $element.find('li').eq(len - 1).remove().prependTo($element);
	$element.css('marginLeft', 0);
	if(options.auto) timer = setInterval(function(){ slide(true) }, options.interval);
};

今回は以上になります。

次回はmasonryでコンテンツを隙間なく敷き詰め表示方法をいろいろ作成したいと思います。

この記事を書いた人

著者 : ハヤシユタカ

2001年、有限会社ムーニーワークスを設立。WEB制作の他、書籍執筆、セミナー講演、企業研修などを行う。また、クリエイター育成機関デジタルハリウッドでは1999年より講師として本科WEBデザイナーコースやデジタルデザインコースを担当。 詳しいプロフィールはこちら

最近書いた記事

この記事に関連する記事