React中如何实现双指捏合缩放图片时保持中心点位置?
在实现图片双指缩放功能时发现,每次捏合缩放后图片位置会偏移,无法保持双指中心点作为缩放中心。比如用户用两根手指缩放时,图片总是以左上角为轴心缩放。
我尝试监听touchstart和touchend事件,计算两指距离,但发现transform的origin没算对。代码大概是这样写的:
const [scale, setScale] = useState(1);
let startDistance = 0;
const handlePinch = (e) => {
if (e.touches.length === 2) {
const currentDistance =
Math.hypot(
e.touches[0].clientX - e.touches[1].clientX,
e.touches[0].clientY - e.touches[1].clientY
);
const newScale = currentDistance / startDistance;
setScale(prev => prev * newScale);
}
};
但这样缩放时图片会偏离手指位置,应该怎样正确计算缩放中心点坐标?是不是需要根据手指位置动态设置transform-origin属性?
transform-origin属性。不过直接用CSS的transform-origin有点麻烦,推荐通过矩阵变换来实现,这样更灵活。大致思路是这样的:
1. 在
touchstart事件中记录两指的中心点坐标。2. 在
touchmove事件中,根据新的手指位置重新计算中心点,并结合当前缩放比例更新矩阵变换。3. 使用
DOMMatrix或直接拼接transform值来应用变换。给个代码示例吧:
然后在你的图片组件里绑定这些事件,并使用
applyTransform生成的样式。这样就能保证缩放时以双指中心点为轴心了。注意哦,这种方式不仅处理了缩放,还同时解决了平移的问题。毕竟用户捏合的时候可能还会带动图片移动。折腾过手势交互的都懂,这玩意儿调试起来真是够呛,但搞定了就特别有成就感。
transform-origin设置。关键代码:算错就是没动态更新手指中心坐标。