not good but great

プログラミング、アート、映画・本の感想について書きます。

Canvasでマウスポインタ周りのパーティクルの速度を落とす

demo

Creative JSの動画を見たのがきっかけ

CreativeJS for Designers from Seb Lee-Delisle on Vimeo.


パーティクルをとりあえず動かしてみることを解説している。基本的なところはこれを写経して、後はオリジナルで何かできないかやっていた。

マウスポインタの取得方法

document.addEventListener("mousemove",onDocumentMouseMove,false);

イベントをこれでキャッチ。マウスを動かすと関数が実行される。

function onDocumentMouseMove(event){
	mouseX = event.clientX;
	mouseY = event.clientY;
}

画面端からの座標を取得。

マウスポインタ周りのパーティクルの速度を落とす

     //マウスポインタからパーティクルまでの距離	
		distance = Math.sqrt( Math.pow(blob.x - mouseX,2) + Math.pow(blob.y - mouseY,2));

		if(distance < radius){//
			blob.xSpeed *= 0.58;//減速
			blob.size *= 0.98;//縮小
		}

		if(distance > radius && distance < radius + 30){
			blob.xSpeed *= 1.3;//加速
		}

		blob.x += blob.xSpeed;
		blob.y += blob.ySpeed;

仕組みは簡単で、2点間の距離をまず計算する。それが円の半径よりも小さい、つまち円内にパーティクルが存在するなら、1より少ない数をかけ続ければ減速する。大きさについても同じ。

外側の緑の円では逆に加速させている。

画面外のパーティクルは削除

blobArray.push(blob);

実行するたびにパーティクル(blob:水滴)を配列に加えている。これだと実行時間が立つと、配列の要素数がどんどん増えていき、かなり重くなる。

     //delete the blob if it enters the outside screen 
		if(blob.x < 0 || canvas.width < blob.x || blob.y < -blob.size || SCREEN_HEIGHT + blob.size / 2 < blob.y || blob.size < 0.1){
			blobArray.splice(i,1);
		}

だから画面外に出たパーティクルは配列から削除している。spliceを使っているので、要素を削除したあと、順番を詰めてくれる。deleteもあるが、それは要素がundefinedになるだけで詰める訳ではない。

パーティクルに影をつける

     var canvas = document.getElementById("world");
     var c = canvas.getContext("2d");

     //影
		c.shadowColor = blob.shadowColor;
		c.shadowBlur = 10;

		//パーティクル	
		c.beginPath();
		c.arc(blob.x,blob.y,blob.size,0,Math.PI * 2);
		c.closePath();
		c.fill();

Canvasでは影をつけれる。Blurでぼかすとぼんやりした感じになる。OffsetX,Yで影の位置を変えることもできる。複数影を設定することも出来るが、アニメーションをさせるため実行するとかなり重くなったのでやめた。

乱数を返す関数を自作

function randomRange(min,max){
	return Math.random() * (max - min) + min;
}

指定した範囲内の乱数を返す関数。CreativeJSで使われていたが、元の関数が表示されていないので自分でつくった。

ボツ案

    t += 0.01;
	radian = t * Math.PI / 180;

	if(radian > 360){
		t = 0;
	}
	SIN = Math.sin(radian);
	COS = Math.cos(radian);

requestAnimationFrameでループさせて、tを増加させて三角関数を使えるようにする。

blob.x = COS * blob.x - SIN * blob.y + centerX - centerX * COS + centerY * SIN;
blob.y = SIN * blob.x + COS * blob.y + centerY - centerX * SIN - centerY * COS;

画面を中心とした回転行列を使って、パーティクルを回したが、速すぎた。動きもイマイチだった。
任意点周りの回転移動 画像処理ソリューション

blob.size = Math.abs( 20 * Math.cos(Math.sin(t * 3 + i))*Math.sin(t * 0.2 ));

大きさを三角関数を用いて変えたりもした。ぐいんぐいん動くけど、逆に見づらいのでやめた。

関数の参考にしたやつ。
Equations for Organic Motion

c.rotate(Math.PI * t);

Canvas自体が回転してしまって、むちゃくちゃなことになった笑。