情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引

イベント処理

  1. マウスクリック

      イベント処理に対する最も簡単な方法は,BUTTON 要素などにイベント処理属性を記述する方法です.この例では,BUTTON 要素onClick 属性を付加してイベント処理を実現しています.
    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">
    09			x      = 70;
    10			y      = 65;
    11			canvas = null;
    12			ctx    = null;
    13	
    14			function draw() {
    15				canvas = document.getElementById('canvas_e');
    16				canvas.width  = 270;   // キャンバス要素の幅
    17				canvas.height = 130;   // キャンバス要素の高さ
    18				ctx = canvas.getContext('2d');
    19						// 矩形(左)
    20				ctx.lineWidth = 5;
    21				ctx.beginPath();
    22				ctx.strokeRect(20, 15, 100, 100);
    23				ctx.stroke();
    24						// 矩形(右)
    25				ctx.beginPath();
    26				ctx.strokeRect(150, 15, 100, 100);
    27				ctx.stroke();
    28						// 塗りつぶした円
    29				ctx.beginPath();
    30				ctx.fillStyle = "rgb(0, 255, 0)";
    31				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    32				ctx.fill();
    33			}
    34						// マウスのクリック
    35			function Click()
    36			{
    37				if (x < 100) {
    38					ctx.clearRect(25, 20, 90, 90);
    39					x = 200;
    40				}
    41				else {
    42					ctx.clearRect(155, 20, 90, 90);
    43					x = 70;
    44				}
    45				ctx.beginPath();
    46				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    47				ctx.fill();
    48			}
    49		</SCRIPT>
    50	</HEAD>
    51	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    52		<H1>マウスクリック(その1)</H1>
    53		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="270" HEIGHT="130"></CANVAS><BR><BR>
    54		<BUTTON STYLE="font-size: 90%" onClick="Click()">移動</BUTTON>
    55	</BODY>
    56	</HTML>
    			
    54 行目

      このボタンをクリックすると,onClick 属性に記述された関数 Click( 35 行目~ 48 行目)が呼ばれます.

    09 行目~ 12 行目

      x,y は円の中心座標です.今までは,変数 canvas や ctx を関数 draw 内で定義していましたが,これらの変数は,他の関数からも参照されるため,この位置(関数の外側)にグローバル変数として定義しておく必要があります.

    37 行目~ 40 行目

      円が左側の矩形内に存在する場合に対する処理です.矩形内をクリアし,円の中心座標を変更しています.

    41 行目~ 44 行目

      円が右側の矩形内に存在する場合に対する処理であり,上と同様の処理を行います.

    45 行目~ 47 行目

      塗りつぶした円を描いています.

      しかし,上に述べた方法は,CANVAS 内の特定の場所をクリックしたときだけイベント処理を行いたいような場合には使用できません.この例では,DOM のメソッド addEventListener を使用して,マウスクリックイベントに対応しています.矩形内部の円をクリックすると,イベントが発生し,Click メソッドが呼び出されます(円を左から右,又は,右から左に移動).
    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">
    09			x      = 70;
    10			y      = 65;
    11			canvas = null;
    12			ctx    = null;
    13			x_base = -1;
    14			y_base = -1;
    15	
    16			function draw() {
    17				canvas = document.getElementById('canvas_e');
    18				canvas.width  = 270;   // キャンバス要素の幅
    19				canvas.height = 130;   // キャンバス要素の高さ
    20				ctx = canvas.getContext('2d');
    21				x_base = canvas.offsetLeft;   // キャンバスの左上のx座標
    22				y_base = canvas.offsetTop;   // キャンバスの左上のy座標
    23				canvas.addEventListener("click", Click, false);   // クリックイベント
    24						// 矩形(左)
    25				ctx.lineWidth = 5;
    26				ctx.beginPath();
    27				ctx.strokeRect(20, 15, 100, 100);
    28				ctx.stroke();
    29						// 矩形(右)
    30				ctx.beginPath();
    31				ctx.strokeRect(150, 15, 100, 100);
    32				ctx.stroke();
    33						// 塗りつぶした円
    34				ctx.beginPath();
    35				ctx.fillStyle = "rgb(0, 255, 0)";
    36				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    37				ctx.fill();
    38			}
    39						// マウスのクリック
    40			function Click(event)
    41			{
    42				let x_now = event.pageX - x_base;
    43				let y_now = event.pageY - y_base;
    44				let x1 = x - x_now;
    45				let y1 = y - y_now;
    46				let r  = Math.sqrt(x1 * x1 + y1 * y1);
    47				if (r < 40) {
    48					if (x < 100) {
    49						ctx.clearRect(25, 20, 90, 90);
    50						x = 200;
    51					}
    52					else {
    53						ctx.clearRect(155, 20, 90, 90);
    54						x = 70;
    55					}
    56					ctx.beginPath();
    57					ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    58					ctx.fill();
    59				}
    60			}
    61		</SCRIPT>
    62	</HEAD>
    63	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    64		<H1>マウスクリック(その2)</H1>
    65		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="270" HEIGHT="130"></CANVAS>
    66	<!--  addEventListener を使用せず,以下のように記述しても良い
    67		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="270" HEIGHT="130" onClick="Click(event)"></CANVAS>
    68	-->
    69	</BODY>
    70	</HTML>
    			
    13 行目~ 14 行目

      Window の左上を原点とした座標系におけるキャンバスの位置(キャンバスの左上の座標 : (offsetLeft, offsetTop) )を保存するための変数です.21 行目~ 22 行目において設定しています.

    23 行目

      EventListener を追加しています.この記述により,キャンバス上でマウスをクリックすると関数 Click が呼ばれます.この行の代わりに,67 行目の記述でも可能です.

    42 行目~ 43 行目

      マウスをクリックした位置 ( pageX, pageY ) は,Window の左上を原点とした座標系で表現されるため,それを,キャンバスの左上を原点とした座標系に変換しています.

    44 行目~ 59 行目

      マウスをクリックした点と円の中心までの距離 r を計算し,その値が円の半径( 40 )より小さい場合(円がクリックされた場合)に以下に記述された移動処理を行います.47 行目の if 文に対応する else 文が存在しないため,r の値が 40 以上の時は何も実行されません.なお,sqrt は,Math オブジェクトのメソッドであり,引数で与えられたデータの平方根を計算して返します.

    66 行目~ 68 行目

      「 <!-- 」と「 --> 」で囲まれた部分は,コメントとみなされ,画面に表示されません.

  2. ドラッグ

      ドラッグも,同様の方法で簡単に実現できます.この例では,円にマウスカーソルを合わせてドラッグすると,円を移動することができます.
    001	<!DOCTYPE HTML>
    002	<HTML>
    003	<HEAD>
    004		<TITLE>ドラッグ</TITLE>
    005		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    006		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    007		<LINK REL="stylesheet" TYPE="text/css" HREF="../../../../master.css">
    008		<SCRIPT TYPE="text/javascript">
    009			x      = 70;
    010			y      = 65;
    011			x_s    = 70;
    012			y_s    = 65;
    013			canvas = null;
    014			ctx    = null;
    015			x_base = -1;
    016			y_base = -1;
    017			drag   = false;
    018	
    019			function draw() {
    020				canvas = document.getElementById('canvas_e');
    021				canvas.width  = 270;   // キャンバス要素の幅
    022				canvas.height = 130;   // キャンバス要素の高さ
    023				ctx = canvas.getContext('2d');
    024				x_base = canvas.offsetLeft;   // キャンバスの左上のx座標
    025				y_base = canvas.offsetTop;   // キャンバスの左上のy座標
    026						// 矩形(左)
    027				ctx.lineWidth = 5;
    028				ctx.beginPath();
    029				ctx.strokeRect(20, 15, 100, 100);
    030				ctx.stroke();
    031						// 矩形(右)
    032				ctx.beginPath();
    033				ctx.strokeRect(150, 15, 100, 100);
    034				ctx.stroke();
    035						// 塗りつぶした円
    036				ctx.beginPath();
    037				ctx.fillStyle = "rgb(0, 255, 0)";
    038				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    039				ctx.fill();
    040			}
    041						// マウス移動イベント
    042			function Move(event, sw = 0)
    043			{
    044				if (drag) {
    045					ctx.clearRect(0, 0, canvas.width, canvas.height);
    046						// 矩形(左)
    047					ctx.lineWidth = 5;
    048					ctx.beginPath();
    049					ctx.strokeRect(20, 15, 100, 100);
    050					ctx.stroke();
    051						// 矩形(右)
    052					ctx.beginPath();
    053					ctx.strokeRect(150, 15, 100, 100);
    054					ctx.stroke();
    055						// 塗りつぶした円
    056					let x_now = 0;
    057					let y_now = 0;
    058					if (sw > 0) {
    059						event.preventDefault();
    060						x_now = x + event.changedTouches[0].pageX - x_s;
    061						y_now = y + event.changedTouches[0].pageY - y_s;
    062					}
    063					else {
    064						x_now = x + event.pageX - x_s;
    065						y_now = y + event.pageY - y_s;
    066					}
    067					ctx.beginPath();
    068					ctx.fillStyle = "rgb(0, 255, 0)";
    069					ctx.arc(x_now, y_now, 40, 0, 2*Math.PI, false);
    070					ctx.fill();
    071				}
    072			}
    073						// マウスボタン押下イベント
    074			function Down(event, sw = 0)
    075			{
    076				let x_now = 0;
    077				let y_now = 0;
    078				if (sw > 0) {
    079					x_now = event.changedTouches[0].pageX - x_base;
    080					y_now = event.changedTouches[0].pageY - y_base;
    081				}
    082				else {
    083					x_now = event.pageX - x_base;
    084					y_now = event.pageY - y_base;
    085				}
    086				let x1 = x - x_now;
    087				let y1 = y - y_now;
    088				let r  = Math.sqrt(x1 * x1 + y1 * y1);
    089				if (r < 40) {
    090					drag = true;
    091					if (sw > 0) {
    092						x_s = event.changedTouches[0].pageX;
    093						y_s = event.changedTouches[0].pageY;
    094					}
    095					else {
    096						x_s = event.pageX;
    097						y_s = event.pageY;
    098					}
    099				}
    100			}
    101						// マウスボタン離されたイベント
    102			function Up(event, sw = 0)
    103			{
    104				if (drag) {
    105					if (sw > 0) {
    106						x += (event.changedTouches[0].pageX - x_s);
    107						y += (event.changedTouches[0].pageY - y_s);
    108					}
    109					else {
    110						x += (event.pageX - x_s);
    111						y += (event.pageY - y_s);
    112					}
    113					drag = false;   // ドラッグ終了
    114				}
    115			}
    116		</SCRIPT>
    117	</HEAD>
    118	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    119		<H1>ドラッグ</H1>
    120		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="270" HEIGHT="130" onMouseMove="Move(event, 0)" onTouchMove="Move(event, 1)" onMouseDown="Down(event, 0)" onTouchStart="Down(event, 1)" onMouseUp="Up(event, 0)" onTouchEnd="Up(event, 1)"></CANVAS>
    121	</BODY>
    12	</HTML>
    			
    011 行目~ 012 行目

      マウスボタンが押し下げられたとき(ドラッグが始まったとき)の Window の左上を原点とした座標系におけるマウスの位置です.

    017 行目

      ドラッグが始まると true に,また,ドラッグが終了すると false に設定されます.つまり,ドラッグ中か否かを表す変数です.

    042 行目~ 072 行目

      ドラッグ中の場合,キャンバス領域をクリアした後,2 つの矩形と円を描画します.円の位置は,移動に伴って変化していきます( 058 行目~ 066 行目).sw が正の場合は,スマホ等に対する処理です.059 行目では,デフォルトのイベントを禁止しています(この例の場合は,必ずしも必要としない).スマホ等の場合,指の位置が配列 changedTouches に入っており,changedTouches[0] は,1 本指で操作する場合に相当します.

    074 行目~ 100 行目

      円内でマウスボタンが押し下げられた場合は,変数 drag を true に設定し,現在のマウス位置を変数 x_s,y_s に保存しています.

    102 行目~ 115 行目

      ドラッグ中であった場合は,円の位置を現在のマウスの位置に設定し,ドラッグを終了します.ドラッグ中には,移動に伴って矩形や円が再描画されています(関数 Move )ので,円が描画されている位置と現在のマウスの位置はほとんど同じはずです.

    120 行目

      CANVAS 要素を定義し,そこに,イベント属性を追加しています.これらの記述により,マウスが移動中は関数 Move( 042 行目~ 072 行目),マウスボタンが押し下げられたときは関数 Down( 074 行目~ 100 行目),また,マウスボタンが離されたときは関数 Up( 102 行目~ 115 行目)が呼ばれます.なお,onTouchMove,onTouchStart,及び,onTouchEnd は,スマホやタブレットに対応するための処理です.

  3. キーイベント

      最後に,キーイベントについて説明します.この例においては,n キーを押すと,円の位置が変化します.
    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>キーイベント( n キー)</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			x      = 70;
    10			y      = 65;
    11			canvas = null;
    12			ctx    = null;
    13	
    14			function draw() {
    15				canvas = document.getElementById('canvas_e');
    16				canvas.width  = 270;   // キャンバス要素の幅
    17				canvas.height = 130;   // キャンバス要素の高さ
    18				ctx = canvas.getContext('2d');
    19				canvas.addEventListener("keydown", KeyDown, false);   // キーが押された時
    20						// 矩形(左)
    21				ctx.lineWidth = 5;
    22				ctx.beginPath();
    23				ctx.strokeRect(20, 15, 100, 100);
    24				ctx.stroke();
    25						// 矩形(右)
    26				ctx.beginPath();
    27				ctx.strokeRect(150, 15, 100, 100);
    28				ctx.stroke();
    29						// 塗りつぶした円
    30				ctx.beginPath();
    31				ctx.fillStyle = "rgb(0, 255, 0)";
    32				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    33				ctx.fill();
    34			}
    35						// キーが押されたとき
    36			function KeyDown(event)
    37			{
    38				if (event.keyCode == 78) {   // 「n」キー
    39					if (x < 100) {
    40						ctx.clearRect(25, 20, 90, 90);
    41						x = 200;
    42					}
    43					else {
    44						ctx.clearRect(155, 20, 90, 90);
    45						x = 70;
    46					}
    47					ctx.beginPath();
    48					ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    49					ctx.fill();
    50				}
    51			}
    52		</SCRIPT>
    53	</HEAD>
    54	<BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    55		<H1>キーイベント( n キー)</H1>
    56		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="270" HEIGHT="130" TABINDEX="1"></CANVAS>
    57	</BODY>
    58	</HTML>
    			
    19 行目

      EventListener を追加しています.この処理により,キーが押されると関数 KeyDown( 36 行目~ 51 行目)が呼ばれます.

    36 行目~ 51 行目

      押されたキーが「 n 」キー(キーコードが 78 )であった場合は,移動処理を実行します.

    56 行目

      TABINDEX 属性の記述を忘れないで下さい.

  4. もう一つの例

      この例では,円をマウスでクリックしても,n キーを押しても,円が移動するようにしています.
    <!DOCTYPE HTML>
    <HTML>
    <HEAD>
    	<TITLE>マウスクリックとキーイベント</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    	<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    	<SCRIPT TYPE="text/javascript">
    		x      = 70;
    		y      = 65;
    		canvas = null;
    		ctx    = null;
    		x_base = -1;
    		y_base = -1;
    
    		function draw() {
    			canvas = document.getElementById('canvas_e');
    			canvas.width  = 270;   // キャンバス要素の幅
    			canvas.height = 130;   // キャンバス要素の高さ
    			ctx = canvas.getContext('2d');
    			x_base = canvas.offsetLeft;   // キャンバスの左上のx座標
    			y_base = canvas.offsetTop;   // キャンバスの左上のy座標
    			canvas.addEventListener("click", Click, false);   // クリックイベント
    			canvas.addEventListener("keydown", KeyDown, false);   // キーが押された時
    					// 矩形(左)
    			ctx.lineWidth = 5;
    			ctx.beginPath();
    			ctx.strokeRect(20, 15, 100, 100);
    			ctx.stroke();
    					// 矩形(右)
    			ctx.beginPath();
    			ctx.strokeRect(150, 15, 100, 100);
    			ctx.stroke();
    					// 塗りつぶした円
    			ctx.beginPath();
    			ctx.fillStyle = "rgb(0, 255, 0)";
    			ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    			ctx.fill();
    		}
    					// マウスのクリック
    		function Click(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 (x < 100) {
    					ctx.clearRect(25, 20, 90, 90);
    					x = 200;
    				}
    				else {
    					ctx.clearRect(155, 20, 90, 90);
    					x = 70;
    				}
    				ctx.beginPath();
    				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    				ctx.fill();
    			}
    		}
    					// キーが押されたとき
    		function KeyDown(event)
    		{
    			if (event.keyCode == 78) {   // 「n」キー
    				if (x < 100) {
    					ctx.clearRect(25, 20, 90, 90);
    					x = 200;
    				}
    				else {
    					ctx.clearRect(155, 20, 90, 90);
    					x = 70;
    				}
    				ctx.beginPath();
    				ctx.arc(x, y, 40, 0, 2*Math.PI, false);
    				ctx.fill();
    			}
    		}
    	</SCRIPT>
    </HEAD>
    <BODY CLASS="white" STYLE="text-align: center" onLoad="draw()">
    	<H1>マウスクリックとキーイベント</H1>
    	<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="270" HEIGHT="130" TABINDEX="1"></CANVAS>
    </BODY>
    </HTML>
    			

情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引