减去画布原点并缩放点
从事件的 clientX 和 clientY 以及 canvas.getBoundingClientRect() 返回的矩形开始。该矩形相对于视口定位,因此在缩放之前减去其左侧和顶部。如果逻辑游戏是 800 x 450 并且显示的矩形是 400 x 225,则将局部 x 和 y 乘以 2。然后,无论页面的滚动位置如何,显示中心的指针都会映射到逻辑 (400, 225)。
使用实际的内容矩形,而不是基于窗口宽度的假设。考虑画布外部的 CSS 边框或填充,并在调整大小或方向更改后刷新映射。如果游戏使用摄像机偏移、信箱或其他世界变换,请在将该点与游戏的命中区域进行比较之前以相反的顺序反转这些操作。
测试整个表面,包括死角
在转换后的指针位置放置一个临时十字准线,并测试画布的所有四个角、中心和目标的每个边缘。一个简单的校准检查是单击绘制的圆的中心并确认报告的世界点位于圆的中心附近。然后在其外部单击以检查命中边界是否与预期的容错裕度相符。 MDN 将 clientX 记录为相对于视口的元素边界,并将 getBoundingClientRect() 记录为返回相对于视口的元素边界;将这些测量配对可以避免混合坐标空间。
保持渲染和点击区域链接
存储目标的世界位置和尺寸一次,然后使用该数据来绘制它并针对它测试指针。避免为可见图标和单击区域维护单独的手动输入屏幕坐标。更改画布比例、CSS 大小、设备像素比或相机偏移后重新测试。如果坐标探针正确但目标仍然未命中,请检查其形状数学和输入顺序,而不是添加任意像素偏移。
关于画布命中测试坐标的常见问题
我应该使用 offsetX 和 offsetY 来进行画布点击吗?
它们对于简单的未转换画布来说很方便,但显式的客户端坐标、元素边界和游戏转换使布局或相机缩放发生变化时每个转换步骤更加清晰。
devicePixelRatio 属于指针转换吗?
仅当您的指针指向并命中区域使用后备存储像素时。一种常见的方法是将视口坐标映射到逻辑游戏单元,在渲染变换中保持设备像素缩放。
延伸阅读
发现信息过时了? 报告需要更正的内容