Canvasアニメーションの基礎については下記を参考にしてください。
この記事は下記をベースとして進めます。
HTML5で作るCanvasアニメーションの基礎
HTML5+Canvasでパーティクルっぽいのを作ってみる
基本となるオブジェクトを作成する
前回作成したParticleオブジェクトを少し編集します。
var Particle = function(scale, color, vx, vy) { this.scale = scale; //大きさ this.color = color; //色 this.vx = vx; //X速度 this.vy = vy; //Y速度 this.position = { // 位置 x: 0, y: 0 }; }; Particle.prototype.draw = function() { ctx.beginPath(); ctx.arc(this.position.x, this.position.y, this.scale, 0, 2*Math.PI, false); ctx.fillStyle = this.color; ctx.fill(); }; Particle.prototype.update = function() { // ここにアニメーション処理を書く this.position.y -= this.vy; this.draw(); };
主な変更点はアニメーション処理を「update」としてParticleに持たせたことです。
作成したParticleオブジェクトを使用して動かしてみましょう。
ループ関数ではupdateをParticleのupdateを実行するだけになります。
var particle = new Particle(12, '#D0A000', 5, -6); particle.position.x = (canvas.width / 2) - 6; particle.position.y = 0; loop(); // ループ処理 function loop() { requestAnimFrame(loop); // 描画をクリアー ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height); particle.update(); }
とりあえず落下はしてますけど、一定の速度なので全然リアルな動きではないですね。
加速度を付ける
落下すると物体のスピードは重力の影響を受けて徐々に速くなります。
なのでupdateで徐々に速くなるような仕組みを作ってあげましょう。
var Particle = function(scale, color, vx, vy, gv) { this.scale = scale; //大きさ this.color = color; //色 this.vx = vx; //X速度 this.vy = vy; //Y速度 this.gv = gv; //重力 [追加] this.position = { // 位置 x: 0, y: 0 }; }; Particle.prototype.update = function() { this.vy += this.gv; this.position.y += this.vy; this.draw(); };
gvという重力値を設定してvyをプラス処理をしています。
加速度がついてそれらしくなってきましたが、ちょっとわかりづらいのでX方向にも動かしてみましょう。
Particle.prototype.update = function() { this.vy += this.gv; this.position.x += this.vx; this.position.y += this.vy; this.draw(); }; var particle = new Particle(12, '#D0A000', 5, -5, 0.4); particle.position.x = 0; particle.position.y = 100;
さらにnew時にYをマイナス方向にすることで、最初に上方向に上昇した後に放物線を描くように落下します。
バウンドさせる
今の状態は落下すると画面外に出てしまいますが、Canvasの下を地面と仮定してバウンドさせてみましょう。
Particle.prototype.update = function() { this.vy += this.gv; this.position.x += this.vx; this.position.y += this.vy; // 地面の衝突判定 if (this.position.y > canvas.height - this.scale) { this.vy *= -0.6; this.vx *= 0.85; this.position.y = canvas.height - this.scale; } this.draw(); };
7〜11行目を追加しています。
vyにマイナス数値を掛けるることで逆方向(バウンド)の動きをします。
xxに小数点を掛けることで速度は減速します。
パーティクルっぽくしてみる。
最後に前回やったようにParticleオブジェクトを大量生成してみます。
var density = 100; //パーティクルの密度 var particles = []; //パーティクルをまとめる配列 var colors = ['#D0A000', '#6DD0A5', '#E084C5']; for (var i=0; i<density; i++) { var color = colors[~~(Math.random()*3)]; var scale = ~~(Math.random()*5)+3; var x = Math.random() * 10 - 5; var y = Math.random()* 9 + 4; var g = Math.random()* 0.2 + 0.3; particles[i] = new Particle(scale, color, x, -y, g); particles[i].position.x = canvas.width / 2; particles[i].position.y = 200; } function loop() { requestAnimFrame(loop); // 描画をクリアー ctx.clearRect(0,0, ctx.canvas.width, ctx.canvas.height); for (var i in particles) { particles[i].update(); } }
爆発みたいな感じになりましたね。
動き的に奇妙なところもありますが、なかなか面白くないですかね。