WebTecNote

[MooTools Tutorial]巨大な背景画像の読み込みとMoreの使い方

MooToolsには豊富な機能拡張クラス(プラグイン)があります。
公式サイトでは基本クラス群をCore、機能拡張クラス群をMoreと称してあるのでそのように覚えておくと良いと思います。
Moreクラスはコアに実装されていない機能を個別に提供するもので、
どれもCoreのクラスに依存しているのでCoreとセットでないと動きません。

Moreの公式サイトでの配布は約60種類、MooTorialに約70種類くらいあります。
大体のことは網羅されているので、そのまま活用するもよし、組み合わせて新しいプラグインを作るもよしです。

このエントリーはそんな便利なMoreクラスの使い方を説明しつつ、
Flashでやってしまいがちな横幅1000pxを越える大きな背景画像の読み込みを、MoreのAssetsクラスを使って行うチュートリアルです。
前編後編で分けていますがタイトルが違うのでご注意を。こちらは前編です。

前編:ページ開く→ローディング画像表示と背景画像を1枚読み込み→読み込み完了で背景表示

後編:画像3枚読み込み→クロスフェードでエンドレス切替

ということをやってます。後編はこちら »

Moreクラスの使い方

Step3まで前のチュートリアルとダブりますが、このエントリーから見る方も居ると思うので一応最初から説明します。
今回のスクリプトを利用するのにダウンロードが必要なのはダウンロードページのトップにあるMooTools 1.2.4のファイルとMoreのAssetsクラスです。

まずCoreですが、

ダウンロードするとmootools-1.2.4-core.jsみたいに、バージョンの後ろにcoreと入ったファイル名になるので、
txtの拡張子を削除して拡張子を.jsにしといてください。

次にMoreのAssetsクラス。

More Builderに移動し、Utilitiesの一番上にあるAssetsにチェックを入れてダウンロードします。
Moreの場合もバージョンの後ろにmoreと入ったファイル名になるので、
分かりやすく変更したりCoreのファイルにコピペしたりしてください。

Step1:画面を作る

画面を適当に作ります。
背景は後でdiv要素を作ってbody閉じタグ直前に挿入するので、
コンテンツを入れた要素をposition:relativeなどでz-indexを1以上に指定してください。
さらに、全画面表示をするためbodyとhtmlにはheight:100%とmin-height:100%が必要。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" dir="ltr">
<head profile="http://purl.org/net/ns/metaprof">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="ja" />
<title>WTN*MooTools Assets Image Loading DEMO</title>
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="Imagetoolbar" content="no" />
<meta content="Tenderfeel" name="author" />
<link href="mailto:tenderfeel@gmail.com" rev="made" />
<link rel="index" href="https://tenderfeel.xsrv.jp/" />
<link href="http://yui.yahooapis.com/2.8.0r4/build/reset/reset-min.css" type="text/css" rel="stylesheet" />
<style type="text/css">
<!--
	html,body { height:100%;min-height:100%;background-color:#000; color:#666; font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;}
	#container {position:relative;z-index:1}
	h1 { padding:50px 0 0 50px;}
	li { margin:0 0 10px 0;}
	a { color:#fff; font-size:200%;text-decoration:none;}
	a:hover { color:#80ffff;}
	#footer {overflow:hidden;_zoom:1;position:absolute;bottom:5px;left:0;width:100%;text-align:center;z-index:1}
	#footer li {display:inline;margin-left:-1px;padding:0 5px;border-left:solid 1px;font-size:77%;line-height:1}
	#footer li:first-child {border:0;}
-->
</style>
</head>
<body id="home">
	<div id="container">
	<h1>MooTools Assets Image Loading DEMO</h1>
	</div>
	<ul id="footer">
		<li>powered by MooTools</li><li>copyright © Tenderfeel all rights reserved.</li>
	</ul>
</body>
</html>

IE6みたいな古い子のことは先生知りません。

Step2:MooToolsのCoreとMoreを読み込む

head内にスクリプトタグを入れるだけです。

<script type="text/javascript" src="mootools-1.2.4-core.js"></script>
<script type="text/javascript" src="mootools-Assets.js"></script>

入れる場所はbodyの閉じタグ直前とかでもいいんですが、これから書くソースより前に読み込まれてないとエラーになります。

Step3:addEventでdomreadyする

type=javascriptなscriptタグを新しく追加し、イベントを実行するためのスターターを書きます。

<script type="text/javascript">
//<!&#91;CDATA&#91;
window.addEvent("domready",function(){

});
//&#93;&#93;>
</script>

windowオブジェクトにdomreadyイベントを追加→DOMが読み込まれたら引数の関数を実行 っていうソースなんですが、
MooToolsでページを読み込まれた時に何かするときはほぼ100%の確率でこの書式を使います。

Step4:背景画像のパスとbodyタグを変数に保存する

後で複数回登場する設定や要素はあらかじめ変数に入れておきます。

MooToolsのドル関数はひとつだとID指定でしか要素が取得出来ませんが、
ふたつだとタグ名やクラス名、CSSセレクタなどで取得する事が出来ます。
複数の要素を得られる可能性があるので、要素を得られた場合の戻り値は必ず配列になります。
何も得られなかった場合はnullが戻されます。

window.addEvent("domready",function(){

	var ImageSrc = "bg_body.jpg";//背景画像のパス
	var container = $$("body")[0];//bodyタグ

});

bodyタグは1つしかないので先頭のキー[0]を指定。

Step5:ローディング画像を表示する

別途ローディング画像の要素をMoreのSpinnerクラスで作って挿入するという手もあるんですが、
手っ取り早いのは背景に指定してしまうことです。
Step1で要素を変数に保存しているので、setStyleメソッドを使って背景にローディング画像を設定します。

window.addEvent("domready",function(){
									
	var ImageSrc = "bg_body.jpg";
	var container = $("home");

	container.setStyle("background","url(ajax-loader.gif) no-repeat center center");
	
});

ローディング画像が表示されていたら次のステップへ。

Step6:Assetsクラスを使用して画像を読み込む

Assetsは利用するメソッドによりImageの他にJavaScriptとCSSも読み込めます。
返り値はそれぞれ、Imageはimgタグ、Javascriptはscriptタグ、CSSはlinkタグで
どのメソッドにもonload(Imagesの場合のみonComplete)イベントがあるので、読み込み完了後に何かを実行する事が可能です。

前編では画像を1枚だけ読み込むので、imageメソッドを利用します。
書式はこうです↓

var myImage = new Asset.image(source[, properties]);

//source(string):画像までのパス
//properties(object):imgタグに付与する属性やイベント(onload/onerror/onabort)

今回はデモなので、読み込みに失敗したときはonerrorでアラートを表示させます。
onloadイベントは次のステップで書くのでとりあえず空けておいてください。
実際のサイトで利用する場合は別の背景をsetStyleするとかで良いと思います。

window.addEvent("domready",function(){
									
	var ImageSrc = "bg_body.jpg";
	var container = $("home");

	container.setStyle("background","url(ajax-loader.gif) no-repeat center center");
	
	//Class Assets
	new Asset.image(ImageSrc,{
		onload: function(el){
			//console.log(el); //FireBug確認用
		},
		onerror:function(){
			alert("イメージの読み込みに失敗しました");
		}
	});
});

onloadの引数elには読み込み完了した画像のIMGタグが格納されます。

Step7:読み込まれた画像を元に背景要素を作る

Asset.imageのonloadイベント内で、まず背景用のdiv要素を作ります。
MooToolsで要素を作る場合はElementクラスを使用し、基本的な書式は次のようになります。

var myElement = new Element(tag[, option]);

//tag(string):HTMLのタグ名
//option(object):タグに指定する属性やスタイル、イベント、Fxなどいろいろ

実際見てみた方が早いと思うので作ってみます。
背景用のdiv要素につける属性はIDとstyleになりますが、
要素に設定するCSSはオプションで設定しておきます。
背景画像のURLは戻り値elのsrcプロパティの値を使用します。

onload: function(el){
	
	var bg = new Element("div",{ "id":"bg_body",
		styles:{
			"height":"100%",
			"min-height":"100%",
			"width":"100%",
			"background":"url("+el.src+") no-repeat center center",
			"position":"absolute",
			"top":0,
			"left":0,
			"z-index":0
			}
		});
	
	container.setStyle("background","none");//ローディング画像を消す
},

要素を作ったら背景に指定してるローディング画像を消します。

それから、作った背景要素をbodyタグの一番下にinjectメソッドで挿入します。
injectメソッドは次のような書式なのですが、

挿入する要素.inject(挿入先の要素[,位置]);

通常は指定した要素の内側の一番上に挿入されますが、第二引数で位置を指定すると
挿入先に指定した要素を基準として位置を変更することが出来ます。

今回はbody閉じタグ前に入れるので、ElementクラスのgetLast()メソッドで
bodyタグの一番最後にある要素を取得して基準にし、第二引数に”after”を設定しました。

onComplete: function(el){
	
	var bg = new Element("div",{"id":"bg_body",
		styles:{
			"height":"100%",
			"min-height":"100%",
			"width":"100%",
			"background":"url("+el.src+") no-repeat center center",
			"position":"absolute",
			"top":0,
			"left":0,
			"z-index":0
			}
		});

	container.setStyle("background","none");//ローディング画像を消す

	bg.inject(container.getLast(),"after");//背景要素を入れる
	
},

Step8:作った背景要素をフェードインさせる

Step7で作った背景要素をフェードインさせれば完成です。
フェードは透明度切替だけでいいのでFx.Tweenを使用します。
Fx.Tweenについての詳細はリファレンス和訳版)を見てください。

Fx.Tweenの場合には、操作するプロパティが1つだけなのであらかじめoptionのオブジェクト内で
操作するプロパティの名前を”property”で指定しておくことができますが、
空にしたままstartやsetの第1引数で設定する事も出来ます。

なお、使用頻度の高い透明度の操作だけならfadeメソッドを利用して次のように書くことも出来ます。

element.fade("in");//フェードイン
element.fade("out");//フェードアウト

fadeメソッドはオプションがないので、トランジションや遅延を設定することが出来ません。
オプションをデフォルトから変更したいという場合はnewした方がスマートです。
今回はフェードインさせるときの遅延をゆっくりさせたかったので、durationを2000に設定しています。

背景要素を追加した後に、透明度を操作するFx.Tweenのインスタンスを作成しsetで0(透明)にします。
その後、startさせて透明度を1(不透明)にします。

onComplete: function(el){
	
	var bg = new Element("div",{"id":"bg_body",
		styles:{
			"height":"100%",
			"min-height":"100%",
			"width":"100%",
			"background":"url("+el.src+") no-repeat center center",
			"position":"absolute",
			"top":0,
			"left":0,
			"z-index":0
			}
		});

	container.setStyle("background","none");//ローディング画像を消す

	bg.inject(container.getLast(),"after");//背景要素を入れる
	
	var fx = new Fx.Tween(bg,{duration:2000,property:"opacity"}).set(0);//Fxインスタンス

	fx.start(1);//フェードイン実行
},

以上で前編は完成です。ソース全文は次のようになりました。

window.addEvent("domready",function(){
									
	var ImageSrc = "bg_body.jpg";
	var container = $$("body")[0];
	
	container.setStyle("background","url(ajax-loader.gif) no-repeat center center");
	var fx = bg = null;
	
	//Class Assets
	new Asset.image(ImageSrc,{
		onload: function(){
			
			var bg = new Element("div",{"id":"bg_body",
				styles:{
					"height":"100%",
					"min-height":"100%",
					"width":"100%",
					"background":"url("+ImageSrc+") no-repeat center center",
					"position":"absolute",
					"top":0,
					"left":0,
					"z-index":0
					}
				})
			container.setStyle("background","none");
			
			bg.inject(container.getLast(),"after");
			
			var fx = new Fx.Tween(bg,{duration:2000,property:"opacity"}).set(0);
			
			fx.start(1);
			
		},
		onerror:function(){
			alert("イメージの読み込みに失敗しました");
		}
	});
	
});

jQueryに比べると冗長なソースだけど、慣れてくると読みやすくなって来るんだなあこれが。
後編ではこれを応用して画像3枚をクロスフェードさせます。

Coreドキュメントの和訳は高橋文樹さんがやってます!GJ!

モバイルバージョンを終了