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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM