<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      手勢模型和Angular Material的實現

      iPhone的出現讓手勢操作大為流行,也使得手勢編程成為開發人員的挑戰。 擬物設計也把手勢編程納入在內,大概也想制定一個在交互模型標準?,F階段因為MD還在預發布階段,因此還只實現了單點手勢(一個指頭),可是已經有足夠的東西值得學習,無論對我們應用還是自己設計手勢編程都是大有裨益。

      Angular Material有兩個手劃控件mdSwipeLeftmdSwipeRight,然而真正的代碼支持卻不在這兩個控件的定義中,而是在核心代碼中,文件位置src\core\services\gesture\gesture.js這里也就是我們深入研究手勢實現的地方。

      基本屏幕事件

      做過界面的人都熟悉mousedown, mouseup, mousemove等事件,很多后臺函數多與這些事件綁定,從而能夠與用戶交互。但是這些事件都有些單薄而僵硬,手勢事件卻更友好和人性化,這也是其大受歡迎的根本原因。
      手勢事件不是空中樓閣,它們本身是需要這些基本事件的支持,這些基本屏幕事件也就成為了手勢模型的一個組成部分,成為最底的一層。

      這些事件首先被劃分為三類,說是三類,理解成三個事件更為恰當,它們與手指與屏幕的交互一一對應:開始事件就是手指按下屏幕;移動事件就是手指在屏幕移動;結束事件就是手指離開屏幕。非常簡單而直觀。
      從下面MD對這三類事件的定義,我們也可以看到每類事件中的變體大都與設備的不同有關而不是真正的不同事件,如鼠標的按下,和手指的按下。這也是我上面說的把它們理解為三個事件更為恰當。

      • START_EVENTS =>'mousedown touchstart pointerdown';
      • MOVE_EVENTS => 'mousemove touchmove pointermove';
      • END_EVENTS => 'mouseup mouseleave touchend touchcancel pointerup pointercancel';

      手勢歸納

      基本事件都是瞬間事件,不存在延時和邏輯判斷,按下就是按下,松開就是松開;這也是稱之為基本事件的原因。
      而手勢卻恰恰相反,

      • 手勢是綜合事件,如滑動手勢,直觀的感覺就是手指按下快速向左(右)滑動,并同時松開手指,這整個過程完成才是一個滑動手勢。
      • 手勢還有邏輯判斷,還是滑動手勢,不僅僅要在以上的全過程之后才激發,手指的還要超過一定的速度才能算是滑動手勢。

      因此,可以把手勢看作在基本事件之上的一個封裝,在MD的實現也是用GestureHandler的函數還偵聽基本事件然后作出綜合處理。

      偵聽

      這里是MD綁定基本事件的代碼:

      angular.element(document)
        .on(START_EVENTS, gestureStart)
        .on(MOVE_EVENTS, gestureMove)
        .on(END_EVENTS, gestureEnd)
      

      MD移動事件的偵聽處理函數:

      function gestureMove(ev) {
        if (!pointer || !typesMatch(ev, pointer)) return;
        updatePointerState(ev, pointer);
        runHandlers('move', ev);
      }
      

      其它兩個(開始和結束事件)都與此類似,只不過有更多的處理過程。這個因為簡單,可以用來好好分析關鍵過程。我們可以看到,這個偵聽函數的關鍵一步就是調用處理器(runHandler)。這個函數內部并不復雜,只是簡單的遍歷預存處理器,然后調用該處理器定義的對應的基本事件處理器。這個處理器就是手勢處理器,它會分析歸納基本事件當條件滿足時觸發手勢事件。

      手勢處理器$$MdGestureHandler

      MD用工廠(factory)的方式定義了手勢處理器的模板(或者可以理解為基類幫助理解),這個factory名稱就是$$MdGestureHandler,為了便于理解,我們把它分解成三部分來看。

      基本屏幕事件處理

      第一部分:4個方法,分別與三類基本屏幕事件對應(cancel是輔助方法),也是用來分別處理三類屏幕事件的,上面的runHandler就是調用的源頭。

      start: function(ev, pointer) {
      	if (this.state.isRunning) return;
      	var parentTarget = this.getNearestParent(ev.target);
      	var parentTargetOptions = parentTarget && parentTarget.$mdGesture[this.name] || {};
      
      	this.state = {
      	isRunning: true,
      	options: angular.extend({}, this.options, parentTargetOptions),
      	registeredParent: parentTarget
      	};
      	this.onStart(ev, pointer);
      	},
      move: function(ev, pointer) {
      	if (!this.state.isRunning) return;
      	this.onMove(ev, pointer);
      	},
      end: function(ev, pointer) {
      	if (!this.state.isRunning) return;
      	this.onEnd(ev, pointer);
      	this.state.isRunning = false;
      	},
      cancel: function(ev, pointer) {
      	this.onCancel(ev, pointer);
      	this.state = {};
      },
      
      優化的屏幕事件

      第二部分:4個內部事件,也是基本與以上4個方法對應,并在4個方法中適當的時機觸發,可以看作是對原始基本事件的梳理之后的重新拋出。 你如果創建自己的手勢處理器,要做的也就是重載這4個事件。從以下代碼我們也可以看到,MD為每一個事件給出了空實現(`angular.noop'),目的就是為了讓自定義處理器自己重載實現。

      onStart: angular.noop,
      onMove: angular.noop,
      onEnd: angular.noop,
      onCancel: angular.noop,
      
      手勢的觸發

      第三部分:也是最后最關鍵的一個方法,手勢事件的觸發dispatchEvent。自定義的手勢處理器最終都是要調用這個方法來觸發手勢事件。大部分觸發時機都在onEnd中,當是不是必須的,要根據你具體的手勢的含義來定。
      dispatchEvent的實現:

      dispatchEvent: dispatchEvent,
      ...
      /*
      * NOTE: dispatchEvent is very performance sensitive. 
      */
      function dispatchEvent(srcEvent, eventType, eventPointer, /*original DOMEvent */ev) {
      	eventPointer = eventPointer || pointer;
      	var eventObj;
      	
      	if (eventType === 'click') {
      	  eventObj = document.createEvent('MouseEvents');
      	  eventObj.initMouseEvent(
      	    'click', true, true, window, ev.detail,
      	    ev.screenX, ev.screenY, ev.clientX, ev.clientY, 
      	    ev.ctrlKey, ev.altKey, ev.shiftKey, ev.metaKey,
      	    ev.button, ev.relatedTarget || null
      	  );
      	
      	} else {
      	  eventObj = document.createEvent('CustomEvent');
      	  eventObj.initCustomEvent(eventType, true, true, {});
      	}
      	eventObj.$material = true;
      	eventObj.pointer = eventPointer;
      	eventObj.srcEvent = srcEvent;
      	eventPointer.target.dispatchEvent(eventObj);
      }
      
      

      手勢實例解析

      手勢內部實現過程雖然較為復雜,以上的流程解析也是為了更好的理解從而有個直觀的感覺。到了每一個手勢的實現時,真正用到的卻不算多,主要就是那4個優化的事件onStart, onMove, onEnd, onCancel和一個觸發的方法'dispatchEvent`。我們來看看一些手勢實例,親身感受一下,良好建模以后的手勢實現。

      滑動手勢 - Swipe
      屏幕事件 觸發條件 觸發事件
      [無]
      按下
      移動
      移動
      移動
      移動
      松開 超過最低速度和位移 $md.swiperight
      [無]
      拖動手勢 - Drag
      屏幕事件 觸發條件 觸發事件
      [無]
      按下
      移動
      移動 當前觸點與起點位移超過閥值 $md.dragstart
      移動 $md.drag
      移動 $md.drag
      松開 $md.dragend
      [無]
      posted @ 2015-04-14 10:43  予沁安  閱讀(3924)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产99青青成人A在线| 人人爽亚洲aⅴ人人爽av人人片| 国产偷国产偷亚洲高清午夜| 无码人妻丝袜在线视频| 肇庆市| 91精品国产自产91精品| 日韩无矿砖一线二线卡乱| 久久综合亚洲鲁鲁九月天| 中卫市| 鲁一鲁一鲁一鲁一澡| 91中文字幕在线一区| 亚洲中文久久久精品无码| 国产精品一区二区三区黄| 亚洲一区二区三区18禁| 亚洲男人的天堂一区二区| 博湖县| 国产一区二区不卡在线视频| 亚洲国产精品综合久久20| 国产精品国产高清国产av| 乱色欧美激惰| 国产一区二区三区亚洲精品 | 熟女一区二区中文字幕| 日本三级香港三级人妇99| 日本高清一区免费中文视频| 日韩人妻少妇一区二区三区| 国产99视频精品免费视频36| 国产精品久久无码不卡黑寡妇 | 久久99国产乱子伦精品免费| 午夜亚洲www湿好爽| av天堂午夜精品一区| 武平县| 四虎成人精品无码永久在线| 欧洲一区二区中文字幕| 丝袜美腿一区二区三区| 欧美黑人巨大videos精品| 116美女极品a级毛片| 精品久久精品午夜精品久久| 欧美日本激情| 国产农村老熟女国产老熟女| 国产日韩另类综合11页| 东方av四虎在线观看|