鼠標事件
canvas.onmousedown = function(e ) {//React to the mouse down event };
canvas.addEventListener('mousedown', function(e ) { //React to the mouse down event});
上面一種方法看起來更簡單一些,但是,如果需要向某個鼠標事件注冊多個監聽器的話,那么用addEventListener()方法會更合適。
瀏覽器通過事件對象傳遞給監聽器的鼠標坐標,是窗口坐標(window coordinate),而不是相對與canvas自身的坐標。而大部分情況下,開發者需要知道的是發生鼠標事件的點相對於canvas的位置,而不是在整個窗口中的位置,所以有必要進行坐標變換。
function windowToCanvas(canvas, x, y) { var bbox = canvas.getBoundingClientRect();
return { x: x – bbox.left * (canvas.width / bbox.width), y: y – bbox.top * (canvas.height / bbox.height) }; }
上述方法,在canvas對象上調用getBoundingClientRect()方法,來獲取canvas元素的邊界框,該邊界框的坐標是相對於整個窗口的。然后返回一個對象,該對象的x、y屬性分別對應於鼠標在canvas之中的坐標。該方法不止是對兩個坐標進行平移縮放,在canvas元素大小與繪圖表面大小不相符時,它還對這兩個坐標進行了縮放。
canvas元素實際上有兩套尺寸,一個是元素本身的大小,還有一個是元素繪圖表面(drawing surface)的大小。以內聯方式設置width和height屬性,實際上是同時設置了元素本身的大小與元素繪圖表面的大小。然而,如果通過CSS來設定canvas元素的大小,那么只會改變元素本身的大小,而不會影響到繪圖表面。
如果css設定的canvas元素大小域其繪圖表面大小不同,瀏覽器就會對繪圖表面進行縮放,使其符合元素的大小,類似於設定了圖片的寬與高,但是與圖片本身尺寸不同,那么,圖片會被拉伸一樣。
鍵盤事件
canvas是一個不可獲取焦點的元素,所以,在canvas上新增鍵盤事件監聽器是徒勞的。如果想要檢測鍵盤事件的話,你應該在document或window對象上新增鍵盤事件監聽器才對。
keydown
keypress
keyup
keydown與keyup是底層事件,幾乎每次按鍵時都會觸發這些事件。
觸摸事件
移動端觸摸事件與桌面平台的鼠標事件有兩個主要的不同點
- 鼠標光標只有一個i額,而觸摸點可能有很多
- 鼠標光標可以懸停(hover),而觸摸點則不行
處理觸摸事件的方式,在許多方面與處理鼠標事件相似,例如
canvas.ontouchstart = function(e ) { alert("touch start"); };
canvas.addEventListener("touchstart", function(e ) { alert("touch start"); });
觸摸事件
事件類型 |
是否可以取消 |
是否走完整個冒泡式觸發過程 |
描述 |
瀏覽器對該事件的默認處理方式 |
touchstart |
是 |
是 |
用戶將某個觸摸點置於觸摸界面上 |
未定義 |
touchmouve |
是 |
是 |
在觸摸界面上移動觸摸點 |
未定義 |
touchend |
是 |
是 |
觸摸點離開了觸摸區域 |
根據具體情況而定,可能將其視為:mousemove,mousedown、mouseup、click |
touchcancel |
是 |
是 |
觸摸點的觸摸動作被打斷,或是觸摸點個數超出了設備所能處理的范圍 |
未定義 |
touchevent對象的屬性
屬性名 |
屬性值的數據類型 |
描述 |
touches |
TouchList |
由正在界面上觸摸的各個觸摸點所組成的列表 |
changedTouches |
TouchList |
與上次觸摸事件相比,發生改變的各個觸摸點,對於touchstart事件來說,它表示那些剛剛被激活的觸摸點。對於touchmove事件來說,表示那些位置發生了移動的觸摸點。對於touchend與touchcancel來說,表示那些不再停留於觸摸界面之上的觸摸點 |
targetTouches |
TouchList |
正在界面上觸摸而且位於當前元素范圍之內的那些觸摸點。除非某個觸摸點被拖到了元素范圍之外,否則該列表就等同於touches列表 |
altKey ctrlKey metaKey shiftKey |
boolen |
如果在觸摸事件發生時,與之對應的按鍵Alt Ctrl Meta或Shift處於被按下的狀態,那么其值就是true,由於某些移動設備並沒有物理鍵盤,所以這些屬性的值可能是不確定的。 |
TouchList對象
TouchList對象有兩個屬性
length
Touch identifiedTouch(identifier)
給定某個TouchList對象,可以可以通過length屬性獲取列表中所含Touch對象的個數
canvas.ontouchstart = function(e) {alert("e.touches.length + ' touches on the device'); };
可以像操作數組那樣,訪問TouchList之中的每一個Touch元素
canvas.ontouchstart = function(e) { for var i=0;i<e.touches.length; ++i} { alert("Touch at: " + e.touches[i].pageX + "," + e.touches[i].pageY); } };
Touch對象
觸摸事件監聽器最終還是需要檢查Touch對象本身的屬性。
屬性名 |
屬性值的數據類型 |
描述 |
clientX |
long |
觸摸點相對於視窗的X坐標,該值不包含滾動條寬度 |
clientY |
long |
Y坐標,不包含滾動條高度 |
identifier |
long |
代表觸摸點身份的獨特標識符,同一個觸摸點的身份標識符在不同的事件中保持不變 |
pageX |
long |
觸摸點相對於視窗的X坐標,包含滾動條的寬度 |
pageY |
long |
相對於視窗的Y坐標,包含滾動條高度 |
screenX |
long |
觸摸點相對於屏幕的X坐標 |
screenY |
long |
觸摸點相對於屏幕的Y坐標 |
target |
EventTarget |
觸摸動作開始時,觸摸點所在的元素。就算該點其后被拖出了初始元素,target依然會指向一開始的那個元素。 |
tips:在事件對象上調用preventDefault()方法,可阻止瀏覽器對該事件采取諸如滾動網頁等默認的處理動作。此方法可以避免各種開發者不想看到的瀏覽器互動操作,如縮放頁面、偶然選取了網頁內容,以及div閃爍等。
手指縮放
對於類型為touchstart及touchmove的觸摸事件,如果發現有兩個點同時在觸摸設備,而且它們中至少有一個位置發生了變化,那么就判定用戶在pinch屏幕。如果程序發現用戶正在pinch屏幕,用於處理touchstart事件的方法會計算兩個觸摸點之間的距離,以及當前放大倍數與該距離的比值。在touchmove事件的方法也會計算當前兩個觸摸點之間的距離,並且將該值乘以剛才計算好的比值,就可以得到新的放大倍數。
