js自定義Android端手勢事件

pangyongsheng發表於2018-06-01

一、手勢事件

下面二維碼是一個例項dome,可掃碼直接檢視:

在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('gesturechange');
var gestureend = new CustomEvent('gestureend');
複製程式碼

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的手勢事件相容

完整程式碼見github.com/pangyongshe…

[1]: 部分程式碼參考https://blog.csdn.net/qq_17757973/article/details/54604625


相關文章