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>

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值