6.11 指定した時間毎に繰り返す

(1/1)
レンチキュラー印刷のイラスト
たとえばアニメーションでフレームを切り替えて画面が動いているように見せるとき、一定間隔で繰り返し処理を行う必要がある。こういうときに利用するのが setIntervalメソッドである。指定したミリ秒ごとに、指定した関数を実行することができる。
今回は、setIntervalメソッドを使ってデジタル時計を表示するプログラムと、雪を降らせるアニメーション・プログラムを作ってみることにする。

目次

サンプル・プログラム

圧縮ファイルの内容
digitalclock.htmlサンプル・プログラム(デジタル時計)
analogClock.htmlサンプル・プログラム(アナログ時計)
snowfall.htmlサンプル・プログラム(雪を降らせる)
digitalclock.html 更新履歴
バージョン 更新日 内容
1.0.0 2023/06/18 初版
analogClock.html 更新履歴
バージョン 更新日 内容
1.0.0 2026/02/01 初版
snowfall.html 更新履歴
バージョン 更新日 内容
1.0.0 2023/06/18 初版

デジタル時計

初期値として以下の値を設定する。
スタイルシートなどへの設定は、windows.onload イベントを使って、このページがロードされるときに設定する。

digitalclock.html

  26: //初期値
  27: const TITLE = 'デジタル時計';       //プログラム・タイトル
  28: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js00/js00-06-11.html';
  29:                                     //参照サイト
  30: const WIDTH  = 600;                 //時計の幅(ピクセル)
  31: const HEIGHT = 400;                 //時計の高さ(ピクセル)
  32: const CLOCK_NAME = 'pclock';        //時計のオブジェクト名【変更不可】
  33: const TIME_NAME  = 'pclock-time';   //時刻部分のオブジェクト名【変更不可】
  34: const DATE_NAME  = 'pclock-date';   //日付部分のオブジェクト名【変更不可】
  35: 
  36: // メイン・プログラム ======================================================
  37: window.onload = function() {
  38:     //タイトル等をセット
  39:     document.title = TITLE;
  40:     document.getElementById('title').innerHTML = TITLE + '&nbsp;<span style="font-size:small;">' + getLastModified() + '版</span>';
  41:     document.getElementById('reference').innerHTML =`
  42: ※参考サイト&nbsp;<a href="${REFERENCE}">${REFERENCE}</a>
  43: `;
  44:     document.getElementById('phelp').style.width = WIDTH + 'px';
  45: 
  46:     //時計のスタイルシートを設定する.
  47:     let pclock = document.getElementById(CLOCK_NAME);
  48:     pclock.style.width  = WIDTH  + 'px';
  49:     pclock.style.height = HEIGHT + 'px';
  50:     let pclock_date = document.getElementById(DATE_NAME);
  51:     pclock_date.style.fontSize = Math.round(WIDTH / 20+ 'px'
  52:     pclock_date.style.paddingTop = Math.round(HEIGHT / 8+ 'px'
  53:     let pclock_time = document.getElementById(TIME_NAME);
  54:     pclock_time.style.fontSize = Math.round(WIDTH / 6+ 'px'
  55:     pclock_time.style.paddingTop = Math.round(HEIGHT / 8+ 'px'
  56: //--ここまで初期設定

時計動作を開始する

digitalclock.html

  58:     //時計動作を開始する関数
  59:     function startClock() {
  60:         setInterval(function () {
  61:             var dt      = new Date();           //現在日時
  62:             let year    = dt.getFullYear();     //
  63:             let month   = dt.getMonth() + 1;
  64:             let date    = dt.getDate();
  65:             let weeknum = dt.getDay();
  66:             const weekday = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
  67:             let week    = weekday[weeknum];
  68:             let hour    = dt.getHours();
  69:             let min     = dt.getMinutes();
  70:             let sec     = dt.getSeconds();
  71: 
  72:             //数字を2桁に揃える
  73:             month = zeroSuppress(month);
  74:             date  = zeroSuppress(date);
  75:             hour  = zeroSuppress(hour);
  76:             min   = zeroSuppress(min);
  77:             sec   = zeroSuppress(sec);
  78: 
  79:             //日付・時刻の文字列を作成
  80:             let today = `${year}.${month}.${date${week}`;
  81:             let time = `${hour}:${min}:${sec}`;
  82: 
  83:             //文字列を出力
  84:             document.getElementById(DATE_NAME).innerText = today;
  85:             document.getElementById(TIME_NAME).innerText = time;
  86: 
  87:         }, 1000);       //1000ミリ秒=1秒ごとに処理する
  88:     }

時計動作を開始するメソッドが startClock で、冒頭で紹介した setIntervalメソッドを使って、取得した現在日時を画面に1000ミリ秒(=1秒)ごとに繰り返し表示する。
すべの文字を再描画しているのだが、前回と変わらない文字はちらつかずに再描画される。

数字の桁数を揃える

digitalclock.html

 105: /**
 106:  * ゼロ・サプレスで数字をdigit桁に揃える.
 107:  * 与えた数字の頭に0を足して桁数を揃える.
 108:  * @param   String  num
 109:  * @param   Integer digit 数字の桁数
 110:  * @return  String 2桁の数字
 111: */
 112: function zeroSuppress(num, digit=2) {
 113:     let str = String(num);
 114:     str = '0'.repeat(digit+ str;
 115: 
 116:     return str.slice(-digit);
 117: }

与えた数字の頭に0を足して桁数を揃えるユーザー関数 zeroSuppress を用意した。桁数を指定するdigitは、デフォルト引数として2を与えている。
まず、与えた数値 num を文字列 str に変換する。
次に、repeatメソッドを使って、str の左側に '0' をdigit個結合する。
最後に、slice メソッドを使って、str の右側からdigit個の文字を取り出す。こうすることで桁合わせができる。

アナログ時計

初期値として以下の値を設定する。
スタイルシートなどへの設定は、windows.onload イベントを使って、このページがロードされるときに設定する。

analogClock.html

  32: // 各種定数(START) =========================================================
  33: const TITLE = 'アナログ時計';                   //プログラム・タイトル
  34: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js00/js00-06-11.html';
  35:                                                 // 参照サイト
  36: const WIDTH = 600;                              // 表示幅(ピクセル)
  37: const canvasId              = 'analogClock';    // canvas ID
  38: const backgroundColorClock  = 'white';          // 文字盤の背景色
  39: const borderColorClock      = 'gainsboro';      // 文字盤の周縁色
  40: const numberColor           = 'dimgray';        // 文字盤の数字の色
  41: const markerColor           = 'dimgray';        // 目盛りの色
  42: const handColor             = 'midnightblue';   // 時針・分針の色
  43: const secondHandColor       = 'indigo';         // 秒針の色
  44: 
  45: // 各種定数(END) ===========================================================

文字盤を描き、その文字盤に 3, 6, 9, 12 の数字を描き、時・分の目盛りを描き、時針・分針・秒針を描くユーザー関数は次の通り。

analogClock.html

  90:     /**
  91:      * 文字盤を描く
  92:      * @param   Object ctx    canvasオブジェクト
  93:      * @param   Number radius 文字盤の半径Object ctx canvasオブジェクト
  94:      * @return  なし
  95:     */
  96:     function drawFace(ctx, radius) {
  97:         ctx.beginPath();
  98:         ctx.arc(0, 0, radius - 5, 0, 2 * Math.PI);
  99:         ctx.fillStyle = 'white';
 100:         ctx.fill();
 101:     
 102:         ctx.lineWidth = 8;
 103:         ctx.strokeStyle = borderColorClock;
 104:         ctx.stroke();
 105:     
 106:         ctx.beginPath();
 107:         ctx.arc(0, 0, 5, 0, 2 * Math.PI);
 108:         ctx.fillStyle = backgroundColorClock;
 109:         ctx.fill();
 110:     }

analogClock.html

 112:     /**
 113:      * 文字盤に 3, 6, 9, 12 の数字を描く
 114:      * @param   Object ctx    canvasオブジェクト
 115:      * @param   Number radius 文字盤の半径Object ctx canvasオブジェクト
 116:      * @return  なし
 117:     */
 118:     function drawNumbers(ctx, radius) {
 119:         const numbers = [12, 3, 6, 9];
 120:         ctx.font = radius * 0.15 + 'px sans-serif';
 121:         ctx.textBaseline    = 'middle';
 122:         ctx.textAlign       = 'center';
 123:         ctx.fillStyle       = numberColor;
 124: 
 125:         numbers.forEach(num => {
 126:             const ang = num * Math.PI / 6;
 127:             ctx.rotate(ang);
 128:             ctx.translate(0, -radius * 0.75);
 129:             ctx.rotate(-ang);
 130:             ctx.fillText(num.toString(), 0, 0);
 131:             ctx.rotate(ang);
 132:             ctx.translate(0, radius * 0.75);
 133:             ctx.rotate(-ang);
 134:         });
 135:     }

analogClock.html

 137:     /**
 138:      * 文字盤に時・分の目盛りを描く
 139:      * @param   Object ctx    canvasオブジェクト
 140:      * @param   Number radius 文字盤の半径Object ctx canvasオブジェクト
 141:      * @return  なし
 142:     */
 143:     function drawMarkers(ctx, radius) {
 144:         for (let i = 0i < 60i++) {
 145:             const ang = i * Math.PI / 30;       // 1分刻み
 146:             ctx.beginPath();
 147:             const len = (i % 5 === 0? 15 : 7; // 5分刻みは大きめに
 148:             ctx.lineWidth = (i % 5 === 0? 4 : 2;
 149:             ctx.strokeStyle = markerColor;
 150:             ctx.rotate(ang);
 151:             ctx.moveTo(0, -radius + 5);
 152:             ctx.lineTo(0, -radius + 5 + len);
 153:             ctx.stroke();
 154:             ctx.rotate(-ang);
 155:         }
 156:     }

analogClock.html

 158:     /**
 159:      * 文字盤に時針・分針・秒針を描く
 160:      * @param   Object ctx    canvasオブジェクト
 161:      * @param   Number radius 文字盤の半径Object ctx canvasオブジェクト
 162:      * @return  なし
 163:     */
 164:     function drawTime(ctx, radius) {
 165:         const now = new Date();
 166:         const hour = now.getHours() % 12;
 167:         const minute = now.getMinutes();
 168:         const second = now.getSeconds();
 169: 
 170:         const hourAngle = (hour + minute / 60* Math.PI / 6;
 171:         drawHand(ctx, hourAngle, radius * 0.5, 8, handColor);
 172: 
 173:         const minuteAngle = (minute + second / 60* Math.PI / 30;
 174:         drawHand(ctx, minuteAngle, radius * 0.75, 6, handColor);
 175: 
 176:         const secondAngle = second * Math.PI / 30;
 177:         drawHand(ctx, secondAngle, radius * 0.85, 2, secondHandColor);
 178:     }

analogClock.html

 180:     /**
 181:      * 針を描く
 182:      * @param   Object ctx    canvasオブジェクト
 183:      * @param   Number pos    針の角度
 184:      * @param   Number length 針の長さ
 185:      * @param   Number width  針の幅
 186:      * @param   String colkor 針の色
 187:      * @param   Number radius 文字盤の半径Object ctx canvasオブジェクト
 188:      * @return  なし
 189:     */
 190:     function drawHand(ctx, pos, length, width, color) {
 191:         ctx.beginPath();
 192:         ctx.lineWidth = width;
 193:         ctx.lineCap = 'round';
 194:         ctx.strokeStyle = color;
 195:         ctx.moveTo(0,0);
 196:         ctx.rotate(pos);
 197:         ctx.lineTo(0, -length);
 198:         ctx.stroke();
 199:         ctx.rotate(-pos);
 200:     }

analogClock.html

  78:     /**
  79:      * 時計を描く
  80:      * @param   なし
  81:      * @return  なし
  82:     */
  83:     function drawClock() {
  84:         drawFace(ctx, radius);
  85:         drawNumbers(ctx, radius);
  86:         drawMarkers(ctx, radius);
  87:         drawTime(ctx, radius);
  88:     }

1秒(1,000ミリ秒)ごとに、文字盤と針を描き直す。こうすることによって、1秒ごとに秒針が進むタイプのアナログ時計が完成する。

analogClock.html

 202:     /**
 203:      * 時針・分針・秒針の更新間隔
 204:      * @param   なし
 205:      * @return  なし
 206:     */
 207:     setInterval(() => {
 208:         ctx.clearRect(-radius, -radius, canvas.width, canvas.height);
 209:         drawClock();
 210:     }, 1000);
 211: 
 212:     // 最初の文字盤を描く
 213:     drawClock();
 214: }

雪を降らせる

次に雪を降らせるプログラムであるが、初期値として以下の値を設定する。
アニメーションは、「6.9 グラフィックキャンバスとヒアドキュメント」で紹介した canvas要素を使う。
すべての準備や関数定義は、前述のデジタル時計と同じで、window.onload イベントの中で行う。

snowfall.html

  26: //初期値
  27: const TITLE = '雪を降らせる';       //プログラム・タイトル
  28: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js00/js00-06-11.html';
  29:                                     //参照サイト
  30: const INTERVAL = 50;                //再描画間隔(ミリ秒)
  31: const CANVAS_NAME = 'pcanvas';      //canvasオブジェクト名【変更不可】
  32: const WIDTH  = 600;                 //表示幅(ピクセル)
  33: const HEIGHT = 400;                 //表示高(ピクセル)
  34: const BGIMAGE = 'https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg';      //背景画像
  35: 
  36: // メイン・プログラム ======================================================
  37: window.onload = function() {
  38:     //タイトル等をセット
  39:     document.title = TITLE;
  40:     document.getElementById('title').innerHTML = TITLE + '&nbsp;<span style="font-size:small;">' + getLastModified() + '版</span>';
  41:     document.getElementById('reference').innerHTML =`
  42: ※参考サイト&nbsp;<a href="${REFERENCE}">${REFERENCE}</a>
  43: `;
  44:     document.getElementById('phelp').style.width = WIDTH + 'px';
  45: 
  46:     //canvas要素を取得する.
  47:     var canvas = document.getElementById(CANVAS_NAME);
  48:     //canvas要素にstyle設定する.
  49:     canvas.style.width  = WIDTH + 'px';
  50:     canvas.style.height = HEIGHT + 'px';
  51:     canvas.style.backgroundImage = "url('https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg')";
  52:     canvas.style.backgroundSize = 'cover';
  53: 
  54:     //Canvasの描画コンテキストを取得する.
  55:     var ctx = canvas.getContext('2d');
  56: 
  57:     //雪粒の数
  58:     var drops = [];
  59: //--ここまで初期設定

雪粒はオブジェクトで

snowfall.html

  61:     //雪粒の設定
  62:     function snowDrop() {
  63:         //雪粒の初期位置をランダムに設定する.
  64:         this.x = Math.random() * canvas.width;
  65:         this.y = 0 - Math.random() * canvas.height;
  66: 
  67:         //雪粒の落下スピードを乱数で設定する.
  68:         this.speed = Math.random() * 10 + 5;
  69:         //雪粒の半径を乱数を使って設定する.
  70:         this.radius = Math.random() * 0.3 + 0.3;
  71: 
  72:         //雪粒を描画する.
  73:         this.draw = function () {
  74:             ctx.beginPath();
  75:             ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
  76:             ctx.fillStyle = 'Azure';
  77:             ctx.fill();
  78:             ctx.closePath();
  79:         }
  80:     }

snowfall.html

   1: <![CDATA[
   2: /** snowfall.html
   3:  *  プログラミング入門 - 6.11 指定した時間毎に繰り返す
   4:  *  雪を降らせる
   5:  *
   6:  * @copyright   (c)studio pahoo
   7:  * @author      パパぱふぅ
   8:  * @動作環境    JavaScript ES6(ES2015)
   9:  * @参考URL     https://www.pahoo.org/e-soul/webtech/js01/js00-06-11.shtm
  10: */
  11: ]]>
  12: <!DOCTYPE html>
  13: <html lang="ja">
  14: <head>
  15: <meta charset="UTF-8">
  16: <title></title>
  17: <meta name="author" content="studio pahoo" />
  18: <meta name="copyright" content="studio pahoo" />
  19: <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />
  20: <meta http-equiv="pragma" content="no-cache">
  21: <meta http-equiv="cache-control" content="no-cache">
  22: <meta http-equiv="X-UA-Compatible" content="IE=edge">
  23: <meta name="viewport" content="width=550,user-scalable=yes" />
  24: 
  25: <script>
  26: //初期値
  27: const TITLE = '雪を降らせる';       //プログラム・タイトル
  28: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js00/js00-06-11.html';
  29:                                     //参照サイト
  30: const INTERVAL = 50;                //再描画間隔(ミリ秒)
  31: const CANVAS_NAME = 'pcanvas';      //canvasオブジェクト名【変更不可】
  32: const WIDTH  = 600;                 //表示幅(ピクセル)
  33: const HEIGHT = 400;                 //表示高(ピクセル)
  34: const BGIMAGE = 'https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg';      //背景画像
  35: 
  36: // メイン・プログラム ======================================================
  37: window.onload = function() {
  38:     //タイトル等をセット
  39:     document.title = TITLE;
  40:     document.getElementById('title').innerHTML = TITLE + '&nbsp;<span style="font-size:small;">' + getLastModified() + '版</span>';
  41:     document.getElementById('reference').innerHTML =`
  42: ※参考サイト&nbsp;<a href="${REFERENCE}">${REFERENCE}</a>
  43: `;
  44:     document.getElementById('phelp').style.width = WIDTH + 'px';
  45: 
  46:     //canvas要素を取得する.
  47:     var canvas = document.getElementById(CANVAS_NAME);
  48:     //canvas要素にstyle設定する.
  49:     canvas.style.width  = WIDTH + 'px';
  50:     canvas.style.height = HEIGHT + 'px';
  51:     canvas.style.backgroundImage = "url('https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg')";
  52:     canvas.style.backgroundSize = 'cover';
  53: 
  54:     //Canvasの描画コンテキストを取得する.
  55:     var ctx = canvas.getContext('2d');
  56: 
  57:     //雪粒の数
  58:     var drops = [];
  59: //--ここまで初期設定
  60: 
  61:     //雪粒の設定
  62:     function snowDrop() {
  63:         //雪粒の初期位置をランダムに設定する.
  64:         this.x = Math.random() * canvas.width;
  65:         this.y = 0 - Math.random() * canvas.height;
  66: 
  67:         //雪粒の落下スピードを乱数で設定する.
  68:         this.speed = Math.random() * 10 + 5;
  69:         //雪粒の半径を乱数を使って設定する.
  70:         this.radius = Math.random() * 0.3 + 0.3;
  71: 
  72:         //雪粒を描画する.
  73:         this.draw = function () {
  74:             ctx.beginPath();
  75:             ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
  76:             ctx.fillStyle = 'Azure';
  77:             ctx.fill();
  78:             ctx.closePath();
  79:         }
  80:     }
  81: 
  82:     //canvasに雪粒を追加する.
  83:     function addSnowDrop() {
  84:         drops.push(new snowDrop());
  85:     }

降らせる雪の粒1つ1つを snowDropメソッドで表す。
1つの snowDropオブジェクトが、1つの雪の粒を表していると考えてほしい。
canvas要素に雪粒を1つ追加するには、snowDropオブジェクトを1つ生成する。

snowDropオブジェクトには、雪粒の位置(x, y)や大きさ(radius)、落下スピード(speed)を、各々プロパティとして持たせてある。つまり、雪粒の位置や大きさ、落下スピードは、雪粒の1つ1つに対して独立に設定することができる。
これにより、アニメーションでは、早く落ちる雪粒や、ゆっくりと落ちる雪粒が混在し、あたかも雪が降っているように見せかけることができる。

雪粒の位置を更新する

snowfall.html

   1: <![CDATA[
   2: /** snowfall.html
   3:  *  プログラミング入門 - 6.11 指定した時間毎に繰り返す
   4:  *  雪を降らせる
   5:  *
   6:  * @copyright   (c)studio pahoo
   7:  * @author      パパぱふぅ
   8:  * @動作環境    JavaScript ES6(ES2015)
   9:  * @参考URL     https://www.pahoo.org/e-soul/webtech/js01/js00-06-11.shtm
  10: */
  11: ]]>
  12: <!DOCTYPE html>
  13: <html lang="ja">
  14: <head>
  15: <meta charset="UTF-8">
  16: <title></title>
  17: <meta name="author" content="studio pahoo" />
  18: <meta name="copyright" content="studio pahoo" />
  19: <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />
  20: <meta http-equiv="pragma" content="no-cache">
  21: <meta http-equiv="cache-control" content="no-cache">
  22: <meta http-equiv="X-UA-Compatible" content="IE=edge">
  23: <meta name="viewport" content="width=550,user-scalable=yes" />
  24: 
  25: <script>
  26: //初期値
  27: const TITLE = '雪を降らせる';       //プログラム・タイトル
  28: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js00/js00-06-11.html';
  29:                                     //参照サイト
  30: const INTERVAL = 50;                //再描画間隔(ミリ秒)
  31: const CANVAS_NAME = 'pcanvas';      //canvasオブジェクト名【変更不可】
  32: const WIDTH  = 600;                 //表示幅(ピクセル)
  33: const HEIGHT = 400;                 //表示高(ピクセル)
  34: const BGIMAGE = 'https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg';      //背景画像
  35: 
  36: // メイン・プログラム ======================================================
  37: window.onload = function() {
  38:     //タイトル等をセット
  39:     document.title = TITLE;
  40:     document.getElementById('title').innerHTML = TITLE + '&nbsp;<span style="font-size:small;">' + getLastModified() + '版</span>';
  41:     document.getElementById('reference').innerHTML =`
  42: ※参考サイト&nbsp;<a href="${REFERENCE}">${REFERENCE}</a>
  43: `;
  44:     document.getElementById('phelp').style.width = WIDTH + 'px';
  45: 
  46:     //canvas要素を取得する.
  47:     var canvas = document.getElementById(CANVAS_NAME);
  48:     //canvas要素にstyle設定する.
  49:     canvas.style.width  = WIDTH + 'px';
  50:     canvas.style.height = HEIGHT + 'px';
  51:     canvas.style.backgroundImage = "url('https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg')";
  52:     canvas.style.backgroundSize = 'cover';
  53: 
  54:     //Canvasの描画コンテキストを取得する.
  55:     var ctx = canvas.getContext('2d');
  56: 
  57:     //雪粒の数
  58:     var drops = [];
  59: //--ここまで初期設定
  60: 
  61:     //雪粒の設定
  62:     function snowDrop() {
  63:         //雪粒の初期位置をランダムに設定する.
  64:         this.x = Math.random() * canvas.width;
  65:         this.y = 0 - Math.random() * canvas.height;
  66: 
  67:         //雪粒の落下スピードを乱数で設定する.
  68:         this.speed = Math.random() * 10 + 5;
  69:         //雪粒の半径を乱数を使って設定する.
  70:         this.radius = Math.random() * 0.3 + 0.3;
  71: 
  72:         //雪粒を描画する.
  73:         this.draw = function () {
  74:             ctx.beginPath();
  75:             ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
  76:             ctx.fillStyle = 'Azure';
  77:             ctx.fill();
  78:             ctx.closePath();
  79:         }
  80:     }
  81: 
  82:     //canvasに雪粒を追加する.
  83:     function addSnowDrop() {
  84:         drops.push(new snowDrop());
  85:     }
  86: 
  87:     //雪粒の位置を更新する関数
  88:     function updateSnowDrops() {
  89:         for (var i = 0i < drops.lengthi++) {
  90:             //雪粒が落下するように見せかける.
  91:             drops[i].y +drops[i].speed;
  92:             //雪粒がcanvasの下端に達したら画面上から消す.
  93:             if (drops[i].y > canvas.height) {
  94:                 drops.splice(i, 1);
  95:                 i--;
  96:             }
  97:         }
  98:     }

snowfall.html

   1: <![CDATA[
   2: /** snowfall.html
   3:  *  プログラミング入門 - 6.11 指定した時間毎に繰り返す
   4:  *  雪を降らせる
   5:  *
   6:  * @copyright   (c)studio pahoo
   7:  * @author      パパぱふぅ
   8:  * @動作環境    JavaScript ES6(ES2015)
   9:  * @参考URL     https://www.pahoo.org/e-soul/webtech/js01/js00-06-11.shtm
  10: */
  11: ]]>
  12: <!DOCTYPE html>
  13: <html lang="ja">
  14: <head>
  15: <meta charset="UTF-8">
  16: <title></title>
  17: <meta name="author" content="studio pahoo" />
  18: <meta name="copyright" content="studio pahoo" />
  19: <meta name="ROBOTS" content="NOINDEX,NOFOLLOW" />
  20: <meta http-equiv="pragma" content="no-cache">
  21: <meta http-equiv="cache-control" content="no-cache">
  22: <meta http-equiv="X-UA-Compatible" content="IE=edge">
  23: <meta name="viewport" content="width=550,user-scalable=yes" />
  24: 
  25: <script>
  26: //初期値
  27: const TITLE = '雪を降らせる';       //プログラム・タイトル
  28: const REFERENCE = 'https://www.pahoo.org/e-soul/webtech/js00/js00-06-11.html';
  29:                                     //参照サイト
  30: const INTERVAL = 50;                //再描画間隔(ミリ秒)
  31: const CANVAS_NAME = 'pcanvas';      //canvasオブジェクト名【変更不可】
  32: const WIDTH  = 600;                 //表示幅(ピクセル)
  33: const HEIGHT = 400;                 //表示高(ピクセル)
  34: const BGIMAGE = 'https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg';      //背景画像
  35: 
  36: // メイン・プログラム ======================================================
  37: window.onload = function() {
  38:     //タイトル等をセット
  39:     document.title = TITLE;
  40:     document.getElementById('title').innerHTML = TITLE + '&nbsp;<span style="font-size:small;">' + getLastModified() + '版</span>';
  41:     document.getElementById('reference').innerHTML =`
  42: ※参考サイト&nbsp;<a href="${REFERENCE}">${REFERENCE}</a>
  43: `;
  44:     document.getElementById('phelp').style.width = WIDTH + 'px';
  45: 
  46:     //canvas要素を取得する.
  47:     var canvas = document.getElementById(CANVAS_NAME);
  48:     //canvas要素にstyle設定する.
  49:     canvas.style.width  = WIDTH + 'px';
  50:     canvas.style.height = HEIGHT + 'px';
  51:     canvas.style.backgroundImage = "url('https://www.pahoo.org/athome/album/2014/img20150101-001454e.jpg')";
  52:     canvas.style.backgroundSize = 'cover';
  53: 
  54:     //Canvasの描画コンテキストを取得する.
  55:     var ctx = canvas.getContext('2d');
  56: 
  57:     //雪粒の数
  58:     var drops = [];
  59: //--ここまで初期設定
  60: 
  61:     //雪粒の設定
  62:     function snowDrop() {
  63:         //雪粒の初期位置をランダムに設定する.
  64:         this.x = Math.random() * canvas.width;
  65:         this.y = 0 - Math.random() * canvas.height;
  66: 
  67:         //雪粒の落下スピードを乱数で設定する.
  68:         this.speed = Math.random() * 10 + 5;
  69:         //雪粒の半径を乱数を使って設定する.
  70:         this.radius = Math.random() * 0.3 + 0.3;
  71: 
  72:         //雪粒を描画する.
  73:         this.draw = function () {
  74:             ctx.beginPath();
  75:             ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
  76:             ctx.fillStyle = 'Azure';
  77:             ctx.fill();
  78:             ctx.closePath();
  79:         }
  80:     }
  81: 
  82:     //canvasに雪粒を追加する.
  83:     function addSnowDrop() {
  84:         drops.push(new snowDrop());
  85:     }
  86: 
  87:     //雪粒の位置を更新する関数
  88:     function updateSnowDrops() {
  89:         for (var i = 0i < drops.lengthi++) {
  90:             //雪粒が落下するように見せかける.
  91:             drops[i].y +drops[i].speed;
  92:             //雪粒がcanvasの下端に達したら画面上から消す.
  93:             if (drops[i].y > canvas.height) {
  94:                 drops.splice(i, 1);
  95:                 i--;
  96:             }
  97:         }
  98:     }
  99: 
 100:     //雪粒を描画する関数
 101:     function drawSnowDrops() {
 102:         for (var i = 0i < drops.lengthi++) {
 103:             drops[i].draw();
 104:         }
 105:     }

雪粒 snowDropオブジェクトの位置を更新する――つまり、雪粒が落ちていくようにするメソッドが updateSnowDropsである。snowDropオブジェクトのプロパティ speed を参照し、Y軸方向の位置を変化させていく。雪粒が canvas要素の下端に達したら画面上から消す(配列 drops から取り除く)。

アニメーションを開始する

snowfall.html

 107:     //アニメーションを開始する関数
 108:     function startAnimation() {
 109:         setInterval(function () {
 110:             //canvasをクリアする.
 111:             ctx.clearRect(0, 0, canvas.width, canvas.height);
 112:             //雪粒を追加する.
 113:             addSnowDrop();
 114:             //雪粒の位置を更新する.
 115:             updateSnowDrops();
 116:             //雪粒を描画する
 117:             drawSnowDrops();
 118:         }, INTERVAL);
 119:     }

アニメーションを開始するメソッドが startAnimation で、冒頭で紹介した setIntervalメソッドを使って、canvas要素のクリア、雪粒の追加、位置の更新、雪粒の描画を50ミリ秒ごとに繰り返し実行する。

参考サイト

(この項おわり)
header