html无原生双指旋转api,需手动计算两指夹角变化:监听touchmove,校验双指、固定向量顺序、归一化角度差,并在旋转时preventdefault以禁用系统缩放,再将弧度转角度并动态设置transform-origin实现绕中心旋转。

HTML 中没有原生双指旋转手势 API
浏览器标准 HTML 和 DOM 规范里,touchstart、touchmove、touchend 这些事件本身不提供“旋转角度”或“缩放中心”等高层语义;所谓“双指旋转”,必须靠手动计算两指间向量夹角变化来实现,不是调一个函数就能用的功能。
用 touchmove 计算两指夹角变化
核心逻辑是:在 touchmove 中持续获取两个触点坐标,构造向量,用 Math.atan2 算出当前夹角,再减去上一次的夹角,得到增量旋转值。
- 必须过滤掉非双指触摸:检查
event.touches.length === 2,否则直接 return - 两指顺序可能交换(比如从左到右 vs 右到左),建议固定以
touches[0]为起点、touches[1]为终点构造向量,避免跳变 - 角度需做归一化处理:差值可能跨 ±π 边界,用
((delta + Math.PI) % (Math.PI * 2)) - Math.PI转成 [-π, π] 区间 - 别在
touchstart就初始化“初始角度”——此时两指刚接触,位置抖动大;建议延迟到第一次touchmove且两指位移都 > 5px 后再记录基准
监听 touch 事件时要注意 preventDefault 的副作用
如果在容器上加了 touchmove 监听并调用了 event.preventDefault(),会阻止页面默认滚动行为,但这也是必要操作——否则 iOS Safari 会在双指拖拽时触发惯性滚动或缩放,干扰旋转逻辑。
- 只对目标元素调用
preventDefault,不要作用于document或body - 仅当检测到双指且正在旋转时才阻止,默认单指行为应保持可滚动
- Chrome on Android 8+ 支持
{ passive: false }选项,但 iOS Safari 仍需显式调用preventDefault才能禁用缩放
rotation 值不能直接赋给 CSS transform: rotate()
浏览器 CSS 的 rotate() 单位是 deg,而 JS 计算出的是弧度(rad),漏转换单位会导致旋转极慢或反向;另外,CSS 旋转默认绕元素中心,若想绕两指中心点旋转,还需动态设置 transform-origin。
- 把弧度转角度:用
rotationRad * (180 / Math.PI) - 两指中心坐标 =
((x0+x1)/2, (y0+y1)/2),单位是 px,设为transform-origin时要拼成字符串,如`${cx}px ${cy}px` - 注意:频繁设置
style.transformOrigin会触发 layout,性能敏感场景建议用transform: rotate(...) translate(...)组合模拟
双指旋转真正难的不是算角度,而是对抗系统级交互干扰(比如 iOS 缩放、滚动拦截时机、touchcancel 频发)和视觉锚点漂移(origin 动态不准导致“甩飞”)。上线前务必在真机上反复测三款设备:iPhone 12(iOS 16)、iPad Air(iOS 17)、Pixel 7(Android 14)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











