Back to Top
Room A
WEB - HTML
  • Twitter
  • Facebook
  • Pinterest
  • Hatena
  • instagram
  • YouTube

map + area + excanvas.js で RollOver効果/Ver.2.0(複数要素対応板)

Ver.1.0 では、1ページに1つの<map>要素が存在する場合のみに対応していますが、実際にサイトを構築する場合は、複数の異なるベース画像を使い、複数の<map>要素が1ページ内に混在するケースの方が多いと思います。

Ver.2.0では1ページに複数の<map>要素が存在してもRollOver効果が得られる様、Ver.1.0に手を加えています。JavaScripでの処理部分が長くなるので、別ファイル(map2canvas.js)にして呼び出しています。
※Ver.1.0と同じく HTML4.01 でも動作すると思いますが未検証です。

複数要素対応版

HTML5では、<canvas>が標準でサポートされる事がほぼ確実なので excanvas.js は必要ありません。(IE8など、HTML5に対応していないブラウザもブラウジング対象にする場合は必要)

map_area_2.html : Sample Code


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>CANVAS TEST for MAP+AREA Ver.2</title>
<script type="text/javascript" src="map2canvas.js" ></script>
<!--[if lte IE 8]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
</head>
 
<body>
<h1>&lt;map&gt; + &lt;area&gt; + excanvas.js で RollOver効果/Ver.2.0</h1>
<h2>::: 1 on Nx :::</h2>
<h3>&lt;map&gt;画像1</h3>
<div id="plan_F1">
<img src="planA.png" alt="MasterPlan" width="600" height="600" border="0" usemap="#Map1" id="floor1" name="floor1" />
<map name="Map1" id="Map1">
<area shape="poly" coords="16,16,266,16,266,200,200,200,200,383,16,383" href="#" alt="room 1" title="Room No.1" />
<area shape="poly" coords="283,16,583,16,583,267,401,267,401,200,283,200" href="#" alt="room 2" title="Room No.2" />
<area shape="rect" coords="400,283,584,584" href="#" alt="room 3" title="Room No.3" />
<area shape="rect" coords="18,399,267,584" href="#" alt="room B" title="Room No.B" />
<area shape="rect" coords="283,398,383,583" href="#" alt="room i" title="Room No.i" />
<area shape="rect" coords="217,216,384,383" href="#" alt="Home" title="Room No.0 / Home" />
</map>
</div>
  
<h3>&lt;map&gt;画像2</h3>
<div id="plan_room1">
<img src="planB.png" alt="Plan Room No.1" width="374" height="524" border="0" usemap="#Map2" id="room1" name="room1" />
<map name="Map2" id="Map2">
<area shape="rect" coords="19,19,174,123" href="../../index.php" alt="HTML" title="HTML" />
<area shape="rect" coords="19,129,173,239" href="#" alt="CSS" title="CSS" />
<area shape="rect" coords="20,246,173,357" href="#" alt="PHP" title="PHP" />
<area shape="rect" coords="20,363,173,474" href="#" alt="JavaScript" title="JavaScript" />
<area shape="rect" coords="181,21,315,152" href="#" alt="MySQL" title="MySQL" />
<area shape="rect" coords="192,183,303,223" href="#" alt="Room No.1" />
</map>
</div>
 
</body>
</html>

<div> や <map>タグに"id"を付与する際、各id名が重複しないように注意する必要があります。

また<img>の"usemap"の値と各map要素のname と id名は、先頭の#を除いた部分が同じである点に注意して下さい。
この値が異なると、どの<img>がどの<map>に対応するのか、ブラウザから見えなくなり正常に動作しません。Adobe の Dreamweaver(Webオーサリングソフト)などを使うと<img>と<map>の関係を自動で設定してくれますが、事前にCSSのセレクタとして設定した他の要素のid名と重複していないか確認して下さい。

map2canvas.js:サンプルコード


window.onload = function area_event(){
	var map_tag = document.getElementsByTagName("map");   //文書内<map>全取得
	for( h=0; h<map_tag.length; h++ ){   //<map>タグ全走査
		var area_tag = map_tag[h].getElementsByTagName("area");   //<map>の<area>全取得
		for( i=0; i< area_tag.length; i++ ){
			if( area_tag[i].addEventListener ){
				area_tag[i].addEventListener('mouseover', draw_img, false );
				area_tag[i].addEventListener('mouseout', dele_img, false );
			}else if( area_tag[i].attachEvent ){  //for under IE9
				area_tag[i].attachEvent('onmouseover', draw_img );
				area_tag[i].attachEvent('onmouseout', dele_img );
			}else{
				area_tag[i].onmouseover = draw_img;
				area_tag[i].onmouseout = dele_img;
			}
		}
	}
}
 
/*図形描画*/
function draw_img(evt){
	var area_obj = new Object();   //初期化
	if( evt.currentTarget ){
		area_obj.mapid = evt.currentTarget.parentNode.id;  //対象<map>:id取得
		area_obj.id = evt.currentTarget.id;
		area_obj.shape = evt.currentTarget.shape;
		area_obj.coords = evt.currentTarget.coords;
	}else{
		area_obj.mapid = evt.srcElement.parentNode.id;
		area_obj.id = evt.srcElement.id;
		area_obj.shape = evt.srcElement.shape.toLowerCase();
		area_obj.coords = evt.srcElement.coords;
	}
 
	xy = area_obj.coords.split(",");   //座標配列化
 
	for( i in xy ){
		xy[i] = parseInt(xy[i]);   //文字列 -> 数値化
	}
 
	var img_Usemap = "#"+area_obj.mapid;  //相関<img>のusemap属性値
	var img_tag = document.getElementsByTagName("img");   //文書内<img>全取得
 
	for( i=0; i< img_tag.length; i++ ){
		var usemap_Val = img_tag[i].getAttribute("usemap");  //<img>のusemap属性値取得
		if( img_Usemap == usemap_Val ){   //一致判定
			img_ID  = img_tag[i].getAttribute("id");
			img_SRC = img_tag[i].getAttribute("src");
			img_ALT = img_tag[i].getAttribute("alt");
			img_W   = img_tag[i].getAttribute("width");
			img_H   = img_tag[i].getAttribute("height");
			img_TOP = img_tag[i].offsetTop;
			img_LEFT = img_tag[i].offsetLeft;
 
			new_ID = "new_"+img_ID;  //<img>:id属性値 -> <canvas>:id生成
 
			var div_ID  = document.getElementById(img_ID).parentNode.id;	//<img>の親<div>:id
			var div_ELE = document.getElementById(div_ID);
			break;
		}
	}

	var canvas = document.getElementById(new_ID);  //<canvas>:id取得 -> 多重生成防止
 
	if( !canvas ){
		var canvas = document.createElement("canvas");  //canvas要素生成
		div_ELE.appendChild(canvas);
 
		if( document.uniqueID ){
			canvas = G_vmlCanvasManager.initElement(canvas);
		}
	}
 
	if( !canvas.getContext ){
		return false; 
	}else{
		canvas.setAttribute("id", new_ID);
		canvas.setAttribute("width", img_W);
		canvas.setAttribute("height", img_H);
 
		canvas.style.zIndex = "-100";
		canvas.style.top = img_TOP+"px";
		canvas.style.left= img_LEFT+"px";
		canvas.style.position = "absolute";
 
		var ctx = canvas.getContext('2d');
 
		ctx.beginPath();
		ctx.fillStyle = 'rgba(0,0,255,0.4)';   //図形:色指定
 
		if( area_obj.shape == "rect" ){
			ctx.fillRect( xy[0], xy[1], xy[2]-xy[0], xy[3]-xy[1] );
		}else if( area_obj.shape == "circle" ){
			ctx.arc( xy[0], xy[1], xy[2], 0, Math.PI*2, false );
		}else if( area_obj.shape == "poly" ){
			ctx.moveTo( xy[0], xy[1] );   //始点指示
 
			for( i=2; i<xy.length; i=i+2 ){   //(x,y)座標Loop
				ctx.lineTo( xy[i], xy[i+1] );
			}
 
			ctx.closePath();
		}
		ctx.fill();
	}
}
 
/*図形消去*/
function dele_img(evt){
	var canvas = document.getElementById(new_ID);   //<canvas>:id取得
	if ( ! canvas || ! canvas.getContext ) {
		return false; 
	}else{
		var ctx = canvas.getContext('2d');
		ctx.clearRect(0,0,img_W,img_H);    //全カンバス図形消去(0,0,幅,高さ)
		canvas.style.backgroundColor = "";
	}
}

複数要素対応としていますが、同一ページ内に1つのmap要素しか存在しない場合でも動作するので、Ver.1.0より実用的かもしれません…(´・ω・`)