[Javascript] Something about pinch gestures

Image Credit

pinch-gesture

最近一直在研究如何在 Browser 上支援 Mac touchpad 的 Pinch 手勢,所以有一些心得想要記錄一下。

3rd party libraries

一開始的想法就覺得這種事情應該有什麼 3rd party 套件有支援了,只要簡單的把 event 和現有的程式接上就可以了。不過找了一陣子後,實在是沒有找到什麼好東西,通常大家推的都是 Hammer.js,不過其實這個 library 是專門設計給 mobile app 使用的,看了一下程式碼發現是組合 touch 相關的 event 後再經過數學運算後提供客製化的 gesture event 像是 pinchpan … 之類的。

不過這個和我的使用情境不太一樣,因為 gesture 相關的 event 只有在 mobile 的 browser 上才會存在,因此只能再找找別的方法。

Solutions

之後很幸運的找到了 Chromium 開發者們的討論串,主要在討論的內容就是要如何把 touchpad 上的 pinch 手勢透過 wheel 這個 event 傳出去!那個討論串主要的重點就是在於 2014 年五月之後,Chromium 開發者們上了一個 patch,讓前端開發者可以透過正規的 wheel event (對了,wheelmousewheel 有點不太一樣,前者才是大家公認的標準,後者則是非標準,只有少部分的 browser 有支援,要注意一下)去偵測 pinch gesture 的觸發。當 wheel event 是透過 pinch 觸發的話,那傳進來的 event 的 ctrlKey 這個屬性則會被設成 true,所以開發者們就可以用這個值來做判斷。

而在我們公司裡,因為我們要監聽這個手勢的發生做客製化的視覺處理,而且我們不希望 Mac 上預設的 zoom in / zoom out 還被觸發,所以要記得透過 event.preventDefault() 來避免 Browser 做 zoom in / zoom out 的動作。

Limitations

當然世界沒這麼美好,所以我最後還是整理了一些目前的限制(以後說不定就沒這個問題)

  • Safari
    1. 目前我手上最新的 Safari 9.0.x 版(Mac OS X 10.11.x)是沒辦法透過上面的方法來偵測手勢及取消預設的 zoom in / zoom out 觸發。
    2. 好消息是在未來的 Safari 9.1.x 版後,他們提供了新的 gesture event 讓開發者們可以去偵測手勢,不過這個版本目前也還沒釋出所以也沒辦法測試,如果官方文件沒有唬爛的話那就應該是可以支援,只是這個 event 目前應該也是 Safari only 的客製化 event 就是了,會不會變成 standard 也不知道。
  • Chrome
    1. 在 2014 年五月後的 Chrome 就支援上述做法來偵測 pinch 手勢了!(我很想查 Chrome 的版本號只是不知道怎麼找,如果有人知道那個 patch 實際被 land 到哪個版本的話,請和我說一下)
    2. 個人 Chrome 48+ 實測是 ok 的。
  • IE / Edge
    1. 如果討論串上的資訊正確的話,那 IE / Edge 應該和 Chrome 一樣有支援 ctrlKey 可以讓開發者去做偵測。
  • Firefox
    1. 無解 …
  • Electron
    1. 我有測試過 Electron 0.36.x+,因為他的核心也是 Chromium,所以這個做法也是可以支援的!
    2. 如果你是用 <webview> 的方式來載入你的 web app 的話,那你特別需要先在 render view 的地方聽  wheel event 但是不需要做任何事(超怪,無法理解),這樣這個 wheel event 就會正確的被傳進你的 <webview>,然後你的 webview 裡面如果有實作 event.preventDefault() 的話,那預設的 zoom in / zoom out 行為就會被取消,這樣你就可以在 webview (也就是你的網站裡面處理這件事情就好)

References

附上所有我找到的有用資源如下:

  1. http://jsbin.com/qiyaseza/8/edit?html,css,js,output
  2. https://bugs.chromium.org/p/chromium/issues/detail?id=289887
  3. http://stackoverflow.com/questions/15416851/catching-mac-trackpad-zoom
  4. http://stackoverflow.com/questions/29929411/disable-pinch-zoom-in-webkit-or-electron
  5. https://gist.github.com/NekR/9a80ebe73573e11f0351