說圖形模塊化之前,先回顧下我們之前畫的圖形.(可回看“圖像模塊1”)
那是一個多邊形,雖然沒有閉合,但這不重要。
這是一個多邊形,雖然沒有閉合,但這不重要。
接下來,咱們就將這個圖形封裝爲一個類對象 Poly
Poly 對象是對路徑的封裝,我們可以從兩方面來考慮:
圖形:路徑可以繪製的所有圖形,可以是一個圖形,也可以是多個圖形,只要都在一個路徑集合裏就行;
樣式:路徑該有的所有樣式了。
接下來我們看一下Poly 對象的默認屬性:
一、繪圖方法和相關屬性
詳細解釋一下這些屬性:
crtPath 是建立路徑的方法,默認是給了一個繪製多邊形的方法,此方法也可以被覆蓋。
vertices 是多邊形的頂點集合。
對於其它圖形的相關屬性,我沒有寫,以後需要了可以再去擴展,比如arc 的圓心位、半徑、起始弧度、結束弧度等等。
繪圖方法相關的相關的屬性:
- close:否閉合路徑
- fill:否以填充方式繪製圖形
- strtoke:否以描邊方式繪製圖形
- shadow:否給圖像添加投影
樣式相關的屬性:fillStyle 填充樣式、strokeStyle 描邊樣式…… 這些樣式名稱和canvas 裏的樣式是一樣的,我就不消多說了。
變換相關屬性:和canvas 裏的變換是一樣的,分別是位移、旋轉、縮放。
Poly 的方法:
draw(ctx) :繪圖方法
checkPointInPath(ctx,{x,y}):檢測點位是否在路徑中
上下滑動可觀看完整代碼
↓ ↓ ↓
注意:
Poly 對象中,我對其點位的定義使用了一個Vector2 對象。
Vector2 是一個二維向量對象,它存儲了基本的x、y 位置信息,封裝了點位的運算方法,比如加、減、乘、除等。
這裏我先不對Vector2 對象做詳細解釋,我們先知道它表示一個{x,y} 點位即可,後面我們用到了它的哪個功能,再解釋哪個功能。
Poly 對象建立完成後,咱們就畫個三角形試試。
實例化Poly 對象:
效果:
爲三角形添加劃入劃出效果:
鼠標選擇邏輯:
- 在事件外聲明hover 變量,存儲鼠標劃入劃出狀態。
- 用canvas監聽鼠標移動事件,獲取鼠標在canvas 中的位置
- 使用poly.crtPath(ctx) 方法建立路徑
- 使用isPointInPath() 判斷鼠標點位是否在路徑中
- 鼠標的選擇狀態發生了改變,讓圖形的填充樣式也做相應的改變,並繪圖。
鼠標劃入效果:
把svg 多邊形畫到canvas 裏
用Poly 對象,我們還可以基於svg 裏的polygon 數據繪圖並選擇。
接下來我用Poly 對象畫一下那座酷似大象的山。
在svg 加載成功後,提取svg 裏的polygon的頂點,然後將其放到Poly 的實例對象的vertices 集合裏。
parsePoints(mount) 解析的就是下面polygon 標籤的points 屬性
parsePoints(mount) 函數:
頁面效果:
二、進階:繪製其它圖形
重寫Poly 對象的crtPath()方法,我們還可以繪製除多邊形之外的其它圖形;
比如用兩個三次貝塞爾畫一顆愛心:
這裏其實還存在了一個問題:
那就是圖形通過變換屬性發生了位移、旋轉或縮放後,使用鼠標相對於canvas 畫布的點位就無法再對圖形做出正確選擇。
對於這個問題存在的原因和解決方式,那就是我看修仙小說頓悟出來的絕殺了:
圖形選擇-物質不易
三、奧義:圖形選擇之“物質不易”
現在,咱們來說鼠標如何選擇變換後的圖形。
首先給大家舉個栗子:
在2029年末世之戰的時候,終結者想幹掉人類領袖大壯,可是大壯太強,而且其實力需要複雜運算才能知曉。
所以終結者就想回到1997年,在大壯實力弱小、且已知的情況下將其幹掉。
這樣根據物質不易法則,2029年末世之戰中的人類領袖大壯也就不會存在。
接下來給大家解密終結者穿梭時間的方法。
終結者需要知道數據:
1997年大壯的初始屬性,比如構成大壯輪廓的頂點集合;
大壯從1997到2029的變換信息,比如其大壯移動了多少、旋轉了多少、長大了多少。
根據物質不易法則:
物質不變,空間不變;空間不變,時間不變。
將物質不易法則逆推,依舊成立:物質改變,空間改變;空間改變,時間改變。
所以終結者想要回到1997 年,只要根據大壯的變換規則逆向變換自己的位置就可以回到1997年。
比如:
從1997年到2029年,大壯沿x 軸移動了100,沿y 軸移動了200,旋轉了90度,變大了2倍。
終結者(鼠標點位)就要沿x 軸移動了-100,沿y 軸移動了-200,旋轉-90度,點位到圓心點的距離縮小2倍。
注意:
終結者的變換順序要和大壯的變換順序一致;
終結者改變的只是點位,點沒有尺寸,其點位變換本質是在目標對象所在的canvas畫布的座標系的位移。
只有如此,當終結者穿梭到1997年的時候,纔可以精準定位大壯。
圖示:
接下來在代碼裏走一下這個原理:
先畫了一顆愛心,其所在的canvas 畫布座標系在x、y方向分別位移了(300,400)
若我的鼠標想要選擇這顆愛心,那它的位置就要基於愛心的變換信息反向變換:
x、y方向分別位移(-300,-400)。
代碼如下:
圖形變換中的位移說完了,那它的旋轉、縮放也是同樣道理,就是讓鼠標位置基於圖形的變換信息反向變換。
下面我直接將所有變換的方法封裝到了獲取鼠標點位的方法裏,即getMousePos(event,poly) ,event是事件,poly 是圖形。
代碼如下:
mousePos 是一個Vector2 對象,其中封裝了關於向量的常用方法。
如:
好啦,關於變換後的圖形選擇我們就說到這。
其實圖形圖形選擇的方法是有很多的,下一章我再跟大家說一個圖形選擇的方法:
圖形選擇-網格選擇
注:物質不易是我從修仙小說上課看的,沒有科學依據,只爲輔助大家理解代碼。
摘至開課吧前端團隊,閱讀後頗有收穫分享至此,希望對大家有所幫助~