2017年12月28日
背景
canvas 是一張畫布,僅有一個(gè)DOM元素边酒,瀏覽器沒(méi)有內(nèi)置多余的API经柴,所有的交互需要開(kāi)發(fā)直接實(shí)現(xiàn)。
幾何計(jì)算
規(guī)則的幾何形狀墩朦,如矩形坯认、圓形等,可通過(guò)簡(jiǎn)單的數(shù)學(xué)計(jì)算獲得氓涣。
應(yīng)用
這是用 canvas 做的一個(gè)關(guān)系網(wǎng)絡(luò)圖牛哺,鼠標(biāo)可以自由拖動(dòng)節(jié)點(diǎn)。這個(gè)場(chǎng)景下交互很簡(jiǎn)單劳吠,鼠標(biāo)點(diǎn)擊畫布引润,在事件中獲取X,Y坐標(biāo),然后計(jì)算每一個(gè)節(jié)點(diǎn)痒玩,看是否落在這個(gè)節(jié)點(diǎn)的半徑內(nèi)淳附。如果是议慰,則標(biāo)記為選中了。
然而奴曙,不規(guī)則圖形會(huì)大大加大計(jì)算復(fù)雜度别凹,如涉及貝塞爾曲線、旋轉(zhuǎn)等洽糟。
可使用 “包圍盒” 的方式炉菲,將不規(guī)則圖形簡(jiǎn)單化
包圍盒
把復(fù)雜路徑簡(jiǎn)單化,再次回歸到方形脊框、圓形等規(guī)則圖形上去颁督。
但如果你需要的是一種非常精準(zhǔn)無(wú)誤差的選取方式,那這種包圍盒方式就不適用了浇雹,下面是兩種 canvas 精確選取方式:
1. 把圖形序號(hào)存在另一張 canvas 的顏色信息里
需額外新增一張僅用來(lái)存信息的canvas(不插入html里面)
當(dāng)在正常的canvas上繪制圖形時(shí),同時(shí)在那張隱式的canvas中也繪制一遍屿讽,并把圖形的索引值作為顏色值來(lái)繪制圖形
ctx.getImageData(x,y,width,height);
ImageData 對(duì)象
R - 紅色 (0-255)
G - 綠色 (0-255)
B - 藍(lán)色 (0-255)
A - alpha 通道 (0-255)
2. 利用 isPointInPath() API
重走一遍繪制流程昭灵,但不真正的繪制出來(lái)(不調(diào)用stroke 和 fill )圖形),而只調(diào)用 isPointInPath()方法判斷點(diǎn)是否在圖形中伐谈,如果在則終止烂完。
附錄
包圍盒
包圍盒是一種求解離散點(diǎn)集最優(yōu)包圍空間的算法,基本思想是用體積稍大且特性簡(jiǎn)單的幾何體(稱為包圍盒)來(lái)近似地代替復(fù)雜的幾何對(duì)象诵棵。
Element.getBoundingClientRect()
返回元素的大小及其相對(duì)于視口的位置抠蚣。
返回值是一個(gè) DOMRect 對(duì)象,包含了一組用于描述邊框的只讀屬性——left履澳、top嘶窄、right和bottom,單位為像素距贷。除了 width 和 height 外的屬性都是相對(duì)于視口的左上角位置而言的柄冲。