2011年10月4日 星期二

為網頁加入多點觸控功能

http://blog.darkthread.net/post-2011-10-02-html5-mutli-touch.aspx



為網頁加入多點觸控功能

相信大家應該看過不少用HTML5做的繪圖板範例(例如: 這個這個這個這個),事實上,只要一個canvas元素配合mousedown, mousemove, mouseup事件,加上幾行Code我們就可以自己寫一個陽春手繪板。不過,這種陽春寫法在iPad、iPhone、Android等觸控平台瀏覽器就吃不開了。
在觸控操作時,自然不會有mousedown、mousemove、mouseup這些事件(難道得抓一隻黃金鼠在螢幕上磨蹭嗎?),而是另外定義了touchstart、touchmove、touchend等觸控平台的專屬事件(參考: iOS APIW3C草案),HTML5 Rocks有一篇很棒的文章介紹開發支援觸控事件網頁的相關知識,小小地研究一番,以下是我的心得筆記:
  1. 在touchstart、touchmove、touchend等事件中,可透過事件參數的touches屬性取得多個觸點位置,可以實現多點觸控甚至捕捉複雜手勢的網頁。(但偵測手勢的演算法會是一大挑戰)
  2. 事件參數提供了touches(螢幕上所有的觸點)、targetTouchs(接觸到特定DOM元素的觸點)、changedTouches(目前事件中發生變化的觸點,例如: touchmove事件移動中的觸點或touchend事件離開螢幕的觸點)等觸點資訊。
  3. 上述觸點資訊物件會提供幾個屬性: identifier(識別碼,可供在多個事件中持續追蹤同一觸點的變化)、target(觸點所操作的DOM元素)、client/page/screen座標(相對於元素、網頁、螢幕的座標)、radius座標及rotationAngle(可用來描述手指接觸面形狀,但目前尚無瀏覽器支援)
  4. 為避免原本瀏覽器的兩指縮放、拖拉捲動操作干擾,可加入viewpoint meta及加掛document.body touchmove事件將其停用,寫法如下: 
     
    document.body.addEventListener('touchmove', function(event) { 
      event.preventDefault(); 
    }, false);
  5. 由於touchmove的觸發頻率很高,若每次被呼叫就立即執行回應邏輯,可能造成系統過度負擔,因此可在touchmove時將touches等資訊保存下來,再透過setInterval以固定頻率執行回應邏輯。(window.requestAnimationFrame會依瀏覽器更新動畫的頻率觸發,可完全配合裝置基於效能及省電考量下的動態調整,算是更好的解決方案,但要考量瀏覽器是否有支援)
  6. 在PC環境下摸擬觸控效果可降低開發及測試的難度,有個很不錯的Touchable jQuery Plugin可以將mousedown/mousemove/mouseup對應成觸控事件。事實上,它另外定義了tap、touchablemove、touchableend等事件,可同時對應到滑鼠操作及觸控,讓網頁程式可同時支援滑鼠及觸控兩種操作平台,如果網頁只要做到單點觸控,算是很好的跨平台選擇。
  7. 針對MacBook或MagicPad等支援多點觸控的裝備,HTML5 Rocks文章有提供一套在Mac實現瀏覽器多點觸控的方法。
  8. 從jquery.UI.iPad plugin偷學到簡單偵測瀏覽器是否支援觸控的方法: 
    $.extend($.support, { touch: "ontouchend" in document }); 
    以上程式碼擴充了jQuery,如此便可由$.support.touch傳回true或false偵測是否瀏覽器是否有觸控功能囉~
光說不練是嘴砲,實彈射擊不可少!
想實地觀察多點觸控事件所能擷取的資訊,所以我寫了以下的測試網頁:
排版顯示純文字
DOCTYPE html>
 
<html>
<head>
    <title>Mutli-Touch Testtitle>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.4.js" 
            type="text/javascript"> script>   
    "viewport" 
     content="width=device-width, initial-scale=1.0, user-scalable=no">
    
blog comments powered by Disqus