天天看點

移動手勢的秘密

本文是由某次部門内部分享整理而來,算是階段性的個人總結。希望對你有所幫助。

提到手勢一般都會想到見面打招呼,交警指揮交通。還有平日裡電腦、手機、PAD 上随處可見的手勢。那先來看幾個例子。

浏覽器自定義滑鼠手勢。

Mac 觸摸盤手勢

手機滑動解鎖

科幻電影中的虛拟操作(原諒我的腦洞)

不管手勢有多少種呈現方式,其實最終都是在幫助使用者完成人機互動的其中一個環節。簡單來說手勢是一種輸入方式、可以起到簡化界面元素、增加互動趣味性的作用。當然在人和人交流時也有人人互動的作用,雖然不知道有沒有這個詞。

PC 常見的輸入裝置有:滑鼠、鍵盤、攝像頭、話筒這麼幾種。移動端引入了更為豐富有用的陀螺儀和觸摸螢幕。

今天小劇打算分享的就是大家每天都要用到的觸摸手勢。手勢在移動裝置上是當之無愧的使用頻次最高的互動了。同樣先來看幾個例子。

左滑删除

切換清單

QQ空間圖像預覽

大多數移動端的圖像預覽互動都大同小異。這裡就拿上面較為複雜的 QQ空間圖檔預覽的例子來做下分析。

1、左側界面是一個普通的好友動态清單,做為圖像預覽的元件的觸發地。

輕擊圖檔:彈出對應圖檔的預覽層。

2、中間是預覽的主體界面,絕大多數預覽操作都是在這裡完成。

輕擊 :取消預覽

左右滑:切換圖檔

長按 :喚出菜單

3、右側界面是彈出菜單部分

輕擊菜單清單,進行對應操作

輕擊空白、取消按鈕關閉菜單

的确,看了上面的分析會發現,手勢也隻是在對應事件完成對應操作而已,并沒有太多複雜的地方。

真的是這樣麼?當然不是,現實往往都是很悲催的。

因為 JS 中隻有下面四個最基礎的手勢事件,各平台在名稱上有細微差異,但作用一緻。

<code>touchstart</code>:手指接觸到螢幕時觸發

<code>touchmove</code>:手指在螢幕上移動時觸發

<code>touchend</code>:手指離開螢幕是觸發

<code>touchcancel</code>:手勢事件被打斷,結束目前手勢操作,一般不觸發<code>touchend</code>

而我們需要的事件是這些,并且這還僅僅隻是單指操作。

輕擊

輕按兩下

長按

上下左右滑動

因為<code>touchcancel</code>并非完整手勢互動中的事件,是以我們隻能用上面三個最原始的事件來模拟長按、輕按兩下、輕擊、上下左右滑動這麼七個手勢。

原生事件支援如此拮據,但好在模拟單指操作的邏輯還是走得通的。通過分析手指按下之後有無移動操作,以及移動的幅度和未移動時停留的時間可以基本判定長按、輕擊、滑動這三類手勢。而通過對比上一次輕擊操作的時間間隔,同樣可以分析出事件是輕擊或輕按兩下。

至于上、下、左、右四個方向的判定,可以通過 x、y 方面上的位移絕對值的大小及正負來判定。

下圖是手勢邏輯的判定圖。

上面分析了 QQ 空間圖像預覽的例子,這裡用 web 實作了一個簡單的版本,推薦使用手機通路,或者也可以使用 chrome 模拟器。

<a href="http://bh-lay.github.io/toucher/swiper/">http://bh-lay.github.io/toucher/swiper/</a>

相比單指操作,雙指操作更為複雜。不僅涉及到不同的事件處理,而且還要同時處理兩個手指的位置及變化。具體擷取方式在後面多指操作會提到。

雙指在進行操作時需要模拟的事件一般有移動、縮放、旋轉這麼三個。剝離其他無關因素這三個手勢涉及到的計算及簡化後的軌迹大緻如下面所示。

記錄手指位置的變化。與單指手勢相似,展現在水準、垂直兩個向量上的變化x、y。

展現在兩手指距離上的變化,縮放比例為 m/n。

旋轉相對麻煩一點,需要計算的是兩手指連線的相對旋轉角度。先求得斜率差,再用反三角函數換算為角度。

其實真實手勢軌迹包含了上面三個方面,是雙指相對變化更為全面的描述方式。在同一個互動中每個行為都可能被觸發,但是在使用中可以選擇性的去響應特定行為。

在最基本的<code>touchstart</code>、 <code>touchmove</code>、 <code>touchend</code> 這三個事件中,<code>event</code>中均有三個手指與螢幕關系的清單,可以用來模拟更為複雜的手勢操作。目前 WEB 層面很少涉及個人經驗也不多,簡單介紹一下。

<code>touches</code>:目前位于螢幕上的所有手指

<code>targetTouches</code>:位于目前DOM元素上的所有手指

<code>changedTouches</code>:涉及目前事件的手指清單

因為手勢的作用并不直覺,而且相當一部分操作表意比較隐晦、使用者的學習成本較高、較為簡單的手勢更容易引起誤操作。

因而在設計手勢時,重要的互動一定有使用者引導,并且手勢需要符合正常的邏輯。每次手勢操作時均需要有效的回報,以減少使用者的顧慮。當然,危險的行為一定要加上二次确認,避免因誤操作帶來的負面影響。

上面說的都是實作層面的原理,有木有一些成熟的類庫呢?答案是一定的,下面推薦幾款流行的手勢類庫。

非常優秀的手勢類庫,支援單、雙指操作,操作流暢性能較好。

借助于 zepto 而流行起來的手勢庫,需要結合 zepto 一起使用。

百度雲團隊開發的手勢類庫,

小劇開發的手勢類庫,僅支援單指手勢操作。是小劇嘗試移動端開發時的作品,也是本文經驗的來源之處。

造這個輪子并非是為了要打敗某個類庫,而是希望從開發的過程中了解手勢的本質以及相關原理。在一次次的入坑與出坑的過程中引導自己不斷思考與反思。

繼續閱讀