• Hammer.js分析(三)——input.js


    input.js是所有input文件夹中类的父类,浏览器事件绑定、初始化特定的input类、各种参数计算函数。

    Input父类和其子类就是在做绑定事件,各种参数计算、整合、设置等返回自定义事件对象,交给识别器的相关对象使用。

    一、Input父类

    Input相当于一个抽象类,对象中总共有3个方法

    1)handler(ev)

    这相当于一个抽象方法,在上图中的6个子对象里,都会实现这个方法。

    ev是事件对象(不是自定义的那个),例如触屏事件中就是 TouchEvent。

    2)init()与destroy()

    绑定事件,在各个子对象都会设置:

    evEl、evTarget 或 evWin 事件类型字符串,字符串中有空格就是多个事件。

    element、target 或 getWindowForElement(this.element) 就是需要绑定事件的对象。

    domHandler 是在构造函数中定义的,就是执行子集重写过的 handler 方法。里面有个判断,“enable” 可以控制是否执行事件。

    this.domHandler = function(ev) {
      if (boolOrFn(manager.options.enable, [manager])) {
        self.handler(ev);
      }
    };

    二、input.js中的函数

    1)createInputInstance(manager)

    根据特性选择创建对象,可指定也可以根据浏览器特性自动绑定。在Manager的构造函数中会被调用。

    var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;
    var SUPPORT_TOUCH = ('ontouchstart' in window);
    var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;
    var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);
    
    function createInputInstance(manager) {
      var Type;
      var inputClass = manager.options.inputClass;//自定义的函数
    
      if (inputClass) {
        Type = inputClass;
      } else if (SUPPORT_POINTER_EVENTS) {
        Type = PointerEventInput;
      } else if (SUPPORT_ONLY_TOUCH) {
        Type = TouchInput;
      } else if (!SUPPORT_TOUCH) {
        Type = MouseInput;
      } else {
        Type = TouchMouseInput;
      }
      return new(Type)(manager, inputHandler);//inputHandler是input.js中的一个函数
    }

    2)inputHandler(manager, eventType, input)

    a. 在每个子类(touch.js中的TouchInput等)的构造函数中,都会执行“Input.apply(this, arguments);”,调用父类(input.js中的Input)的构造函数。

    b. 在上一个函数中会将 inputHandler 传入到子类的构造函数中,这样的话父类中的 callback 就等于是 inputHandler。

    c. 每个子类中的 handler 方法都会调用 callback 函数。

    在每个子类中都会有类似的Map值,key是事件名,value是整数:

    var TOUCH_INPUT_MAP = {
        touchstart: INPUT_START,
        touchmove: INPUT_MOVE,
        touchend: INPUT_END,
        touchcancel: INPUT_CANCEL
    };

    函数内容如下:

    function inputHandler(manager, eventType, input) {
        var pointersLen = input.pointers.length;
        var changedPointersLen = input.changedPointers.length;
        var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));
        var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));
        //设置自定义事件对象的参数
        input.isFirst = !!isFirst;
        input.isFinal = !!isFinal;
        if (isFirst) {
            manager.session = {};
        }
    
        //设置 eventType,例如 'touchstart, mouseup, pointerdown'的对应整数,通过上面的Map值获取到
        input.eventType = eventType;
        //计算旋转、比例、角度、距离等信息
        computeInputData(manager, input);
        //执行隐藏的事件,这个在会在每个事件中调用,例如 'touchstart, mouseup, pointerdown'等
        manager.emit('hammer.input', input);
    
        manager.recognize(input);//执行Manager对象中的recognize方法
        manager.session.prevInput = input;
    }

    3)computeDeltaXY(session, input)

    经过计算的X与Y轴坐标,有正数和负数,以某个点为原点,画坐标轴。如下图所示:

    以prevDelta的X和Y作为原点,center中的X和Y会随着移动而改变,offset就是第一次接触屏幕的点的clientX与clientY。

    center是通过函数“getCenter(pointers)”获得的。

    4)其他技术函数

    1. getCenter(pointers):通过clientX和clientY,以及点的个数,计算所有点的中心坐标,没有负数

    2. getVelocity(deltaTime, x, y):计算两个点之间的移动速度

    3. getDirection(x, y):判断一个点到另外一个点的移动方向

    4. getDistance(p1, p2, props):计算两个点之间的直线距离

    5. getAngle(p1, p2, props):计算两个点之间的夹角

    6. getRotation(start, end):计算两个点集之间的旋转度

    7. getScale(start, end):计算两个点集之间的比例

    三、自定义的input事件对象

    在前面一篇“manager.js”的分析中,提到了自定义事件对象,里面还包括各种计算过的参数。

    1)事件对象

    2)移动方向常量

    之所以是1,2,4,8,16是为了方便位运算。

    var DIRECTION_NONE = 1;
    var DIRECTION_LEFT = 2;
    var DIRECTION_RIGHT = 4;
    var DIRECTION_UP = 8;
    var DIRECTION_DOWN = 16;

    3)事件类型常量

    var INPUT_START = 1;
    var INPUT_MOVE = 2;
    var INPUT_END = 4;
    var INPUT_CANCEL = 8;

    4)具体说明

    Name

    Value

    angle

    移动角度

    center

    多点触控的中心位置,或者单点的坐标

    changedPointers    

    改变了的触摸点数组,例如touchend中的事件中的事件对象TouchEvent里的changedTouches

    deltaTime

    交互过程的总时长(ms)

    deltaX

    经过计算后的X轴坐标点(参考computeDeltaXY)

    deltaY

    经过计算后的Y轴坐标点(参考computeDeltaXY)

    direction

    移动方向(参考移动方向常量)

    distance

    移动距离

    eventType

    事件类型(参考事件类型常量)

    isFinal

    当前交互是否为最后一次(boolean)

    isFirst

    当前交互是否为首次(boolean)

    maxPointers

    最大触摸点数量

    offsetDirection

    从起始点算起的移动方向(参考移动方向常量)

    overallVelocityX

    deltaX坐标点的移动速度

    overallVelocityY

    deltaY坐标点的移动速度

    overallVelocity

    比较overallVelocityXoverallVelocityY,选取绝对值大的那个

    pointerType

    触摸点类型(touch、pen、mouse 或 kinect)

    pointers

    触摸点数组,例如touchend中事件对象TouchEvent里的touches属性

    rotation

    多点触摸结束时的旋转数值,若为单点触摸则为0

    scale

    多点触摸结束时的缩放比例,若为单点触摸则为1

    srcEvent

    源事件对象(类型为TouchEvent、MouseEvent或PointerEvent)

    target

    接收事件的目标,上图中就是 document.getElementById('layer')

    timeStamp

    当前时间戳

    velocityX

    (input.deltaX - last.deltaX)计算后X坐标点的移动速度

    velocityY

    (input.deltaY - last.deltaY)计算后Y坐标点的移动速度

    velocity

    比较velocityX与velocityY,选取绝对值大的那个

    demo源码下载:

    http://download.csdn.net/download/loneleaf1/9429375

    参考资料:

    http://tech.gilt.com/2014/09/23/five-things-you-need-to-know-about-hammer-js-2-0/   

    FIVE THINGS YOU NEED TO KNOW ABOUT HAMMER.JS 2.0

    http://www.cnblogs.com/iamlilinfeng/p/4239957.html   Hammer.js

    http://colinued.leanote.com/post/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E6%89%8B%E5%8A%BF%E5%BA%93hammerJS-2.0.4%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91    移动端手势库hammerJS-2.0.4

  • 相关阅读:
    统计字符的有效字数
    Ubuntu Wifi网络连接不上或经常断网
    Git实战指南----跟着haibiscuit学Git(第十一篇)
    Git实战指南----跟着haibiscuit学Git(第十篇)
    Git实战指南----跟着haibiscuit学Git(第九篇)
    Git实战指南----跟着haibiscuit学Git(第八篇)
    Git实战指南----跟着haibiscuit学Git(第七篇)
    Git实战指南----跟着haibiscuit学Git(第六篇)
    linux之网络命令
    Ceph实战入门之安部署篇
  • 原文地址:https://www.cnblogs.com/strick/p/5184954.html
Copyright © 2020-2023  润新知