area mapとjQueryとcanvasを使ってクリッカブルマップロールオーバーとか〜

以前作ったもの(jQueryとcanvasを使ってイメージマップでhoverすると色かわるみたいな〜 - w7工廠)をクラスっぽくしてみました。
サンプルはこちら(W7工廠分室|トップページ)、設置方法は以前と同じです。
タイトルもついでに変えてみました。(目的と異なる場合はごめんなさい)
ただ・・・見やすいけれど以前のほうが性能はいいかも。
用途としては、建物のフロアガイド、地図、動物・植物・機械の部分説明などに使えます。


(2012-10-15追記)
Firefoxの場合、IntelAtomなマシンだと初期処理?にかなり時間がかかります。以前のもののほうがすぐ動作します。


【最近の更新】(特に記述がない限り以前のほうに記述しています。)
2012-10-15
2012-06-04 特定環境でのエラー現象(ChromeとWindowsとIntel Atomの組み合わせでcanvasの描画がおかしいとか〜 - w7工廠
2012-03-14
2012-01-23
・サンプルはjq_imgMapToCanvas2.jsでした。(汗)
・各描画はswitchの中に入れ込んでもいいのですが、何か図形によって個別に拡張したいときのためにあえて外に出しました。(短縮版は下にあります。)


Javascript (jq_imgMapToCanvas2.js)

/* jq_imgMapToCanvas2.js 2010-12-15→2012-03-14 */
$(function(){
	var c=[];
	$("img.imgMapToCanvas").each(function(){
		var canvas=new ImgMapToCanvas(this);
		c[canvas.id]=canvas;
	});
	$("area").hover(
		function(e){c["canvas_"+$(this).parent().attr("name")].draw(this);},
		function(e){c["canvas_"+$(this).parent().attr("name")].clear();}
	);
});
function ImgMapToCanvas(target){
	this.width=$(target).attr("width");
	this.height=$(target).attr("height");
	this.id=this.init(target);
	this.ctx=this.getCtx();
}
ImgMapToCanvas.prototype={
	init:function(target){//canvas設置
		var id="canvas_"+$(target).attr("usemap").split("#")[1];
		var src="url("+$(target).attr("src")+")";
		$(target).parent().css("position","relative");
		var position=$(target).position();
		var canvas = document.createElement("canvas");
		$(canvas).attr({"id":id,"width":this.width,"height":this.height});
		$(target).before(canvas);
		var isMSIE = /*@cc_on!@*/false;
		if (isMSIE & !jQuery.support.opacity) {//IEのみの処理
			canvas = G_vmlCanvasManager.initElement(canvas);
		}
		$("canvas#"+id)
                .css({"opacity":"1.0","zIndex":"1","top":position.top,"left":position.left,"backgroundImage":src});
		$(target)
		.css({"opacity":"0.1","zIndex":"100","position":"absolute","top":position.top,"left":position.left});
		return id;
	},
	getCtx:function(){//context取得
		var canvas = document.getElementById(this.id);
		if (!canvas || !canvas.getContext) {return false;}
		return canvas.getContext('2d');
	},
	draw:function(hoverArea){//areaの属性取得
		var shape=$(hoverArea).attr("shape").toLowerCase();//種類(circle poly rect)
		var coords=$(hoverArea).attr("coords").split(",");//座標
		for(i in coords){coords[i]=parseInt(coords[i]);}//文字列→数値
		var color=$(hoverArea).attr("color");//色
		if(!color){color='rgba(255, 100, 0, 0.7)';}//色情報無しの場合初期値
		switch(shape){
			case "rect"  :this.drawRect(coords,color);break;
			case "circle":this.drawCircle(coords,color);break;
			case "poly"  :this.drawPoly(coords,color);break;
		}
	},
	drawRect:function(coords,color){//矩形
		this.ctx.beginPath();
		this.ctx.fillStyle = color;
		this.ctx.fillRect(coords[0],coords[1],coords[2]-coords[0],coords[3]-coords[1]);
		this.ctx.fill();
	},
	drawCircle:function(coords,color){//円
		this.ctx.beginPath();
		this.ctx.fillStyle = color;
		this.ctx.arc(coords[0],coords[1],coords[2],0,Math.PI*2,false);
		this.ctx.fill();
	},
	drawPoly:function(coords,color){//非定型
		this.ctx.beginPath();
		this.ctx.fillStyle = color;
		this.ctx.moveTo(coords[0],coords[1]);
		for(i=2;i<coords.length;i=i+2){
			this.ctx.lineTo(coords[i],coords[i+1]);
		}
		this.ctx.closePath();
		this.ctx.fill();
	},
	clear:function(){//全カンバス図形消去
		this.ctx.clearRect(0,0,this.width,this.height);
	}
}



短縮版
Javascript (jq_imgMapToCanvas2_2.js)

/* jq_imgMapToCanvas2_2.js 2010-12-15→2012-03-14 */
$(function(){
	var c=[];
	$("img.imgMapToCanvas").each(function(){
		var canvas=new ImgMapToCanvas(this);
		c[canvas.id]=canvas;
	});
	$("area").hover(
		function(e){c["canvas_"+$(this).parent().attr("name")].draw(this);},
		function(e){c["canvas_"+$(this).parent().attr("name")].clear();}
	);
});
function ImgMapToCanvas(target){
	this.width=$(target).attr("width");
	this.height=$(target).attr("height");
	this.id=this.init(target);
	this.ctx=this.getCtx();
}
ImgMapToCanvas.prototype={
	init:function(target){//canvas設置
		var id="canvas_"+$(target).attr("usemap").split("#")[1];
		var src="url("+$(target).attr("src")+")";
		$(target).parent().css("position","relative");
		var position=$(target).position();
		var canvas = document.createElement("canvas");
		$(canvas).attr({"id":id,"width":this.width,"height":this.height});
		$(target).before(canvas);
		var isMSIE = /*@cc_on!@*/false;
		if (isMSIE & !jQuery.support.opacity) {//IEのみの処理
			canvas = G_vmlCanvasManager.initElement(canvas);
		}
		$("canvas#"+id)
                .css({"opacity":"1.0","zIndex":"1","top":position.top,"left":position.left,"backgroundImage":src});
		$(target)
		.css({"opacity":"0.1","zIndex":"100","position":"absolute","top":position.top,"left":position.left});
		return id;
	},
	getCtx:function(){//context取得
		var canvas = document.getElementById(this.id);
		if (!canvas || !canvas.getContext) {return false;}
		return canvas.getContext('2d');
	},
	draw:function(hoverArea){//areaの属性取得
		var shape=$(hoverArea).attr("shape").toLowerCase();//種類(circle poly rect)
		var coords=$(hoverArea).attr("coords").split(",");//座標
		for(i in coords){coords[i]=parseInt(coords[i]);}//文字列→数値
		var color=$(hoverArea).attr("color");//色
		if(!color){color='rgba(255, 100, 0, 0.7)';}//色情報無しの場合初期値
		this.ctx.beginPath();
		this.ctx.fillStyle = color;
		switch(shape){
			case "rect"  :
				this.ctx.fillRect(coords[0],coords[1],coords[2]-coords[0],coords[3]-coords[1]);
				break;
			case "circle":
				this.ctx.arc(coords[0],coords[1],coords[2],0,Math.PI*2,false);
				break;
			case "poly"  :
				this.ctx.moveTo(coords[0],coords[1]);
				for(i=2; i<coords.length;i=i+2){
					this.ctx.lineTo(coords[i],coords[i+1]);
				}
				this.ctx.closePath();
				break;
		}
		this.ctx.fill();
	},
	clear:function(){//全カンバス図形消去
		this.ctx.clearRect(0,0,this.width,this.height);
	}
}