any-touch 一個手勢庫git
用 TypeScript 開發手勢庫 - (1)web開發經常使用手勢有哪些?github
用 TypeScript 開發手勢庫 - (2)web開發經常使用手勢有哪些?web
不到30行, 用any-touch實現一個drawertypescript
爲了同時支持鼠標和touch設備, 咱們第一步把2種設備產生數據統一化, 統一化後的數據咱們統一叫他input.segmentfault
input包含11個字段,4個基礎字段,7個快捷字段, 這些都是爲下一步進行計算處理(computed)使用.數組
input包含4個基礎字段:eventType / point / changedPoints / nativeEvent, 接下來依次解釋.瀏覽器
eventType能夠理解爲輸入狀態, 如touchstart/mousedown對應start, touchmove/mousemove對應move, touchend/mouseleave對應end, touchcancel對應cancel, 總計4種狀態.架構
觸點信息, 存儲當前觸點相對瀏覽器窗口左上角的座標(clientX, clientY), point是個數組, 存儲當前的全部觸點.函數
發生變化的觸點信息, 是個數組, 存儲着上一次觸點相對當前觸點發生變化的觸點(初看有些繞, 如不明可留言.).spa
若是是touch設備, 那麼對應touchEvent, 鼠標對應MouseEvent.
處理touchEvent
export default (event: TouchEvent): any => { const point = Array.from(event.touches).map(({clientX,clientY})=>({clientX,clientY})); const changedPoints = Array.from(event.changedTouches).map(({clientX,clientY})=>({clientX,clientY})); const eventType = event.type.replace('touch', ''); return { eventType, changedPoints, point, nativeEvent: event, }; };
處理mouseEvent
let prevPoints: { clientX: number, clientY: number }[]; let isPressed = false; // 默認MouseEvent中對type聲明僅爲string export default (event: MouseEvent): BaseInput | void => { let { clientX, clientY, type, button } = event; const changedPoints = prevPoints || [{ clientX, clientY }]; let points = [{ clientX, clientY }]; prevPoints = [{ clientX, clientY }]; // 必須左鍵 if ('mousedown' === type) { if (0 === button) { isPressed = true; } else { return; } } if ('mousemove' === type) { if (!isPressed) return; } else if ('mouseup' === type) { if (isPressed) { points = []; } else { return; }; isPressed = false; } const MAP = { mousedown: 'start', mousemove: 'move', mouseup: 'end' }; return { eventType: <eventType>MAP[<'mousedown' | 'mousemove' | 'mouseup'>type], changedPoints, points, nativeEvent: event }; };
快捷字段均由基礎字段簡單衍生而來, 僅爲了使用方便而直接放在這.
對應point數組的長度.
對應changedPoints的長度.
當前時間戳.
綁定事件的元素.
觸發事件所在元素.
觸點座標, 若是是多點, 那麼對應多點的中心座標(getCenter函數源碼).
對應center.x和center.y
是否本輪識別週期的開始, 若是當前的eventType爲start階段, pointLength和changedPointLength的長度相等, 那麼能夠斷定, 當前爲開始.
是否本輪識別週期的結束, 若是當前的eventType爲end或者cancel階段, 且全部觸點均離開, 那麼斷定爲結束.
擴展字段的源碼比較長, 請移步至倉庫.
下期咱們會講解computed, 計算階段比較複雜, 設計到input的開始/前一個/當前狀態的計算, 你們能夠提早預熱.