mousemove事件,鼠标移动过快时,无法全部响应

问题描述:

项目中,运用mousemove来实现绘制圆形时,发现鼠标移动速度过快时,绘制的圆形,不能连接一起,中间出现断点,无法形成一条完整的路径。

问题分析:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>事件</title>
	<style type="text/css">
		*{
			margin: 0;
			padding: 0;
		}
		#content{
			width: 200px;
			height: 200px;
			border: 1px solid #ccc;
			background-color: blue;
			margin: 0 auto;
		}

	</style>
</head>
<body>
	<div id="content"></div>
	<script type="text/javascript">
		var box=document.getElementById("content");
		var isMouseDown=false;
		var t=0;
		box.addEventListener("mousemove",function(e){
			if(isMouseDown){
				console.log("move");	
				/*t++;
				console.log(t);*/
			}
			
		});
		box.addEventListener("mousedown",function(e){
			isMouseDown=true;
		});
		document.addEventListener("mouseup",function(e){
			isMouseDown=false;
		});

	</script>
</body>
</html>

鼠标移动过快时效果图:

在这里插入图片描述

鼠标移动缓慢时效果图:
这里写图片描述

经过如上代码分析,发现当鼠标移动过快时,console.log(“move”)执行的次数很少;当鼠标移动足够缓慢时,执行次数鼠标移动的像素数近似(这正好验证了,当每移动一个像素时,就会触发mousemove事件)。

**原因:**鼠标移动时,不会存储所有的移动信息,而是通过取插值的方法取得鼠标位置信息,否则,系统会被鼠标移动拖垮。所以就会出现,移动过快时,出现断点的问题。

解决方案:

绘制移动轨迹时,最常想到的方案就是通过每移动一个像素,就绘制一个圆,让所有圆连接在一起,正好形成轨迹。(下图中的圆,就是每移动一个像素,绘制出的圆,连接在一起就是一条轨迹路径)
在这里插入图片描述

理想是美好的,现实是残酷的。正如上面分析的那样,mousemove事件的响应时间粒度不够,鼠标移动过快时,不能做到移动一个像素,响应一次mousemove事件,所以无法通过移动一个像素就绘制一个圆,进而形成连续轨迹路径。如下图所示,移动过快时,路径会间断。
在这里插入图片描述

我们换种思路,第一次mousemove响应时,记录为起点startPoint,第二次响应记录为终点endPoint,将两点相连绘制直线,就不会出现中间断点的情况。
为了美观,可以利用lineCap属性,可以保证直线两端为圆角,如下所示:

ctx.beginPath();
ctx.lineCap="round";
ctx.moveTo(20,40);
ctx.lineTo(200,40);
ctx.stroke();

在这里插入图片描述

这样我们的问题就解决了
演示效果:http://zhaoshaobang.github.io/blog/lottery/


下面是我的个人公众号-《前端名狮》
会每日更新大厂前端面试题,和一些精选文章,有需要的欢迎关注。
前端名狮

如果你在一个QDialog窗口中移动鼠标无法响应mouseMoveEvent函数,可能是因为对话框中的某些控件捕获了鼠标事件导致事件无法传递到对话框的mouseMoveEvent函数中。 解决方法可以尝试以下两种方案: 1. 重写对话框中的鼠标事件过滤器,将鼠标事件传递到对话框的mouseMoveEvent函数中: ```python class MyDialog(QDialog): def __init__(self): super().__init__() # 安装事件过滤器 self.installEventFilter(self) def eventFilter(self, obj, event): if event.type() == QEvent.MouseMove: self.mouseMoveEvent(event) return True return super().eventFilter(obj, event) def mouseMoveEvent(self, event): print('鼠标移动', event.pos()) ``` 2. 在对话框中的控件上禁用鼠标事件: 在QDialog中,可以通过setMouseTracking函数来设置是否跟踪鼠标事件。如果设置为True,则跟踪鼠标事件并传递到mouseMoveEvent函数中。如果设置为False,则不跟踪鼠标事件。你可以在对话框的初始化函数中禁用控件的鼠标事件: ```python class MyDialog(QDialog): def __init__(self): super().__init__() self.setMouseTracking(True) # 开启鼠标跟踪 # 禁用控件的鼠标事件 self.pushButton.setMouseTracking(False) self.lineEdit.setMouseTracking(False) def mouseMoveEvent(self, event): print('鼠标移动', event.pos()) ``` 这样,当鼠标在禁用了鼠标事件的控件上移动,不响应鼠标事件,而是传递到对话框的mouseMoveEvent函数中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值