js实现多点触控
多点触控基础概念
多点触控通过监听触摸事件(touchstart、touchmove、touchend)实现,每个触摸点会生成一个 Touch 对象,包含坐标、标识符等信息。事件对象中的 touches 数组保存当前所有触摸点。
监听触摸事件
element.addEventListener('touchstart', handleTouchStart);
element.addEventListener('touchmove', handleTouchMove);
element.addEventListener('touchend', handleTouchEnd);
处理触摸点数据
在事件处理函数中,通过 event.touches 获取触摸点列表。每个触摸点包含以下关键属性:
clientX/clientY:视口坐标identifier:唯一标识符target:触发事件的元素
示例代码:
function handleTouchStart(event) {
const touches = event.touches;
for (let i = 0; i < touches.length; i++) {
console.log(`Touch ${i}: (${touches[i].clientX}, ${touches[i].clientY})`);
}
}
实现常见手势
双指缩放
计算两个触摸点的初始距离和移动距离的比例:
let initialDistance;
function handleTouchStart(event) {
if (event.touches.length === 2) {
initialDistance = getDistance(event.touches[0], event.touches[1]);
}
}
function handleTouchMove(event) {
if (event.touches.length === 2) {
const currentDistance = getDistance(event.touches[0], event.touches[1]);
const scale = currentDistance / initialDistance;
element.style.transform = `scale(${scale})`;
}
}
function getDistance(touch1, touch2) {
const dx = touch1.clientX - touch2.clientX;
const dy = touch1.clientY - touch2.clientY;
return Math.sqrt(dx * dx + dy * dy);
}
旋转手势
通过计算两个触摸点的角度变化实现:
let initialAngle;
function handleTouchStart(event) {
if (event.touches.length === 2) {
initialAngle = getAngle(event.touches[0], event.touches[1]);
}
}
function handleTouchMove(event) {
if (event.touches.length === 2) {
const currentAngle = getAngle(event.touches[0], event.touches[1]);
const rotation = currentAngle - initialAngle;
element.style.transform = `rotate(${rotation}rad)`;
}
}
function getAngle(touch1, touch2) {
const dy = touch2.clientY - touch1.clientY;
const dx = touch2.clientX - touch1.clientX;
return Math.atan2(dy, dx);
}
兼容性注意事项
- 部分旧浏览器可能不支持
touches属性,需检测 API 支持性。 - 移动端需添加
meta标签禁用默认手势:<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
性能优化建议
- 使用
requestAnimationFrame节流touchmove事件。 - 避免在事件处理函数中进行复杂计算,必要时使用 Web Worker。
通过以上方法,可实现完整的多点触控交互,适用于画板、地图缩放等场景。

