2 次元の HTML5 キャンバスで 3 次元を実現する

パララックス処理の威力

パララックス (視差) 処理は、矢印キーやマウスを使用して Web アプリケーションのグラフィック・レイヤーをアニメーション化するための非常に興味深い手法です。この記事では jQuery と HTML5 を使用してパララックス環境を作成する方法を紹介し、1 つの例をもとに、複数のレイヤーを使用してグラフィックを作成し、アニメーション化する方法を説明します。

Kris Hadlock, Web Developer/Designer, Studio Sedition

Photo of Kris HadlockKris Hadlock は、1996年から契約 Web 開発者および設計者として、SPIN Magazine、IKEA、United Airlines、JP Morgan Chase、Le Cordon Bleu、Canon などの企業のプロジェクトを手掛けてきました。著書には『Query Mobile: Develop and Design』、『Ajax for Web Application Developers』(Sams)、『The ActionScript Migration Guide』(New Riders) があります。また、コラムニストおよびライターとしても、Peachpit.com、InformIT.com、Practical Web Design magazine などの数々の Web サイトや設計関連の雑誌で活躍しています。彼は、フォームと関数の融合を専門とする Web 設計およびソフトウェア開発会社、www.studiosedition.com の創設者でもあります。



2012年 7月 26日

はじめに

HTML5 のキャンバスでパララックス (視差) 処理を行うと、2 次元 (2D) の描画コンテナーで 3 次元 (3D) のスクロール・エフェクトを表示することができます。基本的な考え方としては、複数のレイヤーが異なる速度でスクロールするレイヤー・エフェクトを使用することで、アニメーションが 3 次元に見えるようにします。例えば、複数のレイヤーによって、フォアグラウンド、ミドルグラウンド、バックグラウンドを表現することで、「距離の錯覚」を実現することができます。この目の錯覚は車を運転していると見える景色に似ているはずです。つまり運転者の近くにあるものは速く動き、遠くにあるものはゆっくりと動くように見えます。ビジュアル・エフェクトとして 3 次元のスクロール・エフェクトを実現する方法はいくつかあります。

この記事では、HTML5 のキャンバスを使用して 2 次元の描画コンテナーで 3 次元であるかのような錯覚を作り出す方法について説明します。そのために、複数のグラフィック・レイヤーを作成してそれらを組み合わせ、グラフィックの中に距離の錯覚を作り出します。次に、HTML5、jQuery、JavaScript を組み合わせてパララックス・アニメーションを作成する方法について説明します。

この記事で紹介する例のソース・コードはダウンロードすることができます。


パララックス処理を行うためのグラフィック・レイヤー

この記事で紹介する例では、山と空のグラフィックの前面に四輪駆動車のグラフィックを配置してアニメーション化します。最初のステップは、アニメーションのレイヤーとして使用するグラフィックを作成することです。パララックス処理により、複数のレイヤーが異なる速度でスクロールするレイヤー・エフェクトを実現することができます。ビジュアル・エフェクトを作成する上で、パララックス環境で使用するグラフィックの選択は重要な部分です。奥行があるような錯覚を与え、異なる速度でアニメーションをスクロールできるように、これらのグラフィックを分離し、特定の方法で保存する必要があります。

パララックスのビジュアル・エフェクトのためのグラフィック・セットを作成する場合、以下に挙げるいくつかの点を考慮する必要があります。

  • 作成するレイヤーの奥行を何レイヤーにするか。この記事の例では 3 つのレイヤーを使用します。
  • バックグラウンドを除き、すべてのレイヤーは透明でなければなりません。この記事の例では、空はバックグラウンドの .jpg ファイルであり、山と四輪駆動車は透明な .png ファイルです。
  • 補色的な配色 (コンプリメンタリー配色) のグラフィックと、コントラストの強い (コントラスト配色の) グラフィックを検討し、(速く動かすことで近くにあるように感じられる) 常識的なビジュアル・エフェクト、または (グラフィック・レイヤーが実質的に独立している) 前衛的なビジュアル・エフェクトを作成します。この記事の例では、前衛的ではない、常識的なビジュアル・エフェクトを作成します。
  • グラフィックの境界はシームレスでなければなりません。

バックグラウンド

まず、お好みの画像編集ソフトウェアを開きます。この記事では Adobe Photoshop を使用しました。

最初に空のグラフィックを作成します。このグラフィックはシーンのバックグラウンド・レイヤーに使用されるため、透明である必要はありません。他のレイヤーは、すべて空のグラフィックの前に表示され、その後ろに配置されるものは見えません。空のグラフィックのサイズは幅 800 ピクセル、高さ 300 ピクセルでなければなりません。この大きさであれば、幅 400 ピクセルの最終的な HTML5 キャンバスの中でグラフィックをアニメーション化することができます。この例でバックグラウンドに使用する空のイラストはサイズが 800x300 ピクセルであり、sky.jpg として保存されています (図 1)。

図 1. アニメーション化されるシーンのバックグラウンド・レイヤー
この記事の例で、アニメーション化したシーンのバックグラウンド・レイヤーとして使用する、空のグラフィック

ミドルグラウンド

次に、ミドルグラウンド・レイヤーのグラフィックとして山のイラストを作成する必要があります。山のグラフィックのサイズも幅 800 ピクセル、高さ 300 ピクセルです。ただし、山はグラフィックの一番下に表示されるだけなので、山の上部は透明で、バックグラウンドがそのまま見えます。空のバックグラウンドの上に透明なレイヤーを描画するためには、山のグラフィックを透明な PNG ファイルとして保存します。GIF を使用することはできません。GIF を使用するとアンチエイリアシングによって境界がギザギザになり、滑らかでシームレスな境界にならないからです。図 2 は透明な部分を含む山のグラフィックを Photoshop で表示したものです。Photoshop で表示されるのと同じように、透明な部分のピクセルが表示されているのがわかります。

図 2. 山のグラフィックによるミドル・レイヤー
この記事の例で、アニメーション化したシーンのミドルグラウンド・レイヤーとして使用する、山のグラフィック

フォアグラウンド

最後に、フォアグラウンドのグラフィックを作成します。この例では、アニメーション化したシーンに合うように四輪駆動車を使用します。このグラフィックはこれまでのグラフィックとは少し異なり、バックグラウンドやミドルグラウンドのグラフィックと同じ幅である必要はありません。少しリアルに見えるように、アニメーション化された車のグラフィックとしては、何種類かの異なる状態の車のグラフィックを作成する必要があります。図 3 はこの車の 3 つの状態を示しており、それぞれのグラフィックでホイールとホイールキャップが少しずつ回転しています。

図 3. フロント・レイヤーの四輪駆動車のグラフィック
この記事の例で、アニメーション化したシーンのフロント・レイヤーとして使用する、四輪駆動車のグラフィック

この四輪駆動車のグラフィックは、パララックス・アニメーションに使用する際には、一度に 1 つの車のみが表示されるように切り取られます。皆さんが作成する幅の狭いウィンドウ内では、アニメーションの進行に合わせて x プレーンでグラフィックの位置を変えながら、表示する車のグラフィックも変更します。

これでグラフィックが準備できたので、次のステップではパララックス処理によるエフェクトを作成します。


パララックス処理の関数を作成する

この記事では、パララックス処理によるビジュアル・エフェクトを実現するために、HTML5 と jQuery、そして JavaScript を少し使用します。HTML5 の部分は HTML の <canvas> 要素のみで構成されるため、単純に HTML ページ内にあります (リスト 1)。

リスト 1. <canvas> 要素を使用した HTML5 ファイルの構造
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Parallax Processing</title>
</head>

<body>
<canvas id="parallax-canvas" width="400" height="300">
	Sorry, your browser does not support HTML5 Canvas.
</canvas>

<script type="text/javascript" 
	src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
	</script>
<script type="text/javascript" src="assets/js/parallax-processing.js"></script>

</body>
</html>

リスト 1 には Google の CDN (Content Delivery Network) にある jQuery ライブラリーへの参照が含まれています。また、パララックス処理によるエフェクトを実現するためのカスタム jQuery の作成で使用するparallax-processing.js ファイルへの参照も含まれています。

パララックス処理ファイルの中ではまず、このスクリプト全体で使用されるすべての変数の値を設定する必要があります。

  1. HTML として追加したパララックスの <canvas> 要素の幅と高さを設定します。この 2 つの変数はスクリプトを通じて使用されるため、これらの変数にアクセスするコードを簡潔にするために、名前を wh にします。
  2. この前のセクションで作成したグラフィック・レイヤーへの参照を設定します。JavaScript の Image オブジェクトを使用して各グラフィック・レイヤーを作成します。

それぞれのレイヤーでは、Image オブジェクトを作成したら、Web サーバー上にある画像ファイルへのファイル・パスを参照するように Image オブジェクトの src プロパティーの値を設定します。

Image オブジェクトの準備ができたら、それぞれのオブジェクトを配置してアニメーションを行うために、いくつかの位置を指定する値を設定します。空のグラフィックには 2 つの変数 (skydxskyx) が関連付けられています。skydx はアニメーションの各インターバルの間に空のグラフィックをどの程度移動するか (このあと、説明します) を定義し、skyx は空のグラフィックをどこからスライスするかの規準となる x 座標を定義します。山のグラフィックにも同じ目的の 2 つの変数 (mountainsdxmountainsx) があり、空のグラフィックの変数との唯一の違いは、これらの変数は山のグラフィック専用であることです。

車のグラフィックは少し異なります。このグラフィックには以下の 4 つの変数が関連付けられています。

  • jeepx は x 座標です。この例では x 座標を 100 に設定します。これにより、車は幅 400 ピクセルのキャンバスで中心よりも少しずれた位置に配置されます。
  • jeepy は y 座標です。y 座標は 210 に設定します。これにより、車はキャンバスの一番下に配置されるため、車は山の手前にあるかのように見えます。
  • jeepsx は車の x 座標を設定します。
  • jeepsXWidth は車の各グラフィックの幅に対応した x 座標のオフセットです。
リスト 2. パララックス処理ファイルの中にある JavaScript 変数
var w = $("#parallax-canvas").width();
var h = $("#parallax-canvas").height();

var sky = new Image();
sky.src = "assets/img/sky.jpg";
var skydx = 2;  // Distance to move sky image
var skyx = 0;  // x coord to slice sky image

var mountains = new Image();
mountains.src ="assets/img/mountains.png";
var mountainsdx = 10; // Amount to move mountain image
var mountainsx = 0; // x coord to slice mountain image

var jeep = new Image();
jeep.src ="assets/img/jeep.png";
var jeepx = 100; // x coord of jeep image
var jeepy = 210; // y coord of jeep image
var jeepsx = 0; // x coord to slice jeep image
var jeepsxWidth = 155; // x coord offset for slice jeep width

var cntx =  $("#parallax-canvas")[0].getContext("2d");
setInterval(draw, 10, cntx);

cntx は、HTML5 の <canvas> 要素の getContext メソッドを呼び出した結果を参照する変数です。HTML5 の <canvas> 要素は独自のメソッドやプロパティーを数多く持つオブジェクトであり、ここでは getContext メソッドによって、四角形を JavaScript で描画するために使用する必要があるオブジェクトが返されます。この四角形は、「シーン」の描画ボードとして使用することになります。最後に、10 ミリ秒ごとに (contx 変数を渡して) カスタムの draw 関数が呼び出されるように設定した setInterval の呼び出しを行います。

この例のパララックス処理で setInterval は重要な部分であり、この setInterval を使用して、車、山、空のグラフィックの位置を定期的に更新します。そこにカスタムの draw 関数が登場します。draw 関数は、先ほど参照したコンテキスト・オブジェクトを参照する _cntx を引数に取ります (リスト 3)。この関数で最初に呼び出すのはカスタムの drawRectangle メソッドです。このメソッドは先ほど指定した幅と高さに基づいてキャンバス上に四角形を描画します。

リスト 3. カスタムの draw 関数と drawRectangle 関数
function draw(_cntx) {
	drawRectangle(_cntx, 0, 0, w, h);
	_cntx.drawImage(sky, skyx, 0, 300, 300, 0, 0, w, 300);
	_cntx.drawImage(mountains, mountainsx, 0, 300, 300, 0, 0, w, 300);
	_cntx.drawImage(jeep, jeepsx, 0, jeepsxWidth, 60, jeepx, jeepy, 155, 60);
}

function drawRectangle(_cntx, x, y, w, h) {
	_cntx.beginPath();
	_cntx.rect(x,y,w,h);
	_cntx.closePath();
	_cntx.fill();
	_cntx.stroke();
}

次に、Context オブジェクトの drawImage メソッドを使用して各画像が描画されます。drawImage メソッドは、表 1 で説明されているようにいくつもの引数を取ります。

表 1. drawImage メソッドの引数と、その値および説明
引数説明
img画像、動画、またはキャンバス 描画に使用される画像オブジェクトを表します。
xx 座標描画元の画像の左上の位置を指定する x 座標に対応します。
yy 座標描画元の画像の左上の位置を指定する y 座標に対応します。
width描画元の画像の幅のピクセル数
height高さ描画元の画像の高さのピクセル数
dxx 座標画像の描画先の左上の位置を指定する x 座標に対応します。
dyy 座標画像の描画先の左上の位置を指定する y 座標に対応します。
dwidth画像の描画先の幅のピクセル数
dheight高さ画像の描画先の高さのピクセル数

カスタムの draw 関数を使用して最初にキャンバス上に画像を描画したときの結果は、図 4 のようになります。空がバックグラウンドにあり、山がミドルグラウンドにあり、四輪駆動車がフォアグラウンドにあります。

図 4. パララックス処理に使用する完全なグラフィック・レイヤー・セット
パララックス処理に使用する完全なグラフィック・レイヤー・セット

アニメーション

最後のステップとして、グラフィックのアニメーションを開始してパララックス処理によるビジュアル・エフェクトを作成します。アニメーションを開始する方法はいくつかあります。例えば、グラフィック上でマウスを左方向あるいは右方向に動かした場合や、キーボードの矢印キーを押した場合に動きを生じさせることができます。この例ではキーボードの左矢印と右矢印でアニメーションを開始します。これらの関数を作成するためには、jQuery を使用して keydown イベントを window オブジェクトに適用します。keydown イベントを window オブジェクトに適用することで、この Web ページにフォーカスがあるときはキーの押下が必ずキャプチャーされるようになります。

keydown イベントは event オブジェクトを引数として取り、その引数を使用してユーザーのキーボードでどのキーが押されたかを判断します。そのために、keydown イベントの keyCode プロパティーを確認します。左矢印の keyCode は 37 であり、右矢印の keyCode は 39 です。いずれかのキーが押されると、それぞれの新しい Image オブジェクトに対し、変数の初期設定値を基に計算を使用して空、山、車に関連する変数を同時に更新します (リスト 4)。これらの計算によって変数を更新すると、その結果として最終的に各グラフィック・レイヤーが異なる速度でアニメーション化されます。

リスト 4. keydown イベントによってグラフィック・レイヤーの位置を計算する
$(window).keydown(function(evt) {
	switch (evt.keyCode) {
		case 37: // Left arrow
			if ((skyx + skydx) > skydx)
			  skyx -= skydx;
			else
			  skyx = w;
			
			if ((mountainsx + mountainsdx) > mountainsdx)
			  mountainsx -= mountainsdx;
			else
			  mountainsx = 398;
			
			if (jeepsx > 0) 
				jeepsx -= jeepsxWidth;
			else 
				jeepsx = (jeepsxWidth*2);
		
		break;
		
		case 39: // Right arrow
			if ((skyx + skydx) < (w - skydx))
			  skyx += skydx;
			else
			  skyx = 0;
			
			if ((mountainsx + mountainsdx) < (w - mountainsdx))
			  mountainsx += mountainsdx;
			else
			  mountainsx = 0;
			
			if (jeepsx < (jeepsxWidth*2))
			   jeepsx += jeepsxWidth;
			else
			   jeepsx = 0;
			
			break;
	}
});

グラフィックの動きが実際に発生するのはカスタムの draw 関数の中ですが、keydown イベントが発生すると、ユーザーの意図に基づいて変数の値がすべて更新されます。更新された値を draw 関数と組み合わせることで真のパララックス処理によるエフェクトが生まれ、その結果、奥行のあるリアルな動きを実現することができます。完成したら、すべてのスクリプトをドキュメントの ready イベントの中にまとめることが重要です。そうすることで、そのドキュメントが確実に使用可能な状態になり、HTML 要素の操作を試さなくても、確実にすべての HTML 要素を操作できるようになります。


まとめ

パララックス・アニメーションを作成する方法に制限はなく、結局は皆さんの創造力次第です。例えば、この記事で紹介した水平方向の動きがあるアニメーションと同様に垂直方向の動きがあるアニメーションを作成することもでき、そのアニメーションを、マウスの動き、ブラウザーのスクロール、またはキーボードのキー押下に基づいて動作させることができます。「参考文献」セクションには、さまざまな手法やウィジェットを使用して容易にパララックス処理を行う他の例を挙げてあります。


ダウンロード

内容ファイル名サイズ
Create a parallax environment with HTML5 Canvasparallax-processing.zip4KB

参考文献

学ぶために

製品や技術を入手するために

  • IBM 製品の評価版: IBM 製品の評価版をダウンロードするか、IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、WebSphere などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Web development
ArticleID=826728
ArticleTitle=2 次元の HTML5 キャンバスで 3 次元を実現する
publish-date=07262012