HTML5中Canvas的事件處理介紹
DOM是Web前端領域非常重要的組成部分,不僅在處理HTML元素時會用到DOM,圖形編程也同樣會用到。比如SVG繪圖,各種圖形都是以DOM節點的形式插入到頁面中,這就意味着可以使用DOM方法對圖形進行操作。比如有一個 元素,可以直接用jquery增加click事件$('#p1')k(function(){…})"。然而這種DOM處理方法在HTML5的Canvas裏不再適用,Canvas使用的是另外一套機制,無論在Canvas上繪製多少圖形,Canvas都是一個整體,圖形本身實際都是Canvas的一部分,不可單獨獲取,所以也就無法直接給某個圖形增加JavaScript事件。
Canvas的限制
在Canvas裏,所有圖形都繪製在幀上,繪製方法不會將繪製好的圖形元素作為一個返回值輸出,js也無法獲取到已經繪製好的圖形元素。比如:
代碼如下:
cvs = lementById('mycanvas');
ctx = ontext('2d');
theRect = (10, 10, 100, 100);
ke();
(theRect); //undefined
這段代碼在canvas標籤裏繪製了一個矩形,首先可以看到繪製圖形的rect方法沒有返回值。如果打開瀏覽器的開發者工具,還可以看到canvas標籤內部沒有增加任何內容,而在js裏獲取到的canvas元素以及當前的上下文,也都沒有任何表示新增圖形的內容。
所以,前端常用的dom方法在canvas裏是不適用的。比如點擊上面Canvas裏的矩形,實際點擊的是整個Canvas元素。
給Canvas元素綁定事件
由於事件只能達到Canvas元素這一層,所以,如果想進一步深入,識別點擊發生在Canvas內部的哪一個圖形上,就需要增加代碼來進行處理。基本思路是:給Canvas元素綁定事件,當事件發生時,檢查事件對象的位置,然後檢查哪些圖形覆蓋了該位置。比如上面的例子裏畫過一個矩形,該矩形覆蓋x軸10-110、y軸10-110的範圍。只要鼠標點擊在這個範圍裏,就可以視為點擊了該矩形,也就可以手動觸發矩形需要處理的點擊事件。思路其實比較簡單,但是實現起來還是稍微有點複雜。不僅要考慮這個判斷過程的效率,有些地方還需要重新判斷事件類型,設置要重新定義一個Canvas內部的捕獲和冒泡機制。
首先要做的,是給Canvas元素綁定事件,比如Canvas內部某個圖形要綁定點擊事件,就需要通過Canvas元素代理該事件:
代碼如下:
cvs = lementById('mycanvas');
ventListener('click', function(e){
//...
}, false);
接下來需要判斷事件對象發生的位置,事件對象e的layerX和layerY屬性表示Canvas內部座標系中的座標。但是這個屬性Opera不支持,Safari也打算移除,所以要做一些兼容寫法:
代碼如下:
function getEventPosition(ev){
var x, y;
if (rX || rX == 0) {
x = rX;
y = rY;
} else if (etX || etX == 0) { // Opera
x = etX;
y = etY;
}
return {x: x, y: y};
}
//注:使用上面這個函數,需要給Canvas元素的position設為absolute。
現在有了事件對象的座標位置,下面就要判斷Canvas裏的圖形,有哪些覆蓋了這個座標。
isPointInPath方法
Canvas的isPointInPath方法可以判斷當前上下文的圖形是否覆蓋了某個座標,比如:
代碼如下:
cvs = lementById('mycanvas');
ctx = ontext('2d');
(10, 10, 100, 100);
ke();
intInPath(50, 50); //true
intInPath(5, 5); //false
接下來增加一個事件判斷,就可以判斷一個點擊事件是否發生在矩形上:
代碼如下:
ventListener('click', function(e){
p = getEventPosition(e);
if(intInPath(p.x, p.y)){
//點擊了矩形
}
}, false);
以上就是處理Canvas事件的基本方法,但是上面的代碼還有侷限,由於isPointInPath方法僅判斷當前上下文環境中的路徑,所以當Canvas裏已經繪製了多個圖形時,僅能以最後一個圖形的上下文環境來判斷事件,比如:
代碼如下:
-
如何理解Javascript的caller,callee,call,apply區別
在提到上述的概念之前,首先想説説javascript中函數的隱含參數:argumentsarguments該對象代表正在執行的函數和調用它的函數的參數。[function.]arguments[n]參數function:選項。當前正在執行的Function對象的名字。n:選項。要傳遞給Function對象的從0開始的參數值...
-
php程序員的簡歷模板
日子如同白駒過隙,新一輪的招聘又在朝我們招手,這時一份好的簡歷可以起到很好的.作用哦。那麼如何寫簡歷才簡練、明確呢?以下是小編收集整理的php程序員的簡歷模板,希望能夠幫助到大家。基本簡歷姓名:黃先生國籍:中國現在所在地:廣州民族:漢族户口所在地:潮州身材:170cm...
-
ASP.NET 2.0 程序的基礎知識
成員關係的概念在人類社會中是一個層次比較低的概念,源於希望屬於某個羣組的意識。我們希望能覺得自己是某個團隊的一部分,讓別人知道我們是誰,因此Web搭上這個流行趨勢,採用這個概念只是時間早晚的問題。如果坐下來想一想曾經登錄過多少個站點並在這些站點上保存...
-
如何理解Javascript的caller,callee,call,apply區別
在提到上述的概念之前,首先想説説javascript中函數的隱含參數:argumentsarguments該對象代表正在執行的函數和調用它的函數的參數。[function.]arguments[n]參數function:選項。當前正在執行的Function對象的名字。n:選項。要傳遞給Function對象的從0開始的參數值...