1. 程式人生 > >canvas 中的圖形事件判斷

canvas 中的圖形事件判斷

瞭解canvas這個標籤後,會發現在一個canvas類似一個img圖片,在canvas中繪製的圖形都是一個整體,所有的事件也都是發生在這一個標籤上,沒有辦法直接判斷事件是發生在canvas中的某個圖形上。但是通過canvas中的路徑的概念可以解決這個問題。

關鍵:通過路徑來繪製圖形,用每一個圖形是一個路徑,事件繫結在canvas標籤上,獲得事件的發生的x,y座標。再通過 isPointInPath(),來判斷點(x,y)是否在路徑內,需要注意的是isPointInPath()只對當前路徑(currentPath)有效,並且經測試發現,只對當前路徑的第一個子路徑有效(subPath,一個currentPath可以有多個subPath)。關於路徑的詳細解釋可以看看canvas的api文件。
具體的判斷就是,當事件觸發時,對canvas中的內容進行重繪,每重回一個路徑中的圖形,用 isPointInPath()判斷一次,如果在路徑內,執行相應的操作。

如下面的例子,可以拖動一個canvas標籤中繪製的多個圓中的任一個。

<!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=gb2312" />
<script type="text/javascript">
	var list=[];
	var currentC;
	var _e={};
    var cricle = function(x,y,r){
    	this.x=x;
    	this.y=y;
    	this.r=r;
    	this.isCurrent=false;
    	this.drawC=function(ctx,x,y){
    		ctx.save();
    		ctx.beginPath();
    		ctx.moveTo(this.x,this.y-this.r);
			ctx.arc(this.x,this.y,this.r,2*Math.PI,0,true);
			if ((x && y && ctx.isPointInPath(x, y) && !currentC )||this.isCurrent) {

					
					ctx.fillStyle = '#ff0000';
					currentC=this;
					this.isCurrent=true;

			}else{
				ctx.fillStyle = '#999999';
			}
			ctx.fill();
    	}
    
    }
	function draw(){
		var canvas = document.getElementById('tutorial');
		if (canvas.getContext){
			var ctx = canvas.getContext('2d');
			for(var i=0;i<10;i++){
				var c=new cricle(20*i,20*i,5*i);
				c.drawC(ctx);
				list.push(c);
			}
		}
	}
	
	function reDraw(e){
		e=e||event;
		var canvas = document.getElementById('tutorial');
		var x = e.clientX - canvas.offsetLeft;
		var y = e.clientY - canvas.offsetTop;

		canvas.width = canvas.width;
		if (canvas.getContext){
			var ctx = canvas.getContext('2d');
			for(var i=0;i<list.length;i++){
				var c=list[i];
				c.drawC(ctx,x,y);

				
			}
		}
	
	}
	
	function show(e){
		e=e||event;
		var canvas = document.getElementById('tutorial');
		var ctx = canvas.getContext('2d');
		var x = e.clientX - canvas.offsetLeft;
		var y = e.clientY - canvas.offsetTop;

		if(currentC){
			currentC.x=parseInt(x+(x-currentC.x)/5);
			currentC.y=parseInt(y+(y-currentC.y)/5);
		}
		_e=e;


	}

	window.onload=function(){
		
		var canvas = document.getElementById('tutorial');
		draw();
		
		canvas.onmousedown=function(e){
			e=e||event;
			var x = e.clientX - canvas.offsetLeft;
			var y = e.clientY - canvas.offsetTop;
			if(currentC)
				currentC.isCurrent=false;
			currentC=null;
			reDraw(e);
			_e=e;
			var showTimer=setInterval(function(e){
				reDraw(e);
			},10,_e);
			canvas.onmousemove=show;

			document.onmouseup=function(){
				if(currentC)
					currentC.isCurrent=false;
				currentC=null;
				canvas.onmousemove=null;
				clearInterval(showTimer);
			}

		}
	}
</script>
<style type="text/css">
  canvas { border: 1px solid black; }
</style>
</head>
<body style="background:#eeeeee;">
	<div style="background:#0f0;width:100px;height:100px;position:absolute;left:100px;top:100px;z-index:1;" onclick="alert(1);"></div>
    <canvas id="tutorial" width="1000" height="550" style="z-index:100;display:block;position:absolute;"></canvas>
	
</body>
<script>

</script>
</html>