canvas畫布實現拖拽碰撞 canvas之isPointInPath解析

isPointInPath():判斷指定的座標點是否在canvas繪製的路徑中,如果在返回true,如果不在返回false,只能判斷最後一個繪製的封閉路徑

注意:strokeRect()   fillRect();這兩個方法不適用於isPointInPath()

在canvas畫布中所有的移動,都是通過清空畫布重新繪製的,並不是向js中的dom元素一樣移動,可以通過設置某一個具體對象的left值或者top值讓其移動,在canvas中是通過每次清空畫布,再次繪製,事件間隔很短,看起來像是連續的,

如下:要想拖拽某個元素在畫布中移動,就需要如下操作

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style type="text/css">
		#cv{
			border:1px solid;
		}
	</style>
</head>
<body>
	<canvas id="cv" width="500" height="500"></canvas>
</body>
<script type="text/javascript">
	//isPointInPath():判斷指定的座標點是否在canvas繪製的路徑中,如果在返回true,如果不在返回false,只能判斷最後一個繪製的封閉路徑
	var ctx = cv.getContext("2d");
	//下面兩個方法無法使用isPointInPath()來判斷
	// ctx.strokeRect()
	// ctx.fillRect(50,50,100,100);
	//將canvas繪製的圖形抽象成對象,對象保存圖片的位置及大小信息
	function Rect(x,y,w,h,c="#000"){
		this.x=x;
		this.y=y;
		this.w=w;
		this.h=h;
		this.c=c;
	}
	Rect.prototype.draw=function(){
		ctx.beginPath();
		ctx.rect(this.x,this.y,this.w,this.h);
		ctx.fillStyle=this.c;
		ctx.fill();
	}

	//創建矩形對象,並繪製在畫布上
	
	//只能判斷最後一個繪製的封閉路徑,所以將r1放在r2的繪製後面
	var r2 = new Rect(350,350,50,50,"yellow");
	r2.draw();
	var r1 = new Rect(50,50,50,50,"pink");
	r1.draw();
	//進行拖拽
	cv.onmousedown=function(e) {
		//獲取鼠標在canvas中的座標位置
		var dx = e.clientX-cv.offsetLeft-1;
		var dy = e.clientY-cv.offsetTop-1;
		//當前鼠標座標點是否在矩形內
		if(ctx.isPointInPath(dx,dy)){
			console.log("在圖形內");
			//獲取鼠標在圖形內的座標
			dx=dx-r1.x;
			dy=dy-r1.y;
			cv.onmousemove=function(e){
				cv.width=cv.width;
				var mx = e.clientX-this.offsetLeft-1-dx;
				var my = e.clientY-this.offsetTop-1-dy;
				r1.x=mx;
				r1.y=my;
				//判斷碰撞
				if(isCrash(r2,r1)){
					r1.c="red";
				}else{
					r1.c="cyan";
				}		
				r2.draw();
				r1.draw();
			}	
		}else{
			console.log("在圖像外");
		}
	};
	cv.onmouseup = function(){
		this.onmousemove=null;
	}

	//檢測碰撞的方法:
	function isCrash(x,y){
		var l1 = x.x;
		var r1 =l1+x.w;
		var t1 = x.y;
		var b1 = t1+x.h;

		var l2 = y.x;
		var r2 =l2+y.w;
		var t2 = y.y;
		var b2 = t2+y.h;

		if(l1>r2 || r1<l2 || t1>b2 || b1 <t2){
			return false;
		}
		return true;

	}




</script>
</html>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章