こんにちは、デザイナーのスギヤマです。
今日は、クリスマスイブですね。
個人的にクリスマスは静かに雪が降っていて、綺麗と言ったイメージがあります。
なので気分だけでもそんな雰囲気を味わうべく、色々参考にしながらcanvasの勉強を兼ねて雪を振らせるJSを書いてみました。
以下で簡単説明していきます。
サンプルコード
サンプルおよび記事トップ写真 : 東京駅丸の内正面通りからの夜景
色々準備する
canvasを使うための準備をしていきます。
今回はブラウザーのウィンドウにフィットする様に表示させる方向で進めます。
canvasの表示領域は、設定しないと可変にならないようなので、
リサイズイベントを検知してcanvasのサイズを変えるよう指定します。
snow.js
/*------------------------
canvas要素の取得と設定
-------------------------*/
//canvas要素の取得
var canvas = document.getElementById('canvas');//canvasを取得
var ctx = canvas.getContext('2d');//canvasのコンテキストを取得
//canvasサイズの設定
var wd_width = window.innerWidth; //ウィンドウ幅をキャンバス幅に。
var wd_height = window.innerHeight; //ウィンドウ高をキャンバス高に。
ctx.canvas.width = wd_width;
ctx.canvas.height = wd_height;
/*------------------------------------------------
ループ処理「requestAnimFrame」のベンダープレフィクス
-------------------------------------------------*/
var animFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
/*------------------------
canvasサイズを可変にする
-------------------------*/
function canvas_resize(){
var rswd_width = window.innerWidth;
var rswd_height = window.innerHeight;
canvas.setAttribute('width',rswd_width);
canvas.setAttribute('height',rswd_height);
}
//リサイズイベントを拾って実行
window.addEventListener('resize',canvas_resize,false);
canvas_resize();
雪の粒を描く
雪の粒を作成していきます。
雪の粒は、
- 丸い
- ふわふわしている
- 白い
感じなので、これを表現できるようにします。
白い円が外側に向かって、グラデーションで透明になっていけば大丈夫そうです。
また、雪の粒をランダムな位置に表示したいので、乱数を使う準備が必要です。
以下の個所で諸々指定しています。
snow.js
/*------------------------
乱数
min から max までの乱整数を返す関数
Math.round() を用いると、非一様分布になります
-------------------------*/
function getRandomInt(min, max) {
return Math.floor( Math.random() * (max - min + 1) ) + min;
}
/*------------------------
雪の設定
-------------------------*/
// 雪の粒の初期位置とサイズの設定
function snow(){
this.position_x = getRandomInt(0, wd_width);
this.position_y = getRandomInt(0, wd_height);
this.snow_size = getRandomInt(1, 4);
this.speed = getRandomInt(1, 3); //落下速度
this.wind = getRandomInt(0, 0.5); //横風の強さ
}
// 雪の粒の描画
snow.prototype.draw = function() {
var snow_grad = ctx.createRadialGradient(
this.position_x,
this.position_y,
this.snow_size * 0.6,
this.position_x,
this.position_y,
this.snow_size
);
/* グラデーション終点のオフセットと色をセット */
snow_grad.addColorStop(0,'rgba(225, 225, 225, 0.8)');
snow_grad.addColorStop(0.5,'rgba(225, 225, 225, 0.2)');
snow_grad.addColorStop(1,'rgba(225, 225, 225, 0.1)');
ctx.beginPath();
ctx.fillStyle = snow_grad; // グラデーションをfillStyleプロパティにセット
ctx.arc( this.position_x, this.position_y, this.snow_size, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
以下を参考にしました。
- 円の作り方:
arc()
メソッド - 円形グラデーションの付け方: 円形グラデーションを指定する
- 乱数の取り出し方:
Math.random()
これで、雪の粒が作成できました。
雪を動かす
雪の粒ができたので、今度は動かしていきます。
雪はふわふわ落ちて行くので、ただ、上から下へ移動するするのではなく、左右に揺れながら波の様な動きで落ちて欲しいです。
丁度、サイン波がそんな動きなので、使ってみます。
以下の個所で指定しています。
snow.js
snow.prototype.move = function() {
this.position_x += this.wind + Math.sin(this.position_y/20)*0.3;
this.position_y += this.speed;
if (this.position_y > ctx.canvas.height) {
this.position_y = 0;
this.position_x = getRandomInt(0, wd_width);
}
}
画面内の雪の量を決める
雪の降る量を調整します。
たとえば、snow_density(80);
とかで実行すると画面内に80粒の雪が降ります。
以下の個所で指定しています。
snow.js
// 雪の粒の密度(雪の量)
function snow_density(snow_count) {
for(var num = 0; num < snow_count; num++){
snows[num] = new snow();
}
}
雪を降らせる
雪を降らせます。
流れとしては、
- 雪を初期位置に描画する
- 描画した雪の表示座標を更新して移動させる
- 1~2をくり返す
となります。
以下の個所で指定しています。
snow.js
/*------------------------
雪を降らす処理
-------------------------*/
//雪の粒を描画する
function snow_draw(){
ctx.clearRect(0,0, wd_width, wd_height);
for(var num = 0; num < snows.length; num++){
snows[num].draw();
}
}
//雪の粒の座標を更新する
function snow_move() {
for (var num = 0; num < snows.length; num++) {
snows[num].move();
}
}
//ループ処理
function snowy(){
snow_draw();
snow_move();
animFrame(snowy);
}
snow_density(80);
snowy();
まとめ
どうでしょう?少しはクリスマスっぽい気分になれたでしょうか?
僕は、少しはクリスマスな気持ちになりました。
まだまだ、分からないことが多いですが、canvasを使うと色々な表現ができそうで、楽しそうです。
それではみなさん、ハッピークリスマス。
参考
- http://tsukulog.net/archives/2182
- https://qiita.com/nekoneko-wanwan/items/33afa5d20264c83b2bd1
- https://qiita.com/merci10/items/dfc36e47cd533b8912f7
- http://loktar00.github.io/JQuery-Snowfall/
デザインに関するお問い合わせ
キャンペーンサイトやメディアサイト、コーポレートサイト制作など、幅広く対応致します。デザインに関するお問い合わせ、ご相談は下記ページより承っております。お気軽にお問い合わせください。