「JavaScriptにおいて関数はクラスと同義である」ということで、実際に「雪」クラス(関数)を作って雪がたくさん降ってくる様をcanvasに描いた。
関数Snow(var Snow = function(){…})に定義されているvar変数やthis.moveなどのメソッドはnewされたときオブジェクトとして独立して振舞う。同じcanvas上に雪を表現するためにobjectListという変数をグローバル定義している。このobjectList変数(配列)を使って雪オブジェクトの管理と消去を行う。
/*
* 雪クラス
*/
var Snow = function(sx, sy){
var speed = Math.floor(Math.random() * 5) + 1; // 落下速度 1~5
var yure = Math.floor(Math.random() * 3) + 1; // ゆれ 1~3
// 雪の初期位置
var x = sx;
var y = sy;
// 雪が降る
this.move = function(){
// 雪を描く
g.beginPath();
g.arc(x, y, 5, 0, Math.PI*2, false);
g.stroke();
// 雪の軌跡を計算
x = x + Math.sin((y + speed) * Math.PI/180) * yure;
y = y + speed;
if(y > SCREEN_HEIGHT){
return false;
}
return true;
};
};
オブジェクト管理
var objectList = []; // 雪オブジェクト管理用
画面上をタッチ(マウスクリック)すると雪の発生率が変化する。
今やJavaScriptは、オブジェクト指向プログラミングだけでなく、Web技術やスマートフォンとの連携など様々なテクニックが学べるプログラミング言語となったと思う。
HTML部分
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="snow.js"></script>
<title>雪がたくさん降る1</title>
<style>
<style>
body, #canvas {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<canvas id="canvas" width="320" height="480"></canvas>
</body>
</html>
JavaScript部分
// -------------------------------------------------------------------------
// snow.js 雪がたくさん降る1
//
// created at 2013-12-19 on torisky.com
// -------------------------------------------------------------------------
/*
* グローバル変数
*/
var canvas = null; // キャンバス
var g = null; // コンテキスト
var $id = function(id){ return document.getElementById(id); };
var title; // タイトル文字列
var objectList = []; // 雪オブジェクト管理用
var probability; // 雪の発生確率
/*
* 定数
*/
var SCREEN_WIDTH = 320;
var SCREEN_HEIGHT = 480;
var TICK = 1000/30;
/*
* リセット関数
*/
var reset = function(){
title = "snowy";
objectList = [];
probability = 0.95; // 雪の発生確率
g.clearRect(0, 0, canvas.width, canvas.height);
};
/*
* 情報表示
*/
var showInformation = function(){
g.fillStyle = "rgba(0, 0, 0, 0.5)";
g.fillText(title, 145, SCREEN_HEIGHT/ 2);
g.fillText("ObjectList: " + objectList.length, 24, 24);
var kakuritu = 100-(probability*100);
g.fillText(kakuritu + "% <- Click to change!", 24, 48);
};
/*
* オブジェクト追加関数
*/
var addObject = function(obj){
for(var i=0; i<objectList.length+1; i++){
if(objectList[i] == null){
objectList[i] = obj;
console.log("addObject() " + i);
break;
}
}
};
/*
* 雪クラス
*/
var Snow = function(sx, sy){
var speed = Math.floor(Math.random() * 5) + 1; // 落下速度 1~5
var yure = Math.floor(Math.random() * 3) + 1; // ゆれ 1~3
// 雪の初期位置
var x = sx;
var y = sy;
// 雪が降る
this.move = function(){
// 雪を描く
g.beginPath();
g.arc(x, y, 5, 0, Math.PI*2, false);
g.stroke();
// 雪の軌跡を計算
x = x + Math.sin((y + speed) * Math.PI/180) * yure;
y = y + speed;
if(y > SCREEN_HEIGHT){
return false;
}
return true;
};
};
/*
* マウスクリック/タッチ時の処理
*/
var ontouch = function(x, y){
var kakuritu = Math.floor(Math.random() * 100) + 1;
kakuritu /= 100;
probability = kakuritu;
};
/*
* メイン処理
*/
var mainLoop = function(){
g.clearRect(0, 0, canvas.width, canvas.height);
showInformation();
// オブジェクトの動作と消去
for(var i=0; i<objectList.length; i++){
var obj = objectList[i];
if(obj && !obj.move()){
delete objectList[i];
}
}
// 雪の生成
if(Math.random() > probability){
addObject(new Snow(Math.random() * SCREEN_WIDTH, 0-Math.random()*150));
}
setTimeout(mainLoop, TICK);
};
/*
* 起動処理
*/
window.onload = function(){
// キャンバス情報取得
canvas = $id("canvas");
g = canvas.getContext("2d");
// 雪を降らせる
reset();
mainLoop();
// タッチイベント処理
canvas.onmousedown = function(e){
ontouch(e.clientX, e.clientY);
};
canvas.ontouchstart = function(e){
if(e.touches[0]){
ontouch(e.touches[0].clientX, e.touches[0].clientY);
}
e.preventDefault();
};
};


コメント
[…] canvas上の指定した位置に画像を描画できる、ということで前回作った「JavaScript:雪がたくさん降る」を雪の結晶画像に変更した。 […]