為網頁加入多點觸控功能(IE10版)
0 |
之前曾以iPad為對象寫過為網頁加入多點觸控功能範例,如今支援觸控的Windows 8筆電在手,不改寫成IE10版怎能止癢?
經過簡單研究,大致整理IE10與Safari/Chrome觸控事件差異如下:
- 事件名稱不同,IE使用的不是touchstart、touchmove、touchend等名稱,而是MSPointerDown, MSPointerMove, MSPointerUp, MSPointerOver, MSPointerOut, MSPointerHover... 等。另外,還有高階的手勢事件: MSGestureTap, MSGestureHold, MSGestureStart, MSGestureChange, MSGestureEnd, MSInertiaStart,讓開發者不用自己費心追蹤各指座標變化,就能判定使用者正在縮放、旋轉動作,真是佛心來著,將來肯定要抽空玩一下才不會暴殄天物。
- MSPointerDown等事件概念與touchstart也有所差異。在touchstart中會得到touches陣列,包含多個觸控點的資料;MSPointerDown則是個每個觸控點活動都會觸發一次。
- 滑鼠也會觸發MSPointer*事件! 如只想對觸控產生反應,可用if (e.pointerType == e.MSPOINTER_TYPE_TOUCH)過濾。
- 因為事件觸發基礎不同,原先在touchmove中可以透過changedTouches取得移動中的觸控點,使用IE10則要自行比對座標值該點是否在移動。
- 要攔截觸控事件的元素需加上CSS設定: -ms-touch-action: none; 防止跟IE10預設的縮放、移動瀏覽等觸控操作打架。
- 檢查navigator.msMaxTouchPoints屬性存在與否可偵測IE是否支援觸控,由navigator.msMaxTouchPoints亦可得到裝置所支援的觸控點數。
把握以上重點,經過簡單修改,支援IE10的多點觸控展示網頁就完成囉~ 線上展示
<!DOCTYPE html>
<html>
<head>
<title>Mutli-Touch Test</title>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.4.js"
type="text/javascript"> </script>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no">
<style>
html,body {
/* 停用預設的縮放、移動瀏覽(Panning)等觸控功能, 由自訂程式接管 */
-ms-touch-action: none;
}
</style>
<script>
//http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx
$.extend($.support, { ieTouch: "msMaxTouchPoints" in window.navigator });
$(function () {
//檢查是否為支援觸控功能的IE瀏覽器
if (!$.support.ieTouch) {
$("body").html("<span>IE on touchable device only!</span>");
return;
}
//使用canvas繪製回應
var canvas = document.getElementById("sketchpad");
var ctx = canvas.getContext("2d");
//宣告變數儲存活動中觸控點的資訊
var touches = {}, changedTouches = {};
//傳回仿touchStart事件的touch物件
function createTouchObject(e) {
return { identifier: e.pointerId, pageX: e.clientX, pageY: e.clientY };
}
canvas.addEventListener("MSPointerDown", function (e) {
//由於滑鼠也會觸發,先檢查pointerType,只針對觸控做反應
if (e.pointerType != e.MSPOINTER_TYPE_TOUCH) return;
var t = createTouchObject(e);
touches[t.identifier] = t;
});
canvas.addEventListener("MSPointerMove", function (e) {
if (e.pointerType != e.MSPOINTER_TYPE_TOUCH) return;
var t = createTouchObject(e);
var origT = touches[t.identifier];
touches[t.identifier] = t;
//與前次保存資料比較,偵測點觸控點是否移動
if (origT &&
Math.abs(t.pageX - origT.pageX) + Math.abs(t.pageY - origT.pageY) > 1)
changedTouches[t.identifier] = t;
else
delete changedTouches[t.identifier];
});
canvas.addEventListener("MSPointerUp", function (e) {
if (e.pointerType != e.MSPOINTER_TYPE_TOUCH) return;
var t = createTouchObject(e);
//停止活動,將觸控點自touches及changedTouches移除
delete touches[t.identifier];
delete changedTouches[t.identifier];
});
//定義不同顏色用來追蹤多點
var colors =
("red,orange,yellow,green,blue,indigo,purple," +
"aqua,khaki,darkred,lawngreen,salmon,navy," +
"deeppink,brown,olive,violet,tomato,gray").split(',');
//在canvas繪製追蹤點
ctx.lineWidth = 3;
ctx.font = "10pt Arial";
var r = 40;
function drawPoint(i, x, y, c, id, chg) {
ctx.beginPath();
ctx.fillStyle = c;
//若屬changedTouches則顯示黑框
ctx.strokeStyle = chg ? "#000" : c;
ctx.arc(x, y, r, 0, 2 * Math.PI, true);
ctx.fill();
ctx.stroke();
//顯示touch的identifier及其在陣列中的序號
//touches在上排藍字,chagedTouches在下排紅字
ctx.fillStyle = chg ? "red" : "blue";
ctx.fillText(id,
x - r, y - r - 25 + (chg ? 15 : 0));
}
//清除canvas
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
//利用identifier識別,相同時要保持同一個顏色
var touchHash = {}, colorIdx = 0;
function getColor(id) {
if (touchHash[id] == undefined)
touchHash[id] = ++colorIdx % colors.length;
return colors[touchHash[id]];
}
//每秒更新20次,顯示目前的多點觸控資訊
setInterval(function () {
clearCanvas();
//console.log(JSON.stringify(touches));
for (var i in touches) {
var t = touches[i];
drawPoint(i, t.pageX, t.pageY, getColor(t.identifier),
t.identifier);
}
for (var i in changedTouches) {
var t = changedTouches[i];
drawPoint(i, t.pageX, t.pageY, getColor(t.identifier),
t.identifier, true);
}
}, 50);
});
</script>
</head>
<body style="padding: 0px; margin: 0px;">
<canvas id="sketchpad" width="1366" height="760" style="border: 1px solid gray">
</canvas>
</body>
</html>
實測結果如下: (幸好最多只有10點,不然連腳都要舉起來"觸控"才能完成測試,肯定抽筋)
Comments
Be the first to post a comment