做者:凹凸曼 - Barriorjavascript
在 Canvas 中对文本填充水平或垂直的线性渐变能够轻易实现,而带角度的渐变就复杂不少;就好像下面这样,假设文本矩形宽为 W
, 高为 H
, 左上角坐标为 X, Y
。css
给出两个答案:java
正确答案是图二,由于这样得出来的坐标生成的渐变最紧接文本矩形边界,它的运动轨迹以下动图:函数
(图来源:Do you really know CSS linear-gradients)spa
因此,渐变的起点与终点坐标该怎么计算呢?答:3d
线性渐变长度的计算 W3C 给出了一个公式(A 表示角度):code
gradientLineLength = abs(W * sin(A)) + abs(H * cos(A))
复制代码
不过,该公式主要应用于 CSS 的线性渐变设置,即以 12 点钟方向为 0°,顺时针旋转。cdn
而咱们须要的是以 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
没有此类问题,代码书写更为简洁清晰而且不会因疏忽产生错误,见下面三角函数与角度的对应关系周期图。
Do you really know CSS linear-gradients?
W3C - CSS Images Module Level 3 # linear-gradients
欢迎关注凹凸实验室博客:aotu.io
或者关注凹凸实验室公众号(AOTULabs),不定时推送文章: