2009年11月03日

HTML5 canvas - Burn DEMO

またしても古いでもコードより引っ張ってきてcanvasに移植。
<html>
<head>
<title>Sample0005(Burn Demo)</title>
<script type="text/javascript" >

/*--------------------------------------------------------------------
  Fire Effect デモ by SFPGMR.
  元ネタ:Frank Jan Sorensenさんのパスカルコード
	元ソースコードのヘッダコメント 
	Hi guys, try this, use it in your code, but please credit
	Frank Jan Sorensen Alias:Frank Patxi (fjs@lab.jt.dk) for the
	fireroutine.
  --------------------------------------------------------------------*/



var ctx;
var bufimg;
var w,h;
var dt;
var WIDTH = 320;
var HEIGHT = 200;
var buffer = new Array(WIDTH * HEIGHT);
var maxColor     = 256;  // Constant for the MakePal procedure 
var palette = new Array(maxColor);
var rootRand     =  20;//  Max/Min decrease of the root of the flames 
var decay        =  5;//  How far should the flames go up on the screen?
var minY         = 10;//  Startingline of the flame routine.
                       //  (should be adjusted along with MinY above) 
var smooth       =   2;//  How descrete can the flames be?
var minFire      =  50;//  limit between the "starting to burn" and
                       //  the "is burning" routines 
var xStart       =  50;//  Startingpos on the screen}
var xEnd         = 270;//  Guess! 
var flameWidth        = xEnd - xStart;// Well- 
var fireIncrease  =   100;// 	3 = Wood, 90 = Gazolin 
var flameArray = new Array(flameWidth);// frame Array
var keyBuffer = new Array(0);
var moreFire = 1;

function rgb(hue, saturation, intensity)
{
  var T = 256.9999 * intensity / 2.0;
  this.r = Math.floor((1.0 + saturation * Math.sin(hue - 2.0 * Math.PI / 3.0)) * T);
  this.g = Math.floor((1.0 + saturation * Math.sin(hue)) * T);
  this.b = Math.floor((1.0 + saturation * Math.sin(hue + 2.0 * Math.PI / 3.0)) * T);
  
}

/*
function rgb(r,g,b)
{
	this.r = r;
	this.g = g;
	this.b = b;
}
*/
function pset(x,y,r,g,b,a)
{
	var st = (x + w * y) * 4;
	dt[st++] = r;
	dt[st++] = g;
	dt[st++] = b;
	dt[st++] = a;
}

function init()
{
	var log = "";
	for(var i = 0; i < 256; ++i)
	{
		palette[i] = new rgb(4.6 - 1.5 * i / 64,i / 64.0,i / 64.0);
	}

	for(var i = 0; i < WIDTH*HEIGHT;++i)
	{
		buffer[i] = 0;
	}

	for(var i = 0; i < flameWidth;++i)
	{
		flameArray[i] = 0;
	}

}

function draw()
{	
	// get keycode
	var keyCode = ""
	if(keyBuffer.length > 0)
	{	keyCode = keyBuffer.shift();
	}
	
	// Put the values from FlameArray on the bottom line of the screen
	for(var i = 0;i < flameWidth;++i)
	{
		buffer[i + xStart + 199 * WIDTH] = flameArray[i];
	}
	
	//This loop makes the actual flames
	for(var i = xStart ; i < xEnd; ++i)
	{
		for(var j = minY; j < 200;++j)
		{
			var v = buffer[i + j * WIDTH];
			if(v == 0 || v < decay || i <= xStart || i >= xEnd) 
			{
				buffer[i + (j - 1) * WIDTH] = 0;
			} else {
				buffer[i - (Math.floor((Math.random() * 3)) - 1) + (j - 1) * WIDTH] = v - Math.floor(Math.random() * decay);
			}
		}
	}
	
	if(Math.floor(Math.random() * 150) == 0 || keyCode == "F")
	{
		var r = Math.floor(Math.random() * (flameWidth - 5));
		for(var i = r;i < (r + 5); ++i)
		{
			flameArray[i] = 255;
		}
	}
	
	if((keyCode == "A") && (moreFire >-2))
	{
		--moreFire;
	}
	
	if((keyCode == "S") && (moreFire < 4))
	{
		moreFire++;
	}
	
	if(keyCode >= "1" && keyCode <= "9")
	{
		fireIncrease = 3 + parseInt(keyCode) * 20;
	}
	
	for(var i = 0; i < flameWidth;++i)
	{
		var x = flameArray[i];
		if(x < minFire) {
			if(x > 10) { x += Math.floor(Math.random() * fireIncrease); }
		} else {
			x += Math.floor(Math.random(rootRand * 2 + 1) - rootRand + moreFire);
		}
		if(x > 255) x = 255;
		flameArray[i] = x;
	}
	
	for(var i = 1; i < (flameWidth / 8);++i)
	{
		var X = Math.floor(Math.sqrt(Math.random()) * flameWidth / 8);
		flameArray[X] = 0;
		flameArray[flameWidth - 1 - X] = 0;
	}
	
	for( var i = smooth ; i <  (flameWidth - smooth) ; ++i)
	{
		var X = 0;
		for(var j = -smooth ; j < smooth;++j)
		{
			X += flameArray[i+j];
		}
		flameArray[i] = Math.round(X / (2 * smooth  + 1));
	}
	var b = bufimg.data;
	for(var i = 0; i < WIDTH * HEIGHT; ++i)
	{
		b[i * 4 ] = palette[buffer[i]].r;
		b[i * 4 + 1] = palette[buffer[i]].g;
		b[i * 4 + 2] = palette[buffer[i]].b;
		b[i * 4 + 3] = 255;
	}
	ctx.putImageData(bufimg,0,0);
}

document.onkeydown = function()
{
	keyBuffer.push(String.fromCharCode(event.keyCode).toUpperCase());
}

window.onload = function()
{
	ctx = document.getElementById("ctx").getContext("2d");
	w = document.getElementById("ctx").flameWidth;
	h = document.getElementById("ctx").height;
	bufimg = ctx.createImageData(WIDTH,HEIGHT);
	init();
}


</script>
</head>
<body>
<div>Burn Demo</div>
<div>キー操作:フルキー1〜9 火勢調節 </div>
<input type="button" onclick="timerID = window.setInterval(draw,10);" value="Start"/ >
<input type="button" onclick="window.clearInterval(timerID);" value="Stop"/ >
<div>
<canvas id="ctx" width="320" height="200" style="border:1px solid gray;"></canvas>
</div>
</body>
</html>

タグ:Canvas HTML5
posted by S.F. at 11:38| 千葉 霧| Comment(0) | TrackBack(0) | HTML | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/131909466
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック