※この記事は「古籏一浩のJavaScriptラボ」の第36回です。過去の記事も合わせてご覧ください。
HTML5サウンドプレイヤーのサンプル。マウスで選択した曲(音声ファイル)を再生し、ラインアートを表示する。画像クリックでサンプルページを表示します(Firefox 3/Opera 10/Safari 4で表示可能) |
HTML5 Audioを使ってブラウザー上で動くサウンドプレイヤーを作る記事の続き。前回は、再生リストから選択した音楽(音声ファイル)を再生する基本機能を作りました。このままでも十分と言えば十分ですが、今回はビジュアルエフェクトと操作ボタンを追加して、より充実した機能のプレイヤーに仕上げていきます。
ビジュアルエフェクトを追加する
まずビジュアルエフェクトを追加します。今回は、サウンドプレイヤーの背景いっぱいにcanvas要素を配置し、canvas上にランダムな色の線を描画していくラインアートのプログラムを用意しました。
HTML5 Canvasの基本的な使い方については本連載でもこれまでに取り上げているので解説は省略しますが(関連記事1、関連記事2)、背景にCanvasを表示する場合には、以下のようにwidthとheightに100%の値を設定しても反映されない問題があります。
<canvas id="myCanvas" width="100%" height="100%"></canvas>
そこで、ページが読み込まれた後、スクリプト側でブラウザーのウィンドウサイズを取得し、Canvasのwidthプロパティとheightプロパティに設定します。ウィンドウサイズはWindowオブジェクトのinnerWidth、innerHeightプロパティで取得できます。取得した値を以下のようにCanvasに設定するとウィンドウいっぱいに表示できます。
var canvasObj = document.getElementById('myCanvas');
var conObj = canvasObj.getContext('2d');
canvasObj.width = window.innerWidth;
canvasObj.height = window.innerHeight;
ただし、このままだと画面いっぱいに表示されているCanvasの影響で、プレイリストがクリックできない場合があります。そこで、プレイリストやコントローラのCSSにposition:relativeを設定し、z-indexを指定してCanvasによるビジュアルエフェクトをプレイヤーの背景に表示します。
実際のスクリプトがサンプル09です。曲名をクリックすると音楽とともにラインアートのビジュアルが始まります。
●サンプル09[HTML]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>オリジナルサウンドプレイヤー</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="all">
</head>
<body>
<div id="playListArea"></div>
<div id="controller">
<img src="images/on.png" id="playButton">
<div id="ctime">0:00</div>
</div>
<div id="wrapper"><canvas id="myCanvas"></canvas></div>
<script type="text/javascript" src="js/control.js"></script>
<script type="text/javascript" src="js/visual.js"></script>
</body>
</html>
●サンプル09[JavaScript:visula.js] ※control.jsはサンプル08と同じ
(function(){
var canvasObj = document.getElementById('myCanvas');
var conObj = canvasObj.getContext('2d');
canvasObj.width = window.innerWidth;
canvasObj.height = window.innerHeight;
var x1 = 0;
var y1 = 0;
var x2 = Math.floor(Math.random() * canvasObj.width);
var y2 = Math.floor(Math.random() * canvasObj.height);
var dx1 = (Math.random() * 4 - 2) * 10;
var dy1 = (Math.random() * 4 - 2) * 10;
var dx2 = (Math.random() * 4 - 2) * 10;
var dy2 = (Math.random() * 4 - 2) * 10;
conObj.fillStyle = "rgba(0,0,0,1)";
conObj.rect(0,0,canvasObj.width,canvasObj.height);
conObj.fill();
setInterval(function(){
if (!playFlag) return; // 再生していない時は処理しない
var R = Math.floor(Math.random() * 255);
var G = Math.floor(Math.random() * 255);
var B = Math.floor(Math.random() * 255);
conObj.strokeStyle = 'rgba('+R+','+G+','+B+',0.5)';
conObj.lineWidth = 2;
conObj.beginPath();
conObj.moveTo(x1,y1);
conObj.lineTo(x2,y2);
conObj.closePath();
conObj.stroke();
x1 = x1 + dx1;
y1 = y1 + dy1;
x2 = x2 + dx2;
y2 = y2 + dy2;
if ((x1 < 0) || (x1 > canvasObj.width)) { dx1 = -dx1; }
if ((y1 < 0) || (y1 > canvasObj.height)) { dy1 = -dy1; }
if ((x2 < 0) || (x2 > canvasObj.width)) { dx2 = -dx2; }
if ((y2 < 0) || (y2 > canvasObj.height)) { dy2 = -dy2; }
}, 10);
})();