在 Canvas 中對文本填充水平或垂直的線性漸變能夠輕易實現,而帶角度的漸變就複雜不少;就好像下面這樣,假設文本矩形寬爲 W
, 高爲 H
, 左上角座標爲 X, Y
。javascript
給出兩個答案:css
正確答案是圖二,由於這樣得出來的座標生成的漸變最緊接文本矩形邊界,它的運動軌跡以下動圖:java
(圖來源:Do you really know CSS linear-gradients)函數
因此,漸變的起點與終點座標該怎麼計算呢?答:spa
線性漸變長度的計算 W3C 給出了一個公式(A 表示角度):3d
gradientLineLength = abs(W * sin(A)) + abs(H * cos(A))
不過,該公式主要應用於 CSS 的線性漸變設置,即以 12 點鐘方向爲 0°,順時針旋轉。code
而咱們須要的是以 3 點鐘方向爲 0°,逆時針旋轉,即公式爲:blog
gradientLineLength = abs(W * cos(A)) + abs(H * sin(A)) // 半長: halfGradientLineLength = (abs(W * cos(A)) + abs(H * sin(A))) / 2
那麼這個公式是怎麼來的呢?如下是筆者的求解:ip
由圖可得如下方程組:內存
所以可推導出:
化簡後爲:
因此 c1 + c2
爲:
由三角函數平方公式知:cos(A) * cos(A) = 1 - sin(A) * sin(A)
, 代入 c1 + c2
:
第一步化簡後:
最後的結果就是:
由於 sin, cos
在函數週期內存在負值(見下面角度對應的三角函數週期圖),因此線性漸變的長度須要取絕對值。
至此,咱們知道了線性漸變長度,文本矩形的中心點座標很好算,即:
centerX = X + W / 2 centerY = Y + H / 2
因此,起點與終點的座標分別爲:
startX = centerX - cos(A) * halfGradientLineLength startY = centerY + sin(A) * halfGradientLineLength endX = centerX + cos(A) * halfGradientLineLength endY = centerY - sin(A) * halfGradientLineLength
進行三角函數計算時,應儘可能避免先用 tan
, 由於 tan
在其週期內存在無窮值,須要作特定的條件判斷,而 sin, cos
沒有此類問題,代碼書寫更爲簡潔清晰而且不會因疏忽產生錯誤,見下面三角函數與角度的對應關係週期圖。