Canvas 交互

2017年12月28日

背景

canvas 是一張畫布,僅有一個(gè)DOM元素,瀏覽器沒有內(nèi)置多余的API,所有的交互需要開發(fā)直接實(shí)現(xiàn)。

幾何計(jì)算

規(guī)則的幾何形狀,如矩形、圓形等,可通過簡單的數(shù)學(xué)計(jì)算獲得。

應(yīng)用

這是用 canvas 做的一個(gè)關(guān)系網(wǎng)絡(luò)圖,鼠標(biāo)可以自由拖動節(jié)點(diǎn)。這個(gè)場景下交互很簡單,鼠標(biāo)點(diǎn)擊畫布,在事件中獲取X,Y坐標(biāo),然后計(jì)算每一個(gè)節(jié)點(diǎn),看是否落在這個(gè)節(jié)點(diǎn)的半徑內(nèi)。如果是,則標(biāo)記為選中了。

然而,不規(guī)則圖形會大大加大計(jì)算復(fù)雜度,如涉及貝塞爾曲線、旋轉(zhuǎn)等。

可使用 “包圍盒” 的方式,將不規(guī)則圖形簡單化

包圍盒

把復(fù)雜路徑簡單化,再次回歸到方形、圓形等規(guī)則圖形上去。

但如果你需要的是一種非常精準(zhǔn)無誤差的選取方式,那這種包圍盒方式就不適用了,下面是兩種 canvas 精確選取方式:

1. 把圖形序號存在另一張 canvas 的顏色信息里

需額外新增一張僅用來存信息的canvas(不插入html里面)
當(dāng)在正常的canvas上繪制圖形時(shí),同時(shí)在那張隱式的canvas中也繪制一遍,并把圖形的索引值作為顏色值來繪制圖形

ctx.getImageData(x,y,width,height);

ImageData 對象
R - 紅色 (0-255)
G - 綠色 (0-255)
B - 藍(lán)色 (0-255)
A - alpha 通道 (0-255)

2. 利用 isPointInPath() API

重走一遍繪制流程,但不真正的繪制出來(不調(diào)用stroke 和 fill )圖形),而只調(diào)用 isPointInPath()方法判斷點(diǎn)是否在圖形中,如果在則終止。

附錄

包圍盒

包圍盒是一種求解離散點(diǎn)集最優(yōu)包圍空間的算法,基本思想是用體積稍大且特性簡單的幾何體(稱為包圍盒)來近似地代替復(fù)雜的幾何對象。

Element.getBoundingClientRect()

返回元素的大小及其相對于視口的位置。

返回值是一個(gè) DOMRect 對象,包含了一組用于描述邊框的只讀屬性——left、top、right和bottom,單位為像素。除了 width 和 height 外的屬性都是相對于視口的左上角位置而言的。

MDN - getBoundingClientRect

相關(guān)鏈接

  1. Canvas 拾取的方案和選擇 (蕭慶)
  2. antV 規(guī)則圖形檢測算法
  3. Canvas 與 WebGL 在 ECharts 中的應(yīng)用(沈毅)
  4. A Gentle Introduction to Making HTML5 Canvas Interactive - Simon Sarris
  5. Canvas-tutorials/shapes.js - Simon Sarris
  6. canvas中的isPointInPath()方法
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容