校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > html5中監聽canvas內部元素點擊事件的三種方法

html5中監聽canvas內部元素點擊事件的三種方法

熱門標簽:漳州人工外呼系統排名 鶴壁手機自動外呼系統怎么安裝 濟南辦理400電話 跟電銷機器人做同事 ai電銷機器人連接網關 威海營銷外呼系統招商 中紳電銷智能機器人 鄭州電銷外呼系統違法嗎 農村住宅地圖標注

canvas內部元素不能像DOM元素一樣方便的添加交互事件監聽,因為canvas內不存在“元素”這個概念,他們僅僅是canvas繪制出來的圖形。這對于交互開發來說是一個必經障礙,想要監聽圖形的點擊事件思路很簡單,只要監聽canvas元素本身的點擊事件,再判斷點擊坐標位于哪一個圖形內部,就變相實現了圖形點擊事件。本文將介紹三種方法,判斷坐標點是否位于某個canvas圖形內部。

約定

本文介紹的三種方法適用于識別canvas內形狀不規則而且位置無規律的圖形點擊事件,對于形狀規則或者位置有規律的場景,肯定有更簡便的實現,這里不做討論。

像素法

像素檢測法的思路是,將canvas中的多個圖形(如果有多個的話)分別離屏繪制,并用 getImageData() 方法分別獲取到像素數據保存起來。當canvas元素監聽到點擊事件時,通過點擊坐標可以直接推算出點擊發生在canvas上的第幾個像素,然后遍歷前面保存的圖形數據,看看這個像素的alpha值是不是0,如果是0說明落點不在當前圖形內,否則就說明點到了這個圖形。

根據點擊坐標得到所點擊的像素序號的方法:

像素序號 = (縱坐標-1) * canvas寬度 + 橫坐標

比如在寬度為 5 的畫布上點擊坐標 (3,3) ,根據上述公式得到像素序號是 (3-1) * 5 + 3 = 18 ,如圖所示:

因為canvas導出的圖形數據是將每個像素以 rgba 的順序存成4個數字組成的數組,所以想訪問指定像素的alpha值,只要讀取這個數組的第 pIndex * 4 + 3 個值就可以了,如果這個值不為0,說明該像素可見,也就是點擊到了該圖形。

這個方法是我認為思路最直接、結果最準確、而且對圖形形狀沒有任何要求的方法,但這個方法有一個致命的局限,當圖形需要在畫布上移動時,要頻繁的創建數據緩存才能保證檢測結果準確,受到畫布尺寸和圖形數量的影響, getImageData() 方法的性能會成為嚴重的瓶頸。所以如果canvas圖形是靜態的,這個方法非常適合,否則就不適合用這個方法了。

角度法

角度判斷法的原理很容易理解,如果一個點在多邊形內部,則該點與多邊形所有頂點兩兩構成的夾角,相加應該剛好等于360°。

計算過程可以轉變為以下三個步驟:

1.已知多邊形頂點和已知坐標,將坐標與頂點兩兩組合成三點隊列
2. 已知三點求夾角,可以使用 余玄定理
3.判斷夾角之和是否360°

每一步都很簡單,實現如下:

//計算兩點距離
const getDistence = function (p1, p2) {
  return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))
};
//角度法判斷點在多邊形內部
const checkPointInPolyline = (point, polylinePoints) => {
    let totalA = 0;
    const A = point;
    for (let i = 0; i < polylinePoints.length; i++) {
        let B, C;
        if (i === polylinePoints.length - 1) {
            B = {
                x: polylinePoints[i][0],
                y: polylinePoints[i][1]
            };
            C = {
                x: polylinePoints[0][0],
                y: polylinePoints[0][1]
            };
        } else {
            B = {
                x: polylinePoints[i][0],
                y: polylinePoints[i][1]
            };
            C = {
                x: polylinePoints[i + 1][0],
                y: polylinePoints[i + 1][1]
            };
        }
        //計算角度
        const angleA = Math.acos((Math.pow(getDistence(A, C), 2) + Math.pow(getDistence(A, B), 2) - Math.pow(getDistence(B, C), 2)) / (2 * getDistence(A, C) * getDistence(A, B)))
        totalA += angleA
    }
    //判斷角度之和
    return totalA === 2 * Math.PI
}

這個方法有一個局限性,就是圖形必須是 凸多邊形 。如果不是凸多邊形需要先切割成凸多邊形再計算,這就比較復雜了。

類似的思路還有面積法,如果一個點在多邊形內部,那么該點與多邊形所有頂點兩兩構成的三角形,面積相加應該等于多邊形的面積,首先計算多邊形的面積就很麻煩,所以這種方法可以直接pass掉。

射線法

射線法是一個我講不清道理但非常好用的方法,只要判斷點與多邊形一側的交點個數為奇數,則點在多邊形內部。需要注意的是,只要數任何一側的焦點個數就可以,比如左側。這個方法不限制多邊形的類型,凸多邊形、凹多邊形甚至環形都可以。

實現起來也非常簡單:


 

const checkPointInPolyline = (point, polylinePoints) => {
    //射線法
  let leftSide = 0;
  const A = point;
  for (let i = 0; i < polylinePoints.length; i++) {
    let B, C;
    if (i === polylinePoints.length - 1) {
      B = {
        x: polylinePoints[i][0],
        y: polylinePoints[i][1]
      };
      C = {
        x: polylinePoints[0][0],
        y: polylinePoints[0][1]
      };
    } else {
      B = {
        x: polylinePoints[i][0],
        y: polylinePoints[i][1]
      };
      C = {
        x: polylinePoints[i + 1][0],
        y: polylinePoints[i + 1][1]
      };
    }
    //判斷左側相交
    let sortByY = [B.y, C.y].sort((a,b) => a-b)
    if (sortByY[0] < A.y && sortByY[1] > A.y){
      if(B.x<A.x || C.x < A.x){
        leftSide++
      }
    }
  }
  return leftSide % 2 === 1
}

射線法有一種特殊情況,當點在多變形的一條邊上時需要特殊處理。但在工程中我認為也可以不處理,因為如果用戶剛好點在圖形的邊界上,那么程序認為他沒有點到也講的過去。

總結

以上三種方法都可以實現canvas中不規則圖形的點擊檢測。其中,像素法的優勢在于不挑形狀,而且在靜態場景中有一定的性能優勢;角度法應該說只有理論價值,實用性不佳;工程中最實用的當屬射線法,局限性小,實現簡單,多數時候只需要知道射線法就可以了。
 

 

標簽:萍鄉 惠州 紅河 營口 蘇州 咸陽 甘南 文山

巨人網絡通訊聲明:本文標題《html5中監聽canvas內部元素點擊事件的三種方法》,本文關鍵詞  html5,中,監聽,canvas,內部,元素,點擊,事件,的,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《html5中監聽canvas內部元素點擊事件的三種方法》相關的同類信息!
  • 本頁收集關于html5中監聽canvas內部元素點擊事件的三種方法的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    成av人片一区二区| 亚洲成人自拍一区| 成人蜜臀av电影| 国产精品久久久久一区| 91片黄在线观看| 亚洲国产精品一区二区久久恐怖片| 色婷婷综合视频在线观看| 亚洲一区在线视频| 欧美精品精品一区| 久久不见久久见免费视频7| 久久嫩草精品久久久精品| 菠萝蜜视频在线观看一区| 一区二区三区91| 欧美一区二区视频观看视频| 国内精品伊人久久久久av影院| 国产日韩欧美综合在线| 91猫先生在线| 日本v片在线高清不卡在线观看| 精品理论电影在线| proumb性欧美在线观看| 亚洲午夜久久久久久久久电影网| 欧美一级黄色片| 国产mv日韩mv欧美| 五月天欧美精品| 久久久国产精品午夜一区ai换脸| 91啪九色porn原创视频在线观看| 日韩va欧美va亚洲va久久| 国产网站一区二区| 欧美色男人天堂| 国产美女主播视频一区| 亚洲精品福利视频网站| 久久久亚洲午夜电影| 91久久免费观看| 精品一区二区日韩| 亚洲综合视频在线观看| 久久综合999| 欧美色精品在线视频| 国产精品18久久久久久久久| 亚洲国产你懂的| 中文字幕国产一区| 欧美一级在线视频| 91成人网在线| 国产精品99久久久久久宅男| 亚洲成人精品在线观看| 国产精品美女久久久久久久久 | 精品国产乱码久久| 91麻豆福利精品推荐| 国产一区二区在线免费观看| 亚洲国产日日夜夜| 国产精品欧美久久久久无广告| 91精品国产综合久久香蕉的特点 | 亚洲自拍偷拍av| 中文字幕免费一区| 欧美成人精精品一区二区频| 欧美三级在线看| 91欧美激情一区二区三区成人| 激情综合网av| 青青草97国产精品免费观看| 亚洲香肠在线观看| 亚洲少妇30p| 久久久精品欧美丰满| 91精品麻豆日日躁夜夜躁| 欧美日韩一区二区三区在线 | 亚洲国产视频在线| 亚洲色图欧洲色图婷婷| 国产精品色哟哟| 国产午夜精品一区二区三区视频| 91精品在线免费观看| 欧美日韩三级在线| 欧美日韩一级大片网址| 91国模大尺度私拍在线视频| 一本大道av伊人久久综合| 不卡的av在线播放| 成人激情小说乱人伦| www.66久久| 91视频你懂的| 欧美婷婷六月丁香综合色| 精品国产区一区| 日韩欧美不卡一区| 日韩欧美在线1卡| 欧美白人最猛性xxxxx69交| 日韩欧美中文字幕精品| 欧美va在线播放| 久久精品一区二区三区不卡牛牛| 日本一区二区三区视频视频| 国产日韩欧美精品综合| 国产精品色噜噜| 亚洲欧美精品午睡沙发| 亚洲一区二区三区四区在线免费观看| 一区二区三区四区乱视频| 亚洲午夜久久久| 日韩电影在线一区二区| 久草中文综合在线| 国产成人午夜精品5599| fc2成人免费人成在线观看播放| 成人免费高清在线| 色综合视频一区二区三区高清| 欧美最猛性xxxxx直播| 91精品国产综合久久蜜臀| 精品对白一区国产伦| 欧美激情一区二区三区| 亚洲精品中文在线影院| 青青草精品视频| 国产精品小仙女| 一本到三区不卡视频| 欧美一区二区三区在线电影| 久久九九久精品国产免费直播| **欧美大码日韩| 91精品中文字幕一区二区三区| 3d成人动漫网站| 国产日韩精品一区| 亚洲精品免费在线观看| 日韩精品国产欧美| 国产一区二区三区| 一本久久综合亚洲鲁鲁五月天| 91精品一区二区三区久久久久久| 久久在线免费观看| 亚洲激情在线激情| 久热成人在线视频| 91无套直看片红桃| 精品免费99久久| 亚洲欧洲性图库| 老司机精品视频在线| 色综合一区二区三区| 日韩欧美国产一区二区在线播放| 国产精品久久免费看| 青青草国产精品亚洲专区无| 99在线精品视频| 日韩免费在线观看| 亚洲一区在线观看网站| 岛国精品一区二区| 欧美一级片在线看| 一区二区久久久| 国产91精品入口| 69堂国产成人免费视频| 亚洲人成精品久久久久久 | 91黄色小视频| 久久久亚洲精华液精华液精华液| 亚洲综合成人在线| jizzjizzjizz欧美| 亚洲欧洲在线观看av| 国内精品伊人久久久久av一坑 | 国产日韩欧美a| 蜜桃久久久久久久| 欧美日韩高清一区二区| 1000部国产精品成人观看| 国产专区欧美精品| 日韩一区二区三区视频在线观看| 亚洲精品一二三四区| 9i在线看片成人免费| 久久美女高清视频| 日韩精品1区2区3区| 欧美日韩视频第一区| 亚洲男同性视频| av激情亚洲男人天堂| 国产女同互慰高潮91漫画| 激情六月婷婷久久| 精品国产乱码久久久久久图片 | 伊人开心综合网| av在线不卡免费看| 欧美激情一区二区三区不卡| 国内成+人亚洲+欧美+综合在线| 91麻豆精品国产91久久久久| 亚洲国产日产av| 在线观看成人免费视频| 亚洲精品美国一| 欧美亚洲愉拍一区二区| 亚洲柠檬福利资源导航| 色婷婷av一区二区三区gif| 自拍偷自拍亚洲精品播放| 97久久超碰国产精品| 亚洲欧美一区二区三区孕妇| 91麻豆国产精品久久| 亚洲一区二区三区国产| 欧美午夜电影网| 午夜在线成人av| 日韩区在线观看| 国产呦精品一区二区三区网站| 26uuu亚洲| 成人三级伦理片| 亚洲桃色在线一区| 欧美日韩精品一区二区三区 | 亚洲综合免费观看高清完整版在线| 91老师片黄在线观看| 一区二区三区免费看视频| 欧美日韩国产高清一区| 蜜桃视频一区二区三区| 国产日产精品一区| 成人性生交大片免费看中文网站| 中文字幕一区二区视频| 91黄视频在线| 麻豆91免费观看| 欧美激情一区三区| 色哟哟国产精品| 免费视频一区二区| 中文字幕av一区二区三区 | 欧美疯狂性受xxxxx喷水图片| 奇米综合一区二区三区精品视频| 久久青草欧美一区二区三区| 97久久人人超碰|