Index

HOME > プログラムTOP > JavaScript



雪を降らせる

 雪や花びらなど、上から下へ画像を降らせる単純な方法を試してみます。(IE5以上/NN6以上)
  • 概要 :: 全体像です。
  • 宣言部 :: グローバル変数とクラスを設定します。
  • イベント処理のための関数 :: 各種イベントに対応する関数群です。
  • 画像の位置を設定する関数 :: 雪の位置を決めて移動させる関数です。
  • HTMLの記述例 :: 導入時のHTML側の記述例です。

sasaraan programming

Exposition

■概要

 一つのクラスと以下の五つの関数を作成します。
  • Snow クラス :: イメージオブジェクトや画像の位置やサイズを保持します。
  • Load_Page(id_body)関数 :: ページのロード時(loadイベント)に呼び出し初期化を行います。
  • Start_Click() 関数 :: 画像を表示します。Start ボタンをつくった場合に対応します。
  • Stop_Click() 関数 :: 画像を非表示にします。Stop ボタンをつくった場合に対応します。
  • Size_Changed() 関数 :: ウィンドウサイズの変更時(resizeイベント)に対応します。
  • SetSnow() 関数 :: 画像の位置を設定します。Start_Click関数から呼び出します。
 ・今回使った画像(32x32) :
 画像をつくるのはあまり得意ではありません。悪しからず。

■宣言部

 グローバル変数とクラスの宣言です。画像の位置を記憶させたりイメージオブジェクトを保持するために、クラスにしてひとまとめにしています。これをもとに、必要分インスタンスをつくって画像を表示させることになります。
 変数の宣言の部分では、画像の種類(sSnow)、画像数(nSnow)やスピード(nSpan)、動き(nMove)を調整することができます。
// Snow クラス
function Snow() {
     this.X = 0;                 // 左の位置(X座標 : px)
     this.Y = 0;                 // 上の位置(Y座標 : px)
     this.Width = 32;          // 画像の幅(px)
     this.Height = 32;         // 画像の高さ(px)
     this.Image = null;        // イメージオブジェクト
}

// グローバル変数
var bIE = false;                       // ブラウザがIEかどうか(true | false)
var bIE6std = false;                 // ブラウザがIE6標準モードかどうか(true | false)
var nSpan = 100;                    // 画像を動かす間隔(ミリ秒)
var nMoveX = 2;                     // 一度にX方向に動かす最大距離(左右の揺れ:px)
var nMoveY = 4;                     // 一度にY方向に動かす最大距離(落下距離:px)
var nWidth;                            // 表示領域(body)の幅(px)
var nHeight;                           // 表示領域(body)の高さ(px)
var nSnow = 16;                      // 画像の数
var aSnow;                             // Snowオブジェクトの配列
var sSnow = "snow_sm_1.gif";   // 画像のアドレス
var oParent;                           // 親オブジェクト(body)
var bStop = true;                    // 中止フラグ(true | false) 

■イベント処理のための関数

 ブラウザによって表示領域のサイズの取得の仕方が異なるので、ブラウザの識別が必要になります。ここではユーザーエージェントからブラウザを割り出しています。詳しくは「ブラウザの識別」のページを見てください。
 Size_Changed関数は、表示領域のサイズを取得するためのものです。本来初期化の際に処理すればよいのですが、ユーザーが途中でウィンドウサイズを変更する(resizeイベント)ことも考えられますので、別関数にして対応しています。Start_Click 関数も同様です。
 なお、Math.random で 0〜1 までの乱数を取得できます。
// ロードイベント(引数 : bodyタグのid属性値)
function Load_Page(id_body) {
     if (!document.getElementById) return;     // バージョンチェック(IE5以上/NN6以上)

     // ブラウザの識別
     var ua = navigator.userAgent;
     var nHit = ua.indexOf("MSIE");
     bIE = (nHit >=  0);
     bIE6std = bIE && 
                  (ua.substr(nHit+5, 1) == "6") && 
                  (document.compatMode=="CSS1Compat");

     Size_Changed();                                              // 表示領域のサイズの取得
     oParent = document.getElementById(id_body);    // 親オブジェクトの特定
     aSnow = new Array(nSnow);                             // Snowオブジェクトの配列

     // Snowオブジェクトの作成
     for (var i=0; i<nSnow; i++) {
          aSnow[i] = new Snow();
          aSnow[i].Image = new Image();
          with (aSnow[i]) {
               Image.src = sSnow;                               // 画像URI
               X = Math.random() * nWidth;                  // 初期位置(X)
               Y = Math.random() * nHeight;                 // 初期位置(Y)
               Image.style.position = "absolute";           // 絶対配置モード
          }
     }
     Start_Click();     // 画像の表示
}

// スタートボタンのクリックイベント
function Start_Click() {
     // 画像の表示
     if (!document.getElementById) return;  // バージョンチェック(IE5以上/NN6以上)
     if (bStop) {
          bStop = false;                              // 中止フラグを false にする
          for (var i=0; i<nSnow; i++) {          /* 画像を親オブジェクトに追加 */
               oParent.appendChild(aSnow[i].Image);
          }
          SetSnow();     // 画像の移動を開始
     }
}

// ストップボタンのクリックイベント
function Stop_Click() {
     // 画像の表示取りやめ
     if (!document.getElementById) return;  // バージョンチェック(IE5以上/NN6以上)
     if (!bStop) {
          bStop = true;                               // 中止フラグを true にする
          for (var i=0; i<nSnow; i++) {           /* 画像を親オブジェクトから削除 */
               oParent.removeChild(aSnow[i].Image);	
          }
     }
}

// リサイズイベント
function Size_Changed() {
     // 表示領域のサイズの取得
     if (bIE6std) {               /* IE6標準モードの時 */
          nWidth = document.documentElement.clientWidth;
          nHeight = document.documentElement.clientHeight;
     } else if (bIE) {            /* IE の時 */
          nWidth = document.body.clientWidth;
          nHeight = document.body.clientHeight;
     } else {                      /* IE 以外の時 */
          nWidth = window.innerWidth;
          nHeight = window.innerHeight;
     }
} 

■画像の位置を設定する関数

 SetSnow は画像を動かす関数です。変数bStop が false になっていればタイマーを止めます。そうでなければ画像を動かし続けます。極力単純な計算だけで位置を算出しています。Math.round は四捨五入のためのメソッドです。
function SetSnow() {
     var idTimer;          // タイマーのID
     if (bStop) {            /* 中止フラグが true の時はタイマーを解除 */
          if (idTimer) clearTimeout(idTimer);
          return;
     }

     // 画像の位置の設定
     var i;
     for (i=0; i<nSnow; i++) {

          // X座標の算出 : 揺れ幅
          aSnow[i].X += Math.round((Math.random() * 2 - 1) * nMoveX);

          // Y座標の算出 : 落下距離
          aSnow[i].Y += Math.round(Math.random() * nMoveY);

          // Y座標のチェック : 値が領域の下限を超えていたら一番上に戻る
          if (aSnow[i].Y >= (nHeight - aSnow[i].Height)) {
               aSnow[i].X = Math.round(Math.random() * nWidth);
               aSnow[i].Y = 0;
          }

          // X座標のチェック : 画像が右側にはみ出すのを抑止
          if (aSnow[i].X > (nWidth - aSnow[i].Width)) {
               aSnow[i].X = nWidth - aSnow[i].Width;
          }

          // 画像の位置を設定
          aSnow[i].Image.style.left = aSnow[i].X + "px";
          aSnow[i].Image.style.top = aSnow[i].Y + "px";
     }

     // タイマーの設定
     idTimer = setTimeout("SetSnow()", nSpan);
} 

■HTMLの記述例

 body タグ内にロードイベントとリサイズイベントを記述しています。スタート、ストップの両ボタンはなくてもよいのですが、ここでは設置してそれぞれクリックイベントを記述しています。
<body id="body1" style="background-image:url(back_moz_1.gif); background-color:#cccccc" 
  onload="Load_Page('body1')" onresize="Size_Changed()">
     <form style="text-align:right">
     <input type="button" value="START" onclick="Start_Click()" style="width:6em"> 
     <input type="button" value="STOP" onclick="Stop_Click()" style="width:6em" > 
     </form>
</body> 

www.sasaraan.net

(c) morijoh