作者:月星名店_882 | 来源:互联网 | 2024-11-16 14:51
在移动端开发中,多点触控手势是提升用户体验的重要手段。然而,目前只有iOS浏览器原生支持手势事件,其他设备需要通过touchstart、touchmove和touchend等基础事件进行自定义实现。本文将详细介绍如何在Vue项目中实现多点触控手势。
在移动端开发中,多点触控手势是提升用户体验的关键。然而,目前只有iOS浏览器原生支持手势事件,其他设备需要通过touchstart、touchmove和touchend等基础事件进行自定义实现。本文将详细介绍如何在Vue项目中实现多点触控手势。
基础触摸事件
移动端的基础触摸事件包括:
- touchstart:触摸开始
- touchmove:触摸移动
- touchend:触摸结束
- touchcancel:触摸中断(如弹框打断)
示例代码:
box.addEventListener('touchmove', function(event) {
console.log('触摸移动');
});
touchEvent 对象
touchEvent 对象包含以下属性:
- touches:触发事件时屏幕上的触点个数
- targetTouches:触发事件时事件元素上的触点个数
- changedTouches:触发事件发生改变的触点个数
- target:事件元素
- stopPropagation():阻止事件冒泡
- preventDefault():阻止默认行为
示例代码:
box.addEventListener('touchstart', function(event) {
console.log(event.touches); // 一个手指触摸时输出 Touchlist{0: Touch, length: 1}
var startX = event.touches[0].clientX; // 触点在视口上的位置
});
手势事件
iOS 的手势事件包括:
- gesturestart:手势开始,屏幕上有两个或两个以上的手指
- gesturechange:手势变化,屏幕上有两个或两个以上的手指位置在移动
- gestureend:手势结束,屏幕上只剩下少于两个手指
新增的属性包括:
- scale:触点的距离与初始距离的比例
- rotation:触点的角度差与初始角度差的差
示例代码:
box.addEventListener('gesturechange', function(event) {
box.innerHTML = 'rotation: ' + event.rotation + '
';
box.innerHTML += 'scale: ' + event.scale + '
';
});
自定义多点触控手势
为了在非iOS设备上实现多点触控手势,我们可以封装一个手势插件。以下是gestrue.js的实现:
(function(w) {
/**
* 用于给元素监听手势事件
* @param node 要监听的元素
* @param callback 对象,对象有三个函数 start、change、end
*/
function gesture(node, callback) {
// 手势开始
node.addEventListener('touchstart', function(event) {
if (event.touches.length >= 2) {
node.isGestureStart = true;
this.startDst = getDst(event.touches[0], event.touches[1]);
this.startDeg = getDeg(event.touches[0], event.touches[1]);
if (callback && typeof(callback['start']) === 'function') {
callback['start']();
}
}
});
// 手势移动
node.addEventListener('touchmove', function(event) {
if (event.touches.length >= 2) {
var currentDst = getDst(event.touches[0], event.touches[1]);
var currentDeg = getDeg(event.touches[0], event.touches[1]);
event.scale = currentDst / this.startDst;
event.rotation = currentDeg - this.startDeg;
if (callback && typeof(callback['change']) === 'function') {
callback['change'](event);
}
}
});
// 手势结束
node.addEventListener('touchend', function(event) {
if (node.isGestureStart && event.touches.length <2) {
node.isGestureStart = false;
if (callback && typeof(callback['end']) === 'function') {
callback['end']();
}
}
});
function getDst(touch1, touch2) {
var x = touch2.clientX - touch1.clientX;
var y = touch2.clientY - touch1.clientY;
var z = Math.sqrt(x * x + y * y);
return z;
}
function getDeg(touch1, touch2) {
var x = touch2.clientX - touch1.clientX;
var y = touch2.clientY - touch1.clientY;
var angle = Math.atan2(y, x);
var deg = angle / Math.PI * 180;
return deg;
}
}
w.gesture = gesture;
})(window);
使用案例:实现元素缩放及旋转
以下是一个简单的示例,展示如何使用上述手势插件实现元素的缩放和旋转。
* {
margin: 0;
padding: 0;
}
html, body, #app {
width: 100%;
height: 100%;
overflow: hidden;
}
#box {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
width: 150px;
height: 150px;
background-color: #f90;
}
(function() {
var app = document.querySelector('#app');
var box = document.querySelector('#box');
app.addEventListener('touchstart', function(event) {
event.preventDefault();
});
gesture(box, {
start: function() {
box.startScale = transformCss(box, 'scale') || 1;
box.startRotate = transformCss(box, 'rotate') || 0;
},
change: function(event) {
transformCss(box, 'scale', box.startScale * event.scale);
transformCss(box, 'rotate', box.startRotate + event.rotation);
}
});
})();
注:本文中的transformCss
函数用于设置CSS变换属性,具体实现请参考相关文档。
作者:捕猹少年闰土
若有任何问题或建议,请联系我,共同学习进步。