一, 手势事件
在 ios 系统中, 系统自带了 gesture 事件, 两个手指操作的时候, 就会产生一下三种手势事件:
gesturestart: 当一个手指已经按在屏幕上, 另一个手指又触摸屏幕的时候触发.
gesturechange: 当触摸屏幕的任何一个手指的位置发生变化的时候触发.
gestureend: 当任何一个手指从屏幕上面移开时触发.
这里通过 js 自定义事件模仿 ios 的手势事件为 Android 添加相同的功能;
实现基本思路
在 Android 中我们可以监听 touchstart,touchmove,touchend 去实现手势事件的监听,
当触发 touch 事件的时候, 会生成一个 TouchEvent 对象, 我们可通过其属性 e.touches.length 来判断是否多点触控, 通过 e.touches[index].pageX,e.touches[index].pageY 获取去触点坐标, 通过 e.target 获取 dom 节点;
实现方法
1, 创建自定义事件
- var gesturestart = new CustomEvent('gesturestart');
- var gesturechange = new CustomEvent('gesturestart');
- var gestureend = new CustomEvent('gesturestart');
- 1,gesturestart
首先定义两个变量存储触发状态和起始点信息
- var istouch = false;
- ar start = [];
监听 touchstart 事件, 通过 e.touches.length>2 判断是否多点触控, 如果是, 触发自定义事件 gesturestart
- document.addEventListener("touchstart", function(e) {
- if(e.touches.length>= 2) { // 判断是否有两个点在屏幕上
- istouch = true;
- start = e.touches; // 得到第一组两个点
- e.target.dispatchEvent(gesturestart);
- };
- }, false);
- 2,gesturechange
gesturechange 事件中我们需在事件对象中返回以下两个属性:
scale: 表示两个手指之间的距离情况, 向内收缩会缩短距离, 这个值从 1 开始, 并随距离拉大而增长
rotation: 表示手指变化引起的旋转角度, 负值表示逆时针, 正值表示顺时针, 从零开始.
对于两点间的距离我们可由以下公式计算
(1) 缩放比例可通过两组点之间的长度比计算
scale = dis1 / dis2
首先编写方法两点之间距离的方法 (勾股定理)
- function getDistance(p1, p2) {
- var x = p2.pageX - p1.pageX,
- y = p2.pageY - p1.pageY;
- return Math.sqrt((x * x) + (y * y));
- };
(2) 对于旋转角度第一组点的夹角与第二组点的夹角相减得到
deg= deg2-deg1 =arctan (x2-x1/y2-y1) - arctan (x4-x3/y4-y3)
编写获取夹角方法 (反三角函数求夹角, 注意弧度转化为角度)
- function getAngle(p1, p2) {
- var x = p1.pageX - p2.pageX,
- y = p1.pageY - p2.pageY;
- return Math.atan2(y, x) * 180 / Math.PI;
- };
监听 touchmove 事件, 通过 e.touches.length>= 2 和 istouch 判断是否触发 gesturechange 事件
- document.addEventListener("touchmove", function(e) {
- e.preventDefault();
- if(e.touches.length>= 2 && istouch) {
- var now = e.touches; // 得到第二组触点
- var scale = getDistance(now[0], now[1]) / getDistance(start[0], start[1]); // 得到缩放比例
- var rotation = getAngle(now[0], now[1]) - getAngle(start[0], start[1]); // 得到旋转角度
- gesturechange.scale = scale.toFixed(2);
- gesturechange.rotation = rotation.toFixed(2);
- e.target.dispatchEvent(gesturechange);
- };
- }, false);
- 3,gestureend
监听 touchend 事件, 通过 istouch 判断是否触发 gestureend 事件
- document.addEventListener("touchend", function(e) {
- if(istouch) {
- istouch = false;
- e.target.dispatchEvent(gestureend);
- };
- }, false);
4, 系统环境判断
- function isAndroid(p1, p2) {
- var u = navigator.userAgent;
- return u.indexOf('Android')> -1 || u.indexOf('Adr')> -1; // 是否 android 终端
- };
封装以上方法并执行, 即可实现安卓端与 ios 的手势事件兼容
[1]: 部分代码参考 https://blog.csdn.net/qq_17757973/article/details/54604625
来源: https://www.cnblogs.com/pangys/p/9119845.html