在這篇文章中主要來聊在Canvas中怎麼繪製箭頭。在Canvas的CanvasRenderingContext2D對象中是沒有提供繪製箭頭的方法,言外之意,在Canvas中要繪製箭頭是需要自己封裝函數來處理。那今天的主題就是來看怎麼封裝繪製箭頭的函數。
了解一些基礎知識平常我們常常看到的一些箭頭樣式如下圖所示:
在繪製箭頭最關鍵之處就是處理箭頭:
其包括幾個部分:
從上圖上我們可以看出,控制一個箭頭,可以通過這幾個參數來控制:
起點P1((fromX, fromY))
終點P2((toX, toY))
斜線率headlen
夾角theta(θ)
對於箭頭的P3和P4點,我們就需要通過相應的三角函數計算得來。
那麼P3的坐標可以輕易計算出來:
用同樣的方法可以計算出P4坐標:
除此之外,還有一個關鍵,就是箭頭的角度。獲取箭頭的角度,可以直接通過atan2(y,x)來獲取。這也就涉及到三角函數中的反正切函數。
在三角函數中,兩個參數的函數atan2是正切函數tan的一個變種。對於任意不同時等於0的實參數x和y,atan2(y,x)所表達的意思是坐標原點為起點,指向(x,y)的射線在坐標平面上與x軸正方向之間的角的角度。當y>0時,射線與x軸正方向的所得的角的角度指的是x軸正方向繞逆時針方向到達射線旋轉的角的角度;而當y<0時,射線與x軸正方向所得的角的角度指的是x軸正方向繞順時針方向達到射線旋轉的角的角度。
在幾何意義上,atan2(y, x) 等價於 atan(y/x),但 atan2 的最大優勢是可以正確處理 x=0 而 y≠0 的情況,而不必進行會引發除零異常的 y/x 操作。
簡單的用下圖來闡述:
在一個單位圓內atan2函數在各點的取值。圓內標註代表各點的取值的幅度表示。圖片中,從最左端開始,角度的大小隨著逆時針方向逐漸從-π增大到+π,並且角度大小在點位於最右端時,取值為0。另外要注意的是,函數atan2(y,x)中參數的順序是倒置的,atan2(y,x)計算的值相當於點(x,y)的角度值。
簡單的了解了反正切函數,我們回到我們的主題中。
先來看一張圖:
通過Math.atan2()函數計算出angle:
為了和θ的單位值相匹配,將上面的公式進行一下轉換:
除此之外,還需要計算出箭頭兩條側邊線的夾角:
感覺有點零亂,其實我自己也瞎折騰了好幾天。如果上面的內容不太好理解,建議你移步閱讀這篇文章。
封裝繪製箭頭函數通過前面的內容,可能對繪製箭頭有一定的理論基礎,接下來,我們看如何封裝箭頭函數。
這裡我們傳了九個參數:
ctx:Canvas繪圖環境
fromX, fromY:起點坐標(也可以換成p1,只不過它是一個數組)
toX, toY:終點坐標 (也可以換成p2,只不過它是一個數組)
theta:三角斜邊一直線夾角
headlen:三角斜邊長度
width:箭頭線寬度
color:箭頭顏色
根據前面的內容,我們可以這樣來寫這個函數:
這個時候,只需要調用這個封裝好的函數,我們就可以輕鬆的繪製一條向右的箭頭:
改變不同的坐標,可以得到不同方向的箭頭:
有的時候,我們需要線的兩頭都要有箭頭形狀,在上面的基礎上,稍加修改,增加一個反項的代碼即可:
調用函數:
看到的效果如下:
上面我們看到的僅是一種箭頭方式,文章開頭,提到箭頭方式有多種方式。那麼我們可以將drawArrow功強變得更為強大一些。比如@Patrick Horgan在他的文章中提到的方法:
由於代碼較多,這裡就不展示出來了,不過可以在對應的CodePen示例中查看到代碼:
總結這篇文章主要介紹了通過三角函數的一些知識,封裝了一個箭頭函數,用來幫助我們在Canvas中更輕易的繪製出箭頭。因為在Canvas中沒有直接提供繪製箭頭的函數或者說方法。那麼三角在實際中有什麼哪些運用呢?大家可以發揮想像力,思考一下,寫寫實例。在最後一個方法中,我們其實還運用到了Canvas中的貝塞爾曲線繪製的方法。在下一節中,我們就來學習在Canvas中怎麼繪製貝塞爾曲線。
文章涉及到圖片和代碼,如果展示不全給您帶來不好的閱讀體驗,歡迎點擊文章底部的 閱讀全文。如果您覺得小站的內容對您的工作或學習有所幫助,歡迎關注此公眾號。
W3cplus.com
————————————
記述前端那些事,引領web前沿
長按二維碼,關注W3cplus
▼
長按二維碼,關注"大漠扯CSS"小密圈
▼