Skip to content

Instantly share code, notes, and snippets.

@khirayama
Created January 31, 2015 09:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save khirayama/ba28a96d4103e9156e56 to your computer and use it in GitHub Desktop.
Save khirayama/ba28a96d4103e9156e56 to your computer and use it in GitHub Desktop.
<canvas id='world' width="465" height="465"></canvas>
<div id="fps"></div>
<style>
body {
margin:0;
padding:0;
overflow:hidden;
background:#666;
}
canvas{
background:#000;
position:absolute;
top:0;
left:0;
}
#fps{
background:black;
color:white;
padding:.5em;
display:inline-block;
font-size:80%;
width:5em;
text-align:center;
border-radius:5px;
position:absolute;
top:5px;
left:5px;
}
</style>
<script>
// forked from os0x's "Particle 40000" http://jsdo.it/os0x/ezL2
// forked from os0x's "Particle 10000" http://jsdo.it/os0x/30Pg
// forked from clockmaker's "Particle 3000" http://jsdo.it/clockmaker/particle
/*
* Opera10.60 Betaならいける気がする 10まん
*/
/*
* いろいろ弄ってみたけど、パフォーマンス自体はほとんど変わってない…
* 単にFPS落として40000パーティクル
* Opera10.60 Betaが最適
*/
/*
* Canvas での擬似lock/unlockとか使って無理やり 10000 パーティクル
* 参考: http://ss-o.net/game2d/tech.html#C12
*/
/**
* みんな大好きパーティクル
* (JavaSript, HTML5バージョン)
*
* @author clockmaker
* @see http://clockmaker.jp/blog/
*
* wonderflのパーティクル祭りを参考
* http://wonderfl.net/c/436W/
*/
// -----------------------------------------
// 定数
// -----------------------------------------
var MAX_NUM = 100000; // パーティクルの個数
var FPS = 20;
var FRAMERATE = FPS / 1000 >> 0; // フレームレート
// -----------------------------------------
// クラス定義
// -----------------------------------------
/**
* パーティクル
*/
function Particle(x,y) {
this.x = x;
this.y = y;
this.vx = 0;
this.vy = 0;
}
// -----------------------------------------
// 初期化
// -----------------------------------------
// 変数の初期化
var mouseX = 0;
var mouseY = 0;
// キャンバスの初期化
var canvas = document.getElementById("world");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;
ctx.fillStyle = "rgb(200, 200, 255)";
ctx.fillRect(0, 0, width, height);
// ピクセルを取得
var pixels = ctx.getImageData(0, 0, width, height);
var data = pixels.data;
for (var i = 3, l = data.length;i < l;i+=4){
data[i] = 0;
}
// setPixel を定義(色は固定)
var setPixel = (function(){
var data = pixels.data;
function _setPixel(x, y){
var idx = ((x|0) + (y|0) * width)*4;
data[idx+3] = 255;
}
return _setPixel;
})();
var delPixel = (function(){
var data = pixels.data;
function _setPixel(x, y){
var idx = ((x|0) + (y|0) * width)*4;
data[idx+3] = 0;
}
return _setPixel;
})();
var particles = [];
// パーティクルの初期化
for(var i=0; i<MAX_NUM; i++) {
var p = new Particle(
Math.random() * width,
Math.random() * height
);
particles.push(p);
}
// FPS の表示
var fps_view = document.getElementById('fps');
var Counter = 0, last = +new Date();
// イベントハンドラの登録
canvas.onmousemove = mouseMoveHandler;
setInterval(enterFrameHandler, FRAMERATE);
// -----------------------------------------
// イベントハンドラ
// -----------------------------------------
/**
* マウスが動いたとき
*/
function mouseMoveHandler(e) {
// var rect = e.target.getBoundingClientRect();
// マウス座標の更新(もっとスマートな方法ある?)
// → スマートではないけどoffsetで
mouseX = e.clientX - canvas.offsetLeft;
mouseY = e.clientY - canvas.offsetTop;
}
/**
* タイマー
*/
function enterFrameHandler() {
var gravityX = mouseX;
var gravityY = mouseY;
var n;
var l = particles.length;
while(l--){
n = particles[l];
delPixel(n.x,n.y);
var diffX = gravityX - n.x;
var diffY = gravityY - n.y;
var acc = 50 / (diffX * diffX + diffY * diffY);
var accX = acc * diffX;
var accY = acc * diffY;
n.vx += accX;
n.vy += accY;
n.x += n.vx;
n.y += n.vy;
n.vx *= 0.96;
n.vy *= 0.96;
if (n.x > width)
n.x = 0;
else if (n.x < 0)
n.x = width;
if (n.y > height)
n.y = 0;
else if (n.y < 0)
n.y = height;
// 点描
setPixel(n.x, n.y);
}
ctx.putImageData(pixels, 0, 0);
if (++Counter > FPS){
var now = +new Date();
var _f = 1000 / ((now - last) / Counter);
last = now;
Counter = 0;
fps_view.innerHTML = 'FPS '+_f.toFixed(2);
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment