[canvasアニメーション + 音]みたいなもの作ろかと思って、当初サウンド部分はp5.jsを使うつもりだったが、うまくいかず。そもそもp5.jsのライブラリを読み込んだ時点でcanvasのアニメーション部分が動かなかった。(ライブラリの読み込みをやめると正常に動く。)結局色々調べてサウンド部分はhowler.jsを使ってみた。それで、できたモノが以下。
=================================
→ canvas animation + howler.js (音量注意)
=================================
全体のざっくりとした仕組みとしては、[mousedown]でパーティクルのインスタンスを生成、その際各々パーティクルの色、音をランダムで決定。反射時に音を再生。徐々にパーティクルの半径を減少させ、半径が一定以下になったら消去。
細かく見ていくと、まずサウンドを配列に格納。
Javascript
// サウンド var sound = []; sound[0] = new Howl({ urls:['assets/se01.mp3', 'assets/se01.wav'] }); sound[1] = new Howl({ urls:['assets/se02.mp3', 'assets/se02.wav'] }); sound[2] = new Howl({ urls:['assets/se03.mp3', 'assets/se03.wav'] }); sound[3] = new Howl({ urls:['assets/se04.mp3', 'assets/se04.wav'] }); sound[4] = new Howl({ urls:['assets/se05.mp3', 'assets/se05.wav'] }); var sound_num = sound.length - 1;
で、反射時にサウンドを再生。
Javascript
this.se = Math.floor(Math.random() * sound_num); <省略> // パーティクル画面外で反射 if (this.x - this.radius*0.5 < 0 || this.x - this.radius*0.5 > SCREEN_WIDTH -15) { sound[this.se].play(); this.vx *= -1; } if (this.y - this.radius*0.5 < 0 || this.y - this.radius*0.5 > SCREEN_HEIGHT-15) { sound[this.se].play(); this.vy *= -1; }
そして、マウスイベントとタッチイベントをそれぞれ振り分けて設定。
Javascript
//イベント if ("ontouchstart" in window) { canvas.addEventListener("touchstart", updateTouchPos, false); canvas.addEventListener("touchmove", resetMousePos, false); canvas.addEventListener("touchend", resetMousePos, false); } else { canvas.addEventListener("mousedown", updateMousePos, false); canvas.addEventListener("mouseup", resetMousePos, false); canvas.addEventListener("mouseout", resetMousePos, false); } <省略> // タッチの位置を取得 var updateTouchPos = function (e) { mx = e.touches[0].pageX; my = e.touches[0].pageY; }; // マウスの位置を取得 var updateMousePos = function (e) { var rect = e.target.getBoundingClientRect(); mx = e.clientX - rect.left; my = e.clientY - rect.top; }; // マウスの位置をリセット var resetMousePos = function (e) { mx = null; my = null; };
[if ("ontouchstart" in window) ]でタッチスクリーンに対応しているかいないかで振り分けて、それぞれ関数を呼び出し。マウスイベントとタッチイベントでは、位置取得の方法が異なるのがちょっとキモ。
一応、chrome、Firefox、IE11で動作確認済み。IE8ではもちろん動かず。IE9ではcanvasのアニメーションはする。音はしない。それとiPadとAndoroid携帯でも動作確認済み。iPad動作的に気持ちいいけど、音が不安定。
当初は反射時に音にp5.jsでリバーブをかけたかったが、p5.js自体がダメだったのでhowler.jsを使用。howler.jsはp5.jsのサウンド部分に比べると本当にシンプル。その分できることは限られていて、ゲームの効果音とかで使用するのに向いているっぽい。そしてライブラリが軽い(12k)。
パーティクルの部分のソースは[HTML5デザイン 仕事のネタ CSS3+JavaScript+CSSフレームワークと活用するプロのテクニック]参考にさせて頂きました。
p5.jsのサウンドライブラリを使うには、それ以外の部分、ここで言うとアニメーション部分もp5.jsの書式で記述しなければならないっぽい。サウンドのライブラリは魅力的だけど、それ以外もp5.jsの書式で書かなければならないのが難。
ちなみに、裏実験として音を[ド・レ・ミ・ソ・ラ]のヨナ抜き音階にしてみて、ランダムに鳴らした時に日本的に聞こえるかを試してみた。で、結果は、いまいち聞こえない。