婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > HTML5 Canvas的事件處理介紹

HTML5 Canvas的事件處理介紹

熱門標簽:外呼系統電話怎么投訴 呼和浩特外呼電銷系統排名 申請400電話流程簡介 pageadm實現地圖標注 邢臺縣地圖標注app 南通數據外呼系統推廣 外呼線穩定線路 阜陽企業外呼系統 地圖標注位置能賺錢嗎

DOM是Web前端領域非常重要的組成部分,不僅在處理HTML元素時會用到DOM,圖形編程也同樣會用到。比如SVG繪圖,各種圖形都是以DOM節點的形式插入到頁面中,這就意味著可以使用DOM方法對圖形進行操作。比如有一個<path id="p1">元素,可以直接用jquery增加click事件$('#p1').click(function(){…})"。然而這種DOM處理方法在HTML5的Canvas里不再適用,Canvas使用的是另外一套機制,無論在Canvas上繪制多少圖形,Canvas都是一個整體,圖形本身實際都是Canvas的一部分,不可單獨獲取,所以也就無法直接給某個圖形增加JavaScript事件。

Canvas的限制

在Canvas里,所有圖形都繪制在幀上,繪制方法不會將繪制好的圖形元素作為一個返回值輸出,js也無法獲取到已經繪制好的圖形元素。比如:


復制代碼
代碼如下:

cvs = document.getElementById('mycanvas');
ctx = canvas.getContext('2d');
theRect = ctx.rect(10, 10, 100, 100);
ctx.stroke();
console.log(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 = document.getElementById('mycanvas');
cvs.addEventListener('click', function(e){
//...
}, false);

接下來需要判斷事件對象發生的位置,事件對象e的layerX和layerY屬性表示Canvas內部坐標系中的坐標。但是這個屬性Opera不支持,Safari也打算移除,所以要做一些兼容寫法:


復制代碼
代碼如下:

function getEventPosition(ev){
var x, y;
if (ev.layerX || ev.layerX == 0) {
x = ev.layerX;
y = ev.layerY;
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
x = ev.offsetX;
y = ev.offsetY;
}
return {x: x, y: y};
}
//注:使用上面這個函數,需要給Canvas元素的position設為absolute。

現在有了事件對象的坐標位置,下面就要判斷Canvas里的圖形,有哪些覆蓋了這個坐標。

isPointInPath方法

Canvas的isPointInPath方法可以判斷當前上下文的圖形是否覆蓋了某個坐標,比如:


復制代碼
代碼如下:

cvs = document.getElementById('mycanvas');
ctx = canvas.getContext('2d');
ctx.rect(10, 10, 100, 100);
ctx.stroke();
ctx.isPointInPath(50, 50); //true
ctx.isPointInPath(5, 5); //false

接下來增加一個事件判斷,就可以判斷一個點擊事件是否發生在矩形上:


復制代碼
代碼如下:

cvs.addEventListener('click', function(e){
p = getEventPosition(e);
if(ctx.isPointInPath(p.x, p.y)){
//點擊了矩形
}
}, false);

以上就是處理Canvas事件的基本方法,但是上面的代碼還有局限,由于isPointInPath方法僅判斷當前上下文環境中的路徑,所以當Canvas里已經繪制了多個圖形時,僅能以最后一個圖形的上下文環境來判斷事件,比如:

復制代碼
代碼如下:

cvs = document.getElementById('mycanvas');
ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.rect(10, 10, 100, 100);
ctx.stroke();
ctx.isPointInPath(20, 20); //true
ctx.beginPath();
ctx.rect(110, 110, 100, 100);
ctx.stroke();
ctx.isPointInPath(150, 150); //true
ctx.isPointInPath(20, 20); //false

從上面這段代碼可以看到,isPointInPath方法僅能識別當前上下文環境里的圖形路徑,而之前繪制的路徑,無法回溯判斷。這種問題的解決方法是:當點擊事件發生時,重繪所有圖形,每繪制一個就使用isPointInPath方法,判斷事件坐標是否在該圖形覆蓋范圍內。

循環重繪和事件冒泡

為了實現循環重繪,所以就要將圖形的基本參數事先保存下來:

復制代碼
代碼如下:

arr = [
{x:10, y:10, width:100, height:100},
{x:110, y:110, width:100, height:100}
];

cvs = document.getElementById('mycanvas');
ctx = canvas.getContext('2d');

draw();

function draw(){
ctx.clearRech(0, 0, cvs.width, cvs.height);
arr.forEach(function(v){
ctx.beginPath();
ctx.rect(v.x, v.y, v.width, v.height);
ctx.stroke();
});
}

上面的代碼事先將兩個矩形的基本參數保存下來,每次調用draw方法,就會循環調用這些基本參數,用于繪制兩個矩形。這里還使用了clearRect方法,用于在重繪時清空畫布。接下來要做的是增加事件代理,以及在重繪時對每一個上下文環境使用isPointInPath方法:


復制代碼
代碼如下:

cvs.addEventListener('click', function(e){
p = getEventPosition(e);
draw(p);
}, false);

事件發生時,將事件對象的坐標傳給draw方法處理。這里還需要對draw方法做一些小改動:


復制代碼
代碼如下:

function draw(p){
var who = [];
ctx.clearRech(0, 0, cvs.width, cvs.height);
arr.forEach(function(v, i){
ctx.beginPath();
ctx.rect(v.x, v.y, v.width, v.height);
ctx.stroke();
if(p && ctx.isPointInPath(p.x, p.y)){
//如果傳入了事件坐標,就用isPointInPath判斷一下
//如果當前環境覆蓋了該坐標,就將當前環境的index值放到數組里
who.push(i);
}
});
//根據數組中的index值,可以到arr數組中找到相應的元素。
return who;
}

在上面代碼中,點擊事件發生時draw方法會執行一次重繪,并在重繪過程中檢查每一個圖形是否覆蓋了事件坐標,如果判斷為真,則視為點擊了該圖形,并將該圖形的index值放入數組,最后將數組作為draw方法的返回值。在這種處理機制下,如果Canvas里有N個圖形,它們有一部分是重疊的,而點擊事件恰巧發生在這個重疊區域上,那么draw方法的返回數組里會有N個成員。這時就有點類似事件冒泡的情況,數組的最后一個成員處于Canvas最上層,而第一個成員則在最下層,我們可以視為最上層的成員是e.target,而其他成員則是冒泡過程中傳遞到的節點。當然這只是最簡單的一種處理方法,如果真要模擬DOM處理,還要給圖形設置父子級關系。

以上就是Canvas事件處理的基本方法。在實際運用時,如何緩存圖形參數,如何進行循環重繪,以及如何處理事件冒泡,都還需要根據實際情況花一些心思去處理。另外,click是一個比較好處理的事件,相對麻煩的是mouseover、mouseout和mousemove這些事件,由于鼠標一旦進入Canvas元素,始終發生的都是mousemove事件,所以如果要給某個圖形單獨設置mouseover或mouseout,還需要記錄鼠標移動的路線,給圖形設置進出狀態。由于處理的步驟變得復雜起來,必須對性能問題提高關注。

標簽:楊凌 蚌埠 辛集 撫順 內蒙古 鶴崗 黃山 德州

巨人網絡通訊聲明:本文標題《HTML5 Canvas的事件處理介紹》,本文關鍵詞  HTML5,Canvas,的,事件,處理,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《HTML5 Canvas的事件處理介紹》相關的同類信息!
  • 本頁收集關于HTML5 Canvas的事件處理介紹的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    另类小说视频一区二区| 久久蜜桃av一区精品变态类天堂| 国产在线国偷精品免费看| 日本欧美在线看| 日本vs亚洲vs韩国一区三区| 免费成人美女在线观看.| 免费看精品久久片| 紧缚捆绑精品一区二区| 国产成人在线视频播放| 成人h动漫精品一区二区| 色综合久久综合网97色综合| 欧美三级电影网| 日韩一区二区中文字幕| 久久蜜桃一区二区| 亚洲日本一区二区三区| 婷婷综合另类小说色区| 精品无人区卡一卡二卡三乱码免费卡| 激情综合色播激情啊| 成人精品小蝌蚪| 欧美日韩国产电影| 久久久久久麻豆| 亚洲男人都懂的| 美女网站色91| www.亚洲激情.com| 3751色影院一区二区三区| 久久综合精品国产一区二区三区| 中文字幕一区二区三区av| 三级精品在线观看| 成人性生交大片免费看在线播放| 欧美在线啊v一区| 久久精品一区四区| 亚洲综合小说图片| 国产精品一区一区三区| 欧美日韩色一区| 国产女同性恋一区二区| 无码av免费一区二区三区试看| 韩国av一区二区三区四区| 91麻豆国产精品久久| 精品精品国产高清一毛片一天堂| 国产精品护士白丝一区av| 免费人成在线不卡| 在线观看成人免费视频| 国产欧美一区二区精品久导航| 亚洲高清不卡在线| 91在线精品一区二区三区| 欧美一级片免费看| 亚洲最大色网站| 99天天综合性| 国产欧美综合在线| 激情久久五月天| 欧美日本精品一区二区三区| 亚洲欧洲中文日韩久久av乱码| 国产精品一区二区三区99| 日韩一区二区三区精品视频 | 91精品国产一区二区人妖| 亚洲欧美另类久久久精品| 国产一区 二区| 精品国产免费久久| 欧美a级一区二区| 91精品午夜视频| 亚洲国产欧美日韩另类综合| 色综合中文综合网| 国产精品视频第一区| 国产精品系列在线播放| 日韩三级中文字幕| 蜜臀av国产精品久久久久 | 国模娜娜一区二区三区| 91.xcao| 午夜精品在线看| 9191国产精品| 美女在线观看视频一区二区| 日韩一卡二卡三卡四卡| 六月丁香综合在线视频| 久久综合狠狠综合久久综合88| 老司机免费视频一区二区三区| 精品国产污网站| 国产精品456| 成人免费在线观看入口| 色综合久久综合网欧美综合网| 亚洲欧美日韩精品久久久久| 在线一区二区视频| 日韩专区欧美专区| 亚洲精品一区二区三区香蕉| 成人中文字幕合集| 一区二区三区欧美| 91精品国产综合久久久久久| 精品中文字幕一区二区| 欧美激情资源网| 在线影院国内精品| 日本亚洲免费观看| 久久影院电视剧免费观看| 成人免费视频一区| 亚洲精品国产视频| 91精品国产91久久久久久一区二区 | 夜夜爽夜夜爽精品视频| 这里只有精品电影| 国产精华液一区二区三区| 中文字幕在线免费不卡| 欧美日韩免费在线视频| 美美哒免费高清在线观看视频一区二区| 精品成人一区二区| 色猫猫国产区一区二在线视频| 天堂av在线一区| 国产欧美精品日韩区二区麻豆天美| 色综合天天综合色综合av| 青青草91视频| 亚洲另类春色国产| 欧美精品一区二区三区在线| av在线这里只有精品| 日韩电影在线观看电影| 亚洲视频在线观看一区| 日韩欧美中文字幕精品| 99精品在线免费| 国产在线播放一区二区三区| 亚洲裸体在线观看| 久久先锋资源网| 91精品国产手机| 色综合一个色综合| 成人精品一区二区三区中文字幕| 日韩电影在线一区| 亚洲伊人伊色伊影伊综合网| 国产精品网站一区| 久久你懂得1024| 日韩视频在线一区二区| 欧美日韩精品一区二区三区四区| 国产精品99久久久| 久久机这里只有精品| 亚洲成人av电影在线| 亚洲欧美区自拍先锋| 国产日韩成人精品| 久久综合精品国产一区二区三区| 欧美精品xxxxbbbb| 欧美日本一区二区| 欧美日韩你懂得| 欧美色综合影院| 91国偷自产一区二区使用方法| 99久久久久免费精品国产| 懂色av一区二区夜夜嗨| 久久狠狠亚洲综合| 久久精品国产亚洲一区二区三区| 偷拍自拍另类欧美| 丝袜诱惑制服诱惑色一区在线观看| 玉足女爽爽91| 亚洲成人av免费| 视频一区二区中文字幕| 亚洲午夜精品在线| 丝袜美腿亚洲色图| 蜜桃在线一区二区三区| 蜜臀久久久99精品久久久久久| 天天影视网天天综合色在线播放| 偷拍与自拍一区| 日韩av中文字幕一区二区 | 亚洲一区二区三区视频在线播放| 国产精品传媒视频| 一区二区三区在线播放| 亚洲电影中文字幕在线观看| 亚洲123区在线观看| 日本免费在线视频不卡一不卡二| 久久精品国产秦先生| 激情综合网激情| 99久久久无码国产精品| 色女孩综合影院| 欧美一区二区成人6969| 精品成人私密视频| 自拍偷拍欧美精品| 天堂久久一区二区三区| 极品瑜伽女神91| 一本一道久久a久久精品 | 91精品啪在线观看国产60岁| 欧美成人性福生活免费看| 国产精品日日摸夜夜摸av| 一区二区三区电影在线播| 美女在线视频一区| 91在线视频免费91| 日韩午夜电影av| 日韩一区在线播放| 日韩中文字幕91| 成人免费毛片aaaaa**| 欧美在线观看视频一区二区| 日韩免费电影网站| 亚洲男人的天堂在线观看| 久久国产视频网| 欧美性videosxxxxx| 久久精品亚洲精品国产欧美kt∨| 一个色在线综合| 国产一区二区电影| 欧美日韩一区二区三区视频| 久久众筹精品私拍模特| 亚洲国产成人tv| 波多野结衣中文一区| 日韩精品最新网址| 亚洲一区日韩精品中文字幕| 国产精品亚洲一区二区三区妖精| 欧美日韩在线三级| 亚洲视频免费观看| 精品一区二区在线观看| 欧美亚洲高清一区| 亚洲视频资源在线| 国产一区三区三区| 欧美一级免费大片|