为什么 mousemove 事件在快速移动时会跳过某些坐标?
我在做一个画板功能,监听 mousemove 来记录鼠标轨迹,但发现鼠标移动太快的时候,路径会出现断点,不是连续的。明明我每次都在 event 里取了 clientX 和 clientY 啊。
是不是浏览器不会触发每一个像素点的事件?那该怎么让轨迹更平滑呢?
我现在的代码大概是这样:
canvas.addEventListener('mousemove', (e) => {
const x = e.clientX;
const y = e.clientY;
points.push({ x, y });
drawLine(points);
});
最简单的解决办法是在相邻的两个点之间做线性插值,补上中间的点。比如这样:
如果想更平滑,可以用二次贝塞尔曲线来连接断点,而不是直接用直线。原理是取两个断点的中点作为控制点,画抛物线。
另外提一下,现在更推荐用 Pointer Events API,pointermove 事件对触摸和触控笔也通用,而且规范里有提到事件触发的精度问题,不过浏览器实现上该跳过的点还是会跳过,插值这层还是得自己处理。