JavaScriptで雪を降らせてみた
あけましておめでとうございます。本年もよろしくお願いいたします。
絵心がなくうまく絵が描けないので、JavaScriptで絵を描いて見ることにしました。今回はほとんど解説なしです。
画面上で雪を降らせてみた
実際の雪の動きには近くないのですが、揺れながら降ってくる様子を出してみました。下のリンクから実際に動くページがみられると思います。ちなみに放置すると、雪が積もってしまいます。
雪を降らせるプログラム
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Snow man</title>
<style>
#canvas {
background: #000;
}
</style>
</head>
<body>
<canvas id="canvas" width="640" height="480"></canvas>
<form id="form">
雪の数:<span id="countOfSnow">500</span>
<input type="button" value="↓" onclick="snow(-10)">
<input type="button" value="↑" onclick="snow(+10)"> <br />
風:<span id="windSpeed">0</span>
<input type="button" value="←" onclick="wind(-1)">
<input type="button" value="→" onclick="wind(+1)">
</form>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var itvEvt;
var fps = 60;
var snowCount;
var arrayImage = [];
var maxSnow = 1000;
var fallSnow = 0;
var windSpeed;
var maxWind = 20;
init();
function init(){
snowCount = parseInt(
document.getElementById('countOfSnow').textContent);
windSpeed = parseInt(
document.getElementById('windSpeed').textContent);
for( var i=0; i<snowCount; i++ ){
arrayImage.push({
"x" : Math.random() * canvasWidth,
"y" : Math.random() * canvasHeight,
});
}
clearInterval( itvEvt );
itvEvt = setInterval( draw, 1000/fps );
}
function draw(){
ctx.clearRect( 0, 0, canvasWidth, canvasHeight );
drawSnowman();
ctx.fillStyle = 'rgb( 255, 255, 255 )';
ctx.fillRect( 0, canvasHeight-fallSnow/100, canvasWidth, fallSnow/100 );
drawSnow();
}
function drawSnow() {
ctx.fillStyle = 'rgb( 255, 255, 255 )';
for( var i=0; i<snowCount; i++ ){
arrayImage[i].x += Math.random()*2 -1 +windSpeed;
arrayImage[i].y += Math.random()*1.5;
arrayImage[i].x = ( arrayImage[i].x +canvasWidth ) % canvasWidth;
if( arrayImage[i].y > canvasHeight ){
arrayImage[i].x = Math.random() * canvasWidth;
arrayImage[i].y = -3;
fallSnow++;
}
ctx.beginPath();
ctx.arc( arrayImage[i].x, arrayImage[i].y, 3, 0, 2*Math.PI, false );
ctx.fill();
}
}
function drawSnowman(){
ctx.beginPath();
ctx.fillStyle = 'rgb( 255, 255, 255)';
ctx.arc( 500, 350, 50, 0, 2*Math.PI, false ); //頭
ctx.arc( 500, 440, 70, 0, 2*Math.PI, false ); //胴
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgb( 231, 126, 49 )';
ctx.arc( 500, 350, 7, 7, 0, 2*Math.PI, false );//鼻
ctx.fill();
ctx.beginPath();
ctx.lineWidth = 3;
ctx.strokeStyle = 'rgb( 0, 0, 0 )';
ctx.arc( 485, 335, 5 , 0, Math.PI, true ); //左目
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = 'rgb( 0, 0, 0 )';
ctx.arc( 515, 335, 5 , 0, Math.PI, true ); //右目
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 5;
ctx.strokeStyle = 'rgb( 255, 0, 0 )'; //口
ctx.arc( 500, 350, 25 , 45*Math.PI/180, 135*Math.PI/180, false );
ctx.stroke();
ctx.translate( 500, 350 );
ctx.rotate( 15 * Math.PI/180 );
ctx.fillStyle = 'rgb( 0, 0, 255 )';
ctx.fillRect( -30, -57, 60, 14 ); //バケツのふち
ctx.fillRect( -20, -87, 40, 30 ); //バケツ本体
ctx.rotate( -15 * Math.PI/180 );
ctx.translate( -500, -350 );
}
function snow( num ){
if( 0<=snowCount+num && snowCount+num<=maxSnow ){
snowCount += num;
document.getElementById('countOfSnow').innerHTML = snowCount;
init();
}
}
function wind( num ){
if( -maxWind<=windSpeed+num && windSpeed+num<=maxWind ){
windSpeed += num;
document.getElementById('windSpeed').innerHTML = windSpeed;
init();
}
}
</script>
</body>
</html>
長いように見えるけれど、87~123行目で雪だるまを描いていて、これが36行もあるのが原因のような気がします。
今回はこれでおしまいにします。それでは、また。
ディスカッション
コメント一覧
まだ、コメントがありません