HTML5 canvas - Burn DEMO

公開:2009-11-04 11:38
更新:2020-02-15 04:36
カテゴリ:web,html5,js

またしても古いデモコードより引っ張ってきてcanvasに移植。

2011/6/13 jsdo.itにコードをアップしました。

Burn Demo - jsdo.it - share JavaScript, HTML5 and CSS


<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>