情報学部 菅沼ホーム JavaScript 目次 索引

JavaScript と CANVAS

  1. HTML 文書の基本構造

      HTMLHyper Text Markup Language )には,タグと呼ばれる多くの命令があり,タグによって文章を修飾(文字の大きさ・色を変える,箇条書きにする,表形式にする,等)したり,図を挿入したりすることによって,見栄えの良い文章を作成することになります.

      タグは,一般的に,

    <要素名>・・・・</要素名>

    のように書かれ,「<要素名>」を開始タグ,「</要素名>」を終了タグと呼びます.なお,要素によっては,終了タグがないものや省略しても構わないものがあります.私の Web サイトにおいても,省略可能な箇所は省略している場合が多いかと思いますが,ブラウザによってその解釈が異なる場合もあり,できる限り省略しない方が賢明かと思います.

      例えば,B 要素を使用して,
    文字を<B>太く</B>表示する			
    のように記述すると,「太く」の部分が太く表示されます.また,要素に許される属性を使用することによって,より細かな制御も可能となります.例えば,SPAN 要素の STYLE 属性を使用し,
    文字の背景を<SPAN STYLE="background-color: pink">ピンク</SPAN>にする			
    のように記述すると,「ピンク」の部分の背景色がピンクになります.

      このように,HTML ファイルにおいては,要素や属性は表示されず,その結果だけが表示されることになります.通常のテキスト文書もそのまま表示されますが,改行や複数の半角スペースは無視されます.また,「 <!-- 」と「 --> 」で囲んだ部分はコメント注釈)とみなされ,表示されません.なお,要素名や属性名は,大文字でも小文字でも構いません.

      また,HTML ファイル全体は,以下に示すような構成になります.なお,行番号は,HTML とは関係ありません.これ以降の説明についても同様です.
    01	<!DOCTYPE HTML>
    02	<HTML>
    03		<HEAD>
    04			<TITLE>HTML を理解しよう!</TITLE>
    05			<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06			<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		</HEAD>
    08		<BODY>
    09			本文の記述
    10		</BODY>
    11	</HTML>
    			
      1 行目では,HTML のバージョン情報を記述し(この場合,HTML5 であることを示す),HTML 要素で区切られた 02 ~ 11 行目が HTML ファイルの本体になります.本体は,更に,HEAD 要素で区切られ,ページ全体の制御を行うヘッダ部分と,BODY 要素で区切られ,本文を記述する部分に分かれます.

      HEAD 要素内には,多くの要素が含まれますが,最低限,ページのタイトルを示す TITLE 要素( 04 行目).及び,ページを記述している文字コードを示す META 要素( 05 行目)だけは記述しておいた方が良いと思います.なお,06 行目は,スマホやタブレットに対応するための記述です.

  2. JavaScript

    1. JavaScript の特徴と機能

        JavaScript は,インタプリータ言語です.従って,C/C++,Java などとは異なり,コンパイルすること無しにそのまま実行可能です.JavaScript では,ブラウザの各部品や情報をオブジェクトとして取り扱うことができます.さらに,このオブジェクトのプロパティ(オブジェクトの持っている属性値)やメソッド(オブジェクトに対する操作を行う関数)を使用して,オブジェクトの値や処理の手順を動的に変更することが可能です.

        オブジェクトを大きく分けると,ブラウザが本来持っている部品や情報を扱うナビゲータオブジェクトと,JavaScript 独自に組み込まれたビルトインオブジェクトに分類できます.オブジェクトは,階層構造をしており,あるオブジェクトのプロパティなどを使用するときは,たとえば,window オブジェクトの下にある document オブジェクトのプロパティを参照するためには,「window.document.プロパティ名」のように,オブジェクト間の関係を表すため,「 . 」(ピリオド)で区切って記述する必要があります.ただし,1番上の window オブジェクトは省略することが出来ます.

        JavaScript の各オブジェクトの機能をまとめると以下のようになります.

      1. ナビゲータオブジェクト: ブラウザが所有している部品を取り扱うオブジェクト

      2. ビルトインオブジェクト

      3. トップレベル関数(ビルトイン関数): 文字列の評価,数値への変換,値か否かの判定等

      4. ダイナミック HTML: 属性値や Style の動的変更

    2. JavaScript の利用方法

      1. HTML ファイル内へ記述

          HTML ファイル内に JavaScript を記述する場合は,SCRIPT 要素を使用し,
        <SCRIPT TYPE="text/javascript">
        	<!--
        		ここに,JavaScript のプログラム
        	//-->
        </SCRIPT>					
        のように記述します.なお,「<!--」と「//-->」は,JavaScript に未対応のブラウザが JavaScript のソースプログラムをコメントアウトするためです.ただし,ここで説明する内容は,JavaScript が有効でない限り意味がありませんので,必要ないと思います.

        使用例1

          以下に示すように記述すると,ページが表示されたときに JavaScript も実行されます.また,この例のように,JavaScript によって新しい Window を生成することもできます(以下の方法においても同様).

        01	<!DOCTYPE HTML>
        02	<HTML>
        03	<HEAD>
        04		<TITLE>文書内記述</TITLE>
        05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
        06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
        07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
        08	</HEAD>
        09	<BODY CLASS="white">
        10		<H1 CLASS="center">文書内記述</H1>
        11		<SCRIPT TYPE="text/javascript">
        12			document.write("JavaScript によって出力<BR>\n");
        13			alert("文書内記述");
        14			let w = window.open("", "", "width=300, height=100");
        15			w.document.open();   // 以下,生成された Window 内に記述される
        16			w.document.write('<HTML>\n');
        17			w.document.write('	<HEAD>\n');
        18			w.document.write('		<TITLE>新しい Window</TITLE>\n');
        19			w.document.write('	</HEAD>\n');
        20			w.document.write('	<BODY>\n');
        21			w.document.write('		新しい Window の生成も可能<BR>\n');
        22			w.document.write('	</BODY>\n');
        23			w.document.write('</HTML>\n');
        24			w.document.close();
        25		</SCRIPT>
        26	</BODY>
        27	</HTML>
        					
        01 行目

          HTML のバージョンであり,HTML5 であることを表しています.

        02 行目

          HTML 要素の開始タグであり,HTML ファイルの始まりを表し,それが,27 行目( HTML 要素の終了タグ)まで続くことを表しています.

        03 行目

          HEAD 要素は,HTML ファイルのヘッダーの始まりを表し,それが,08 行目まで続くことを表しています.

        04 行目

          ブラウザのタブに表示される HTML ファイルのタイトルです( TITLE 要素).ファイル毎に変更することになります.

        05 行目

          HTML ファイルを記述する文字コードを表しています.文字化けが起こらないために,必ず記述してください( META 要素).

        06 行目

          スマホやタブレットに対応するための記述です.

        07 行目

          スタイルシートファイル master.css を指定しています.スタイルシートに関しては, STYLE 要素,及び,スタイルシートを参照してください( LINK 要素).

        09 行目

          BODY 要素は,HTML ファイルの本文の始まりを表し,それが,26 行目まで続くことを表しています.CLASS 属性は,スタイルシート master.css で,BODY 要素のスタイルを指定するために使用しています.この例の場合,master.css 内において,以下のような指定を行っています.
        	body.white { background-color: white; color: black; font-size: 130% }						
        10 行目

          ページに対する説明(タイトル)です( H1 要素).この例の場合,master.css 内において,以下のような指定を行っています.
        	H1.center { font-style: italic; text-align: center }						
        11 行目

          SCRIPT 要素の開始タグであり,TYPE 属性によって,12 行目~ 24 行目が JavaScript によって記述されていることを示しています.

        12 行目

          document オブジェクトwright メソッドによって,文字列を画面上に出力することが可能です.文字列に HTML 要素が含まれている場合は,その解釈が行われた後表示されます.この文のように,JavaScript における一つの文はセミコロン「 ; 」で終わります.

        13 行目

          alert は,window オブジェクトのメソッドであり,引数で指定された文字列を表示する警告用ダイアログボックスを開きます.

        14 行目

          window オブジェクトのメソッド open によって,新しい Window を生成して,その結果(生成された Wimdow のアドレス)を変数 w に代入しています.12 行目と同様,「 window. 」の部分を省略しても構いません.

          JavaScript においても,数学と同じように,定数や様々な値を保持するための変数を使用可能です.しかし,すべての変数には「」があり,その「型」に一致した値だけをその変数に代入(記憶)可能です.そのため,C/C++,Java などにおいては,使用する変数に対して,その変数を使用する前にその変数の型を宣言しておく必要があります.しかしながら,JavaScript では,変数に対して型宣言を行う必要はありません.代入されたデータによって,自動的にその変数のが決定されます.例えば,
        	let x1 = 12345;
        	let x2;
        	var y1 = 12.5;
        	var y1;
        	z1 = 12;
        	z1;						
        のような形で変数の使用を開始すると(変数を定義すると),それ以降,その変数を使用することが出来るように(有効に,参照可能に)なります.ブロック内( { } で囲まれた部分,関数も含む)で,let を指定して定義すると,ブロック内のその変数が定義された以降で有効になります.また,関数内で,var を指定して定義すると,関数内のその変数が定義された以降で有効になります.これらの変数をローカル変数と呼びます.関数外で定義された変数,または,let や var を付加せずに定義された変数は,グローバル変数と呼ばれ,変数が定義された以降であれば,どこからでも参照可能(有効)になります.誤りの原因となりやすいので,「グローバル変数は,関数の外で let や var を付加せずに定義する,ローカル変数は,特別の理由が無い限り,var ではなく let を付加して定義する.」といった規則を守った方が良いと思います.なお,詳細については,変数の有効範囲(スコープ)を参照してください.

        15 行目~ 24 行目

          document オブジェクトの wright メソッドによって,新しく生成された Window に HTML 文章(文字列)を出力しています.なお,これらの文においては,文字列をシングルクォテーションマーク「 ' 」で囲んでいますが,ダブルクォテーションマーク「 " 」を使用しても構いません( JavaScript においては,「 ' 」と「 " 」は同等).なお,openclose は,いずれも document オブジェクトのメソッドであり,ドキュメント記述の開始と終了を表します.

          15 行目の「 // 」以降はコメントです.Java のように,「 /* 」と「 */ 」を使用したコメントも使用できます.

        使用例2

          ページが表示されたときには実行されず,マウスでクリックしたときに実行したいような場合は,以下に示す例のように,HEAD 要素の中に実行したいことを関数の形で記述しておき( 08 行目~ 13 行目),指定された箇所がクリックされると( 16 行目に示す SPAN 要素の onClick 属性),その関数が実行されるようにすることも可能です.なお,このような処理(イベント処理)の詳細については後に述べます.

        01	<!DOCTYPE HTML>
        02	<HTML>
        03	<HEAD>
        04		<TITLE>文書内記述(関数)</TITLE>
        05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
        06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
        07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
        08		<SCRIPT TYPE="text/javascript">
        09			function func()
        10			{
        11				alert("文書内記述(関数)");
        12			}
        13		</SCRIPT>
        14	</HEAD>
        15	<BODY CLASS="white">
        16		<H1 CLASS="center">文書内記述(関数)(<SPAN onClick="func()">ここをクリック</SPAN>)</H1>
        17	</BODY>
        18	</HTML>
        					

      2. 外部ファイルへ記述

        使用例3

          JavaScript の関数などを外部ファイルに記述し,それを呼び出すことも可能です.たとえば,下に示す例のように,HEAD 要素内に LINK 要素を使用して,08 行目のような記述をしておき,ファイル control.js の内容を以下のようにすれば,使用例2と同じ結果が得られます.
        function func()
        {
        	alert("外部ファイル");
        }					

        01	<!DOCTYPE HTML>
        02	<HTML>
        03	<HEAD>
        04		<TITLE>外部ファイル</TITLE>
        05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
        06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
        07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
        08		<SCRIPT TYPE="text/javascript" SRC="control.js"></SCRIPT>
        09	</HEAD>
        10	<BODY CLASS="white">
        11		<H1 CLASS="center">外部ファイル(<SPAN onClick="func()">ここをクリック</SPAN>)</H1>
        12	</BODY>
        13	</HTML>
        					

      3. HTML 要素内へ記述

        使用例4

          実行する JavaScript の命令などが少ない場合は,下に示す例のように,HTML 要素内に記述することも可能です.この例では,11 行目の SPAN 要素と 12 行目の A 要素内に記述しています.いずれの場合も,対応する箇所をクリックすると,2 つの alert 関数が順に実行されます.

        01	<!DOCTYPE HTML>
        02	<HTML>
        03	<HEAD>
        04		<TITLE>要素内記述</TITLE>
        05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
        06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
        07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
        08	</HEAD>
        09	<BODY CLASS="white">
        10		<H1 CLASS="center">要素内記述</H1>
        11		SPAN 要素  <SPAN onClick="JavaScript: alert('alert 1');alert('alert 2')">ここをクリック</SPAN><BR><BR>
        12		A 要素  <A HREF="JavaScript: alert('alert 1');alert('alert 2')">ここをクリック</A>
        13	</BODY>
        14	</HTML>
        					

  3. CANVAS 要素の利用方法

    1. アニメーション
        CANVAS 要素を使用してアニメーションを作成するためには,window オブジェクトsetInterval メソッド,または,setTimeout メソッドを使用します.ここで示すアニメーションはすべて同じものであり,半径の異なる円を順に描き,10 個の円を描き終わると再び最初から繰り返し,さらに,この繰り返しを 5 回実行すると停止します.まず,最初に,setInterval メソッドを利用した例を示します.その HTML ファイルは以下に示すとおりです.

      01	<!DOCTYPE HTML>
      02	<HTML>
      03	<HEAD>
      04		<TITLE>アニメーション1</TITLE>
      05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
      06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
      07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../../master.css">
      08		<SCRIPT TYPE="text/javascript" SRC="animation1.js"></SCRIPT>
      09	</HEAD>
      10	<BODY CLASS="eeffee" onLoad="start()">
      11		<H1>アニメーション( setInterval,CANVAS )</H1>
      12		<CANVAS ID="canvas_e" STYLE="background-color: #ffffff;" WIDTH="250" HEIGHT="150"></CANVAS>
      13	</BODY>
      14	</HTML>
      				

      08 行目

        ここで利用している JavaScript のプログラムが記述されたファイル名( animation1.js )です.

      10 行目

        onLoad 属性の指定により,ページがロードされると,ファイル animation1.js に記述されている JavaScript の関数 start が実行されます.

      12 行目

        CANVAS 要素をここに入れています.ここでは,その STYLE 属性WIDTH 属性HEIGHT 属性を利用して,アニメーションを表示する画面(キャンバス)の背景色,幅,高さを指定しています.

        ファイル animation1.js の内容は以下に示すとおりです.この内容を見ながら,少しずつ,プログラムの学習も進めていきます.

      01	count1  = 0;   // 何個の円を描いたかを示す
      02	count2  = 0;   // 10 個の円の描画を何回行ったかを示す
      03	r       = 10;   // 円の半径の初期値
      04	canvas  = null;   // キャンバス
      05	ctx     = null;   // コンテキスト
      06	timerID = -1;   // タイマー
      07				//
      08				// 開始
      09				//
      10	function start()
      11	{
      12		canvas  = document.getElementById('canvas_e');   // キャンバス要素の取得
      13		ctx     = canvas.getContext('2d');   // キャンバスからコンテキストを取得
      14		timerID = setInterval('draw()',100);
      15	}
      16				//
      17				// 描画
      18				//
      19	function draw() {
      20		count1++;
      21		if (count1 > 10) {
      22			count2++;
      23			if (count2 > 4)
      24				stop();
      25			else {
      26				r      = 10;
      27				count1 = 1;
      28				ctx.clearRect(0, 0, canvas.width, canvas.height);
      29			}
      30		}
      31		ctx.beginPath();
      32		ctx.arc(0, 0, r, Math.PI*1.5, Math.PI*2, true);
      33		ctx.stroke();
      34		r = 1.5 * r;   // r *= 1.5; でも可
      35	}
      36				//
      37				// 停止
      38				//
      39	function stop()
      40	{
      41		clearInterval(timerID);
      42		ctx.clearRect(0, 0, canvas.width, canvas.height);
      43		timerID = -1;
      44	}
      				
      01 行目~ 06 行目

        ここでは,6 つのグローバル変数の定義(変数に値の代入)を行っています.なお,これらの文のように,1 つの文の終わりには必ずセミコロン「 ; 」が必要です(「 } 」で終わる場合は必要ない).また,「 // 」の後ろから行末までは,プログラムに対するコメントとみなされ,何の処理も行われません.「 /* 」と「 */ 」で囲むことによって,複数行にわたるコメントを記述することも可能です(同じ行内でも構わない).

      10 行目~ 15 行目

        ページがロードされた時に呼ばれる関数 start の定義です.関数メソッド)に対する一般的記述方法は,
      	function 関数名 (引数, ・・・) {
      		処理
      	}					
      のようになります.関数(メソッド)は,グローバル変数及び引数を通して渡された情報に基づき,何らかの処理を行います.値を返したい(戻り値がある場合)場合は,return 文を使用します.

        この関数内では,まず,12 行目において,DOM のメソッド getElementById を使用して,ID 属性の値が canvas_e である要素を取得しています.その要素は,ここでは,HTML ファイルの 11 行目に相当,つまり,CANVAS 要素を取得していることになります.

        次に,13 行目では,CANVAS 要素のメソッド getContext を利用して,上で取得した CANVAS 要素からそのコンテキストを取得しています.コンテキストとは,CANVAS に描画する絵筆のようなものだと思ってください.

        さらに,14 行目では,setInterval メソッドによって,100 ms 毎に関数 draw を実行するように設定しています.関数 draw の定義は,19 行目~ 35 行目に記述されています.

      20 行目

        変数 count1 の値を 1 だけ増加させています. ++ は,インクリメント演算子と呼ばれ,算術演算子代入演算子を用いて,以下に示すいずれかの方法で記述しても構いません.
      	count1 += 1;
      	count1 = count1 + 1;					
      なお,「 += 」は,代入演算子と算術演算子を結合した演算子です.似たような演算子として,「 += 」以外に,「 -= 」,「 *= 」,「 /= 」など,多くの演算子が存在します.また,1 だけ減少させる演算子 -- デクリメント演算子)も存在します.

      21 行目~ 30 行目

        異なる半径の円を 10 個以上描いた場合の処理です.if 文は,そのときの状況により実行の順序を変化させるための文であり,
      	if (論理式) {
      		文1(複数の文も可)
      	}
      	else {
      		文2(複数の文も可)
      	}
      	・・・・・・					
      のような形式で記述されます.まず,論理式が評価され,その結果が真であれば,文1が実行され,次に,「・・・」以降に書かれた文が実行されます.この場合は,文2は実行されないことになります.また,偽である場合は,文1は実行されず,文2が実行された後,真の場合と同様,「・・・」以降に書かれた文が実行されます.なお,if 文において,真に対応する部分(文1)は必ず必要ですが,偽に対応する部分( else 以下)は,必ずしも必要ありません.また,文1や文2が 1 文だけの時は,「 { 」と「 } 」は必要ありません.

        論理式は,計算結果として真または偽( true または false )を返す文であり,関係演算子,等値演算子,論理演算子などが使用されます.ここでは,count1 の値が 10 より大きい場合,22 行目から 29 行目までが実行されます.

        なお,JavaScript で使用できる関係演算子には,以下のようなものがあります.
      	>  より大きい  a > b   式 a の値が式 b の値より大きいとき真
      	<  より小さい  a < b   式 a の値が式 b の値より小さいとき真
      	>= 以上     a >= b  式 a の値が式 b の値以上のとき真
      	<= 以下     a <= b  式 a の値が式 b の値以下のとき真					
      また,等値演算子には,以下のようなものがあります.
      	== 等しい    a == b  式 a の値と式 b の値が等しいとき真
      	=== 等しい    a == b  式 a と式 b の型と値が等しいとき真
      	!= 等しくない  a != b  式 a の値と式 b の値が等しくないとき真
      	!== 等しくない  a != b  式 a と式 b の型か値が等しくないとき真					
      論理演算子は,論理演算(論理和,論理積,否定)を行うための演算子であり,以下のようなものがあります.
      	|| 論理和  x || y  式 x が真か,または,式 y が真のとき真
      	&& 論理積  x && y  式 x が真で,かつ,式 y が真のとき真
      	!  否定    ! x      式 x が偽のとき真					
      23 行目~ 24 行目

        円を描く繰り返しが 5 回以上になった場合,アニメーションを停止する関数 stop を呼んでいます.関数 stop の定義は,39 行目~ 44 行目に記述されています.

      25 行目~ 29 行目

        円を描く繰り返しが 5 回未満である場合の処理です.円の半径を初期状態に戻し( 26 行目),描いた円の数を数えるカウンタ count1 を 1 に設定し( 27 行目),さらに,今まで描いた図形を削除するため,clearRect メソッドによって指定した矩形部分をクリアしています( 28 行目,この例の場合は,キャンバスの全領域をクリア).

      31 行目

        beginPath は,現在のサブパスをリセットするメソッドです.

      32 行目

        arc は,円弧を描くメソッドであり,円弧に対応したサブパスを生成します.この場合は,原点( CANVAS 要素によって生成された矩形の左上が原点 (0, 0),その右側が x 軸の正方向,下側が y 軸の正方向となる,右図参照)を中心に,半径 r の円の 1 / 4 に対応する円弧を生成します.なお,PI は,ビルトインオブジェクトの一つである Math オブジェクトのプロパティであり,π の値を表します.

      33 行目

        stroke は,作成したサブパスの輪郭を表示するメソッドです.この例の場合,31 行目~ 33 行目によって,一つの円弧が描かれることになります.

      34 行目

        円の半径を 1.5 倍にしています.

      41 行目

        clearInterval は,window オブジェクトのメソッドであり,setInterval で開始したタイマーを停止するメソッドです.

        上に示した例においては,HTML ファイル内に CANVAS 要素を設けておき,その属性として,キャンバスの背景色,幅,高さを設定しましたが,次に述べる例においては,HTML ファイル内ではキャンバスが入る DIV 要素を設定しておき,JavaScript のプログラムでその中に CANVAS 要素を埋め込んでいます.まず,HTML ファイルは以下に示すとおりです.先の例とは,08 行目のファイル名と 12 行目だけが異なっています.

      01	<!DOCTYPE HTML>
      02	<HTML>
      03	<HEAD>
      04		<TITLE>アニメーション2</TITLE>
      05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
      06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
      07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../../master.css">
      08		<SCRIPT TYPE="text/javascript" SRC="animation2.js"></SCRIPT>
      09	</HEAD>
      10	<BODY CLASS="eeffee" onLoad="start()">
      11		<H1>アニメーション( setInterval,DIV )</H1>
      12		<DIV ID="canvas_e"></DIV>
      13	</BODY>
      14	</HTML>
      				

        ファイル animation2.js の内容は以下に示すとおりです.12 行目~ 17 行目だけが異なっています.その内容は,コメント(「 // 」の後ろの部分)から明らかだと思います.createElement メソッドも appendChild メソッドも,getElementById メソッドと同様,DOM のメソッドです.また,14 行目~ 16 行目では,DOM を利用して,CANVAS 要素の属性値を設定しています(上の例における HTML ファイルの 11 行目で設定した内容).

      01	count1  = 0;   // 何個の円を描いたかを示す
      02	count2  = 0;  // 10 個の円の描画を何回行ったかを示す
      03	r       = 10;   // 円の半径の初期値
      04	canvas  = null;   // キャンバス
      05	ctx     = null;   // コンテキスト
      06	timerID = -1;   // タイマー
      07				//
      08				// 開始
      09				//
      10	function start()
      11	{
      12		let area = document.getElementById("canvas_e");   // キャンバスを挿入する場所
      13		canvas   = document.createElement("canvas");   // キャンバス要素を生成
      14		canvas.style.backgroundColor = "#ffffff";   // キャンバスの背景色
      15		canvas.width  = 250;   // キャンバス要素の幅
      16		canvas.height = 150;   // キャンバス要素の高さ
      17		area.appendChild(canvas);   // キャンバス要素を追加
      18		ctx     = canvas.getContext('2d');   // キャンバスからコンテキストを取得
      19		timerID = setInterval('draw()',100);
      20	}
      21				//
      22				// 描画
      23				//
      24	function draw() {
      25		count1++;
      26		if (count1 > 10) {
      27			count2++;
      28			if (count2 > 4)
      29				stop();
      30			else {
      31				r      = 10;
      32				count1 = 1;
      33				ctx.clearRect(0, 0, canvas.width, canvas.height);
      34			}
      35		}
      36		ctx.beginPath();
      37		ctx.arc(0, 0, r, Math.PI*1.5, Math.PI*2, true);
      38		ctx.stroke();
      39		r = 1.5 * r;
      40	}
      41				//
      42				// 停止
      43				//
      44	function stop()
      45	{
      46		clearInterval(timerID);
      47		ctx.clearRect(0, 0, canvas.width, canvas.height);
      48		timerID = -1;
      49	}
      				

        次に,同じアニメーションに対して,setTimeout メソッドを使用してみます.HTML ファイルの内容は,JavaScript のファイル名を変えてあるだけで,最初の例と全く同じです.また,JavaScript のファイル内容は以下に示すとおりです.

        14 行目を見てください.setTimeout メソッドは,設定した時間(この例の場合は,100 ms )が経過すると,設定した関数(この例の場合は,draw )を実行するメソッドです.100 ms 毎に繰り返し実行されるわけではありません.そのため,draw 関数の中で,一端,タイマーをクリアした( 35 行目)後,再度 setTimeout を呼ぶ( 36 行目)ことによって繰り返し処理を実現しています.

      01	count1  = 0;   // 何個の円を描いたかを示す
      02	count2  = 0;   // 10 個の円の描画を何回行ったかを示す
      03	r       = 10;   // 円の半径の初期値
      04	canvas  = null;   // キャンバス
      05	ctx     = null;   // コンテキスト
      06	timerID = -1;   // タイマー
      07				//
      08				// 開始
      09				//
      10	function start()
      11	{
      12		canvas  = document.getElementById('canvas_e');   // キャンバス要素の取得
      13		ctx     = canvas.getContext('2d');   // キャンバスからコンテキストを取得
      14		timerID = setTimeout("draw()", 100);
      15	}
      16				//
      17				// 描画
      18				//
      19	function draw() {
      20		count1++;
      21		if (count1 > 10) {
      22			count2++;
      23			if (count2 > 4)
      24				stop();
      25			else {
      26				r      = 10;
      27				count1 = 1;
      28				ctx.clearRect(0, 0, canvas.width, canvas.height);
      29			}
      30		}
      31		ctx.beginPath();
      32		ctx.arc(0, 0, r, Math.PI*1.5, Math.PI*2, true);
      33		ctx.stroke();
      34		r = 1.5 * r;
      35		clearTimeout(timerID);
      36		timerID = setTimeout("draw()", 100);
      37	}
      38				//
      39				// 停止
      40				//
      41	function stop()
      42	{
      43		clearTimeout(timerID);
      44		ctx.clearRect(0, 0, canvas.width, canvas.height);
      45		timerID = -1;
      46	}
      				

    2. イベント処理
        「マウスをクリックした」,「キーを押した」などの事象をイベントと言い,イベントが生じたときに行う処理をイベント処理と呼びます.今までも,HTML 要素の onLoad 属性onClick 属性を利用してイベント処理を行ってきましたが,アニメーションを作成する場合も,様々なイベントに対する処理が必要になります.ここでは,イベント処理の方法についてもう少し詳しく説明します.ここで使用するアニメーションは,外部画像を読み込み,その表示位置を時間と共に変化させることによって実現しています.まず,最初に示す例は,HTML の BUTTON 要素を使用する方法です.HTML ファイルの内容は以下に示すとおりです.12 行目において,BUTTON 要素の onClick 属性を使用して,「開始」ボタンをクリックすると関数 start が,また,「停止」ボタンをクリックすると関数 stop を実行するように設定しています.

      01	<!DOCTYPE HTML>
      02	<HTML>
      03	<HEAD>
      04		<TITLE>イベント1</TITLE>
      05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
      06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
      07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../../master.css">
      08		<SCRIPT TYPE="text/javascript" SRC="event1.js"></SCRIPT>
      09	</HEAD>
      10	<BODY CLASS="eeffee" onLoad="animation()">
      11		<H1>イベント処理(その1)</H1>
      12		<BUTTON STYLE="font-size:90%" onClick="start()">開始</BUTTON> <BUTTON STYLE="font-size:90%" onClick="stop()">停止</BUTTON><BR><BR>
      13		<CANVAS ID="canvas_e" STYLE="background-color: #ffffff;" WIDTH="400" HEIGHT="300"></CANVAS>
      14	</BODY>
      15	</HTML>
      				

        また,JavaScript のプログラムは以下に示すとおりです.

      01	x       = 0;   // 画像(円の中心)の位置( x 軸)
      02	y       = 0;   // 画像(円の中心)の位置( y 軸)
      03	v       = 0;   // 画像の移動速度
      04	canvas  = null;   // キャンバス
      05	ctx     = null;   // コンテキスト
      06	img     = null;   // 画像
      07	timerID = -1;   // タイマー
      08				//
      09				// 開始
      10				//
      11	function animation()
      12	{
      13		canvas  = document.getElementById('canvas_e');   // キャンバス要素の取得
      14		ctx     = canvas.getContext('2d');   // キャンバスからコンテキストを取得
      15		img     = new Image();
      16		img.src = "ball.gif";
      17		x       = 0;   // 円の中心の座標( x )
      18		y       = canvas.height / 2;   // 円の中心の座標( y )
      19		timerID = setInterval('draw()',100);
      20	}
      21				//
      22				// 描画
      23				//
      24	function draw() {
      25		x += v;
      26		ctx.clearRect(0, 0, canvas.width, canvas.height);
      27		ctx.drawImage(img, x-40, y-40);
      28	}
      29				//
      30				// 開始
      31				//
      32	function start()
      33	{
      34		v = 5;
      35	}
      36				//
      37				// 停止
      38				//
      39	function stop()
      40	{
      41		v = 0;
      42	}
      				
      15,16 行目

        window.document オブジェクト内の image オブジェクトを利用して,画像を読み込んでいます.この様に,オブジェクトのインスタンスを生成する際には,new 演算子を使用します.

      17,18 行目

        画像の描画位置であり,ここで設定された値がその初期位置になります.

      24 行目~ 28 行目

        定期的に実行される関数 draw の定義です.位置を変化させ( 25 行目),画面をクリア( 26 行目)し,drawImage メソッドによって画像を描画( 27 行目)しています.v の値(移動速度)は,ボタンのクリックによって,34 行目,または,41 行目によって変化します.

        上の方法ですと,「画面のどこかをクリックした場合に~する」といったような処理を行えません.次の例では,描かれた画像をクリックすることによって,動いたり停止したりする動作を実現しています.従って,上の例のようなボタンは使用していません.HTML ファイルは,先の例における 12 行目を削除しただけです.また,JavaScript のプログラムはその下に示すとおりです.

      01	x       = 0;   // 画像(円の中心)の位置( x 軸)
      02	y       = 0;   // 画像(円の中心)の位置( y 軸)
      03	v       = 0;   // 画像の移動速度
      04	canvas  = null;   // キャンバス
      05	ctx     = null;   // コンテキスト
      06	img     = null;   // 画像
      07	timerID = -1;   // タイマー
      08	x_base  = -1;   // Window上に置けるキャンバスの位置(左上のx座標)
      09	y_base  = -1;   // Window上に置けるキャンバスの位置(左上のy座標)
      10				//
      11				// 開始
      12				//
      13	function animation()
      14	{
      15		canvas  = document.getElementById('canvas_e');   // キャンバス要素の取得
      16		ctx     = canvas.getContext('2d');   // キャンバスからコンテキストを取得
      17		img     = new Image();
      18		img.src = "ball.gif";
      19		x_base  = canvas.offsetLeft;   // キャンバスの左上のx座標
      20		y_base  = canvas.offsetTop;   // キャンバスの左上のy座標
      21		x       = 0;   // 円の中心の座標( x )
      22		y       = canvas.height / 2;   // 円の中心の座標( y )
      23		canvas.addEventListener("click", Click, false);   // クリックイベント
      24		timerID = setInterval('draw()',100);
      25	}
      26				//
      27				// 描画
      28				//
      29	function draw() {
      30		x += v;
      31		ctx.clearRect(0, 0, canvas.width, canvas.height);
      32		ctx.drawImage(img, x-40, y-40);
      33	}
      34				//
      35				// 円がクリックされた時の処理
      36				//
      37	function Click(event)
      38	{
      39		let x_now = event.pageX - x_base;
      40		let y_now = event.pageY - y_base;
      41		let x1 = x - x_now;
      42		let y1 = y - y_now;
      43		let r  = Math.sqrt(x1 * x1 + y1 * y1);
      44		if (r < 40) {
      45			if (v > 0)
      46				v = 0;
      47			else
      48				v = 5;
      49		}
      50	}
      				
      19,20 行目

        後ほど,マウスがクリックされた位置を特定したいのですが,マウスがクリックした時に得られる座標は Window を基準としています.そこで,キャンバスの左上の座標 offsetLeft, offsetTop をこれらの変数に代入しておき,キャンパス上の座標を得るために使用します.

      23 行目

        キャンバスに,マウスクリックに対応できるようにイベントリスナを追加しています.この行により,キャンバス上でマウスクリックを行うと,Click メソッド( 37 行目~ 50 行目)が呼ばれます.なお,2 番目の引数であるメソッド名としては,任意の名前が許されます(もちろん,37 行目~ 50 行目との対応関係が必要).

      39,40 行目

        event オブジェクトのプロパティ pageXpageY から得られた座標(マウスがクリックされた位置)を,キャンバス上の相対座標に変換しています.

      41 行目~ 49 行目

        Math オブジェクトsqrt メソッドを使用し,マウスでクリックされた場所と円の中心までの距離( r,43 行目)を計算した後,その値が円の半径( 40 )以内であれば,円の移動速度を変化させています.

        上の例では,イベントの処理を行うメソッド Click を,addEventListener とは別の場所に記述しましたが,次の例のように,addEventListener の中に記述することも可能です.

      x       = 0;   // 画像(円の中心)の位置( x 軸)
      y       = 0;   // 画像(円の中心)の位置( y 軸)
      v       = 0;   // 画像の移動速度
      canvas  = null;   // キャンバス
      ctx     = null;   // コンテキスト
      img     = null;   // 画像
      timerID = -1;   // タイマー
      x_base  = -1;   // Window上に置けるキャンバスの位置(左上のx座標)
      y_base  = -1;   // Window上に置けるキャンバスの位置(左上のy座標)
      			//
      			// 開始
      			//
      function animation()
      {
      	canvas  = document.getElementById('canvas_e');   // キャンバス要素の取得
      	ctx     = canvas.getContext('2d');   // キャンバスからコンテキストを取得
      	img     = new Image();
      	img.src = "ball.gif";
      	x_base  = canvas.offsetLeft;   // キャンバスの左上のx座標
      	y_base  = canvas.offsetTop;   // キャンバスの左上のy座標
      	x       = 0;   // 円の中心の座標( x )
      	y       = canvas.height / 2;   // 円の中心の座標( y )
      					// クリックイベント
      	canvas.addEventListener("click", function(event) {
      		let x_now = event.pageX - x_base;
      		let y_now = event.pageY - y_base;
      		let x1 = x - x_now;
      		let y1 = y - y_now;
      		let r  = Math.sqrt(x1 * x1 + y1 * y1);
      		if (r < 40) {
      			if (v > 0)
      				v = 0;
      			else
      				v = 5;
      		}
      	}, false);
      	timerID = setInterval('draw()',100);
      }
      			//
      			// 描画
      			//
      function draw() {
      	x += v;
      	ctx.clearRect(0, 0, canvas.width, canvas.height);
      	ctx.drawImage(img, x-40, y-40);
      }
      				

情報学部 菅沼ホーム JavaScript 目次 索引