使用Three.js raycast点击Fabric.js文本角落出现偏移问题求助
足球服定制配置应用坐标偏移问题修复方案
你遇到的文本点击偏移、缩放操作精度差的问题,确实和getRealPosition方法的坐标计算逻辑缺陷直接相关,可按照以下步骤修复:
常见错误点排查
- 未扣除canvas元素的视口偏移:直接使用鼠标
clientX/clientY计算坐标,没有减去canvas元素getBoundingClientRect()返回的left、top偏移值,页面滚动、父元素定位都会导致全局坐标和canvas内部坐标存在固定偏差 - 未适配canvas像素缩放比:如果canvas的CSS宽高和自身
width/height属性的像素值不一致(比如为了适配高清屏做了倍图处理),需要额外乘以缩放系数才能得到canvas内部的真实坐标 - 未考虑文本变换的矩阵转换:如果文本已经应用了缩放、旋转、平移变换,直接用全局坐标和文本原始包围盒做命中判断一定会出现偏移,需要通过当前变换矩阵的逆矩阵将鼠标坐标转换为文本局部坐标系下的坐标后再做判断
修正后的getRealPosition参考代码
function getRealPosition(canvas, event) { const canvasRect = canvas.getBoundingClientRect(); // 计算canvas实际像素和CSS展示尺寸的缩放比例 const scaleX = canvas.width / canvasRect.width; const scaleY = canvas.height / canvasRect.height; // 先扣除canvas视口偏移,再乘以缩放比得到canvas内部真实坐标 const realX = (event.clientX - canvasRect.left) * scaleX; const realY = (event.clientY - canvasRect.top) * scaleY; // 若有当前操作文本的变换矩阵,需追加逆矩阵转换逻辑,示例如下: // const textTransform = activeText.getTransform() // const inverseMatrix = textTransform.inverse() // const textLocalPoint = inverseMatrix.applyToPoint(realX, realY) // return { x: textLocalPoint.x, y: textLocalPoint.y } return { x: realX, y: realY } }
额外优化建议
- 文本命中检测建议使用canvas原生
isPointInPath方法做像素级判断,比包围盒碰撞精度高很多 - 缩放操作锚点要绑定到你点击的文本角落控制点,不要默认使用文本中心作为缩放锚点,避免缩放过程中出现位置跳变
内容的提问来源于stack exchange,提问作者naoval luthfi
相关产品推荐
相关产品推荐

