zoukankan      html  css  js  c++  java
  • Android系统下用js自定义gesture事件(仿ios实现移动端事件一致)

    一、手势事件

    下面二维码是一个实例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的手势事件兼容

    完整代码见https://github.com/pangyongsheng/pangyongsheng.github.io/tree/master/gesture


    [1]: 部分代码参考https://blog.csdn.net/qq_17757973/article/details/54604625

  • 相关阅读:
    perl文本输出对齐
    putty配色方案
    java线程 同步与异步 线程池
    android为什么不允许新开启一个线程来更新UI,而是用handler来更新界面
    真正能获得基站LBS定位的android程序包括GSM、CDMA
    Android之TelephonyManager&GsmCellLocation类的方法详解
    网络编程之同步,阻塞,异步,非阻塞
    Android私有文件资源文件的存取
    [转]android 获取手机GSM/CDMA信号信息
    json格式转换
  • 原文地址:https://www.cnblogs.com/pangys/p/9119845.html
Copyright © 2011-2022 走看看