12.12 HTML Canvas渐变

渐变是一个常用的增强效果

有时候,简单的颜色并不够用,渐变是一个常用的增强效果,fillStylestrokeStyle都可以接受以CanvasGradient对象表示的渐变颜色值。

画布支持两种类型的渐变:线性渐变放射渐变(也称为径向渐变),每一种渐变在2D渲染上下文中都有对应的创建方法,线性渐变对应的是createLinearGradient,而放射渐变对应的是createRadialGradient。 这两种方法都返回一个CanvasGradient,可以使用CanvasGradient对象本身的addColorStop方法对它进行进一步处理。下面让我们创建一个基本的线性渐变,以了解它们的使用方法。

线性渐变

var gradient = context.createLinearGradient(0, 0, 0, canvas.height());
gradient.addColorStop(0, "rgb(0, 0, 0)"); 
gradient.addColorStop(1, "rgb(255, 255, 255)"); 
context.fillStyle = gradient; 
context.fillRect(0, 0, canvas.width(), canvas.height()); 

我们首先使用createLinearGradient创建一个新的CanvasGradient对象,然后将它赋值给一个变量,这样在将来才能够再次访问这个对象。createLinearGradient方法有4个参数:渐变起点的(x,y)坐标,渐变终点的(x,y)坐标。起点和终点描述了所绘制渐变效果的长度、位置和方向。在这个例子中,渐变是从画布的左上角开始的,然后延伸到左下角.线性渐变的绘制方向与起点和终点所确定的直线是正交的,所以在这个例子中,渐变是从顶部延伸到底部的。

定义一个CanvasGradient对象还不够,我们还需要给它指定一种颜色。因此,我们两次调用CanvasGradient对象(此对象已经保存到一个变量中了)的addColorStop方法。addColorStop方法有两个参数:颜色的偏移值(0表示渐变起点,1表示终点),以及该偏移的颜色值。与fillStyle相同,这个颜色值可以是任何CSS颜色值。在这个例子中,渐变是从起点的黑色(偏移值为0)变化到终点的白色(偏移值为1)。

最后,这个渐变会作为一个颜色值被应用到fillStyle属性中,从而在整个画布上显示从黑色到白色的渐变效果(参见图1)。

绘制一个线性渐变

放射渐变(或称为径向渐变)

放射渐变是使用createRadialGradient方法创建的。这个方法需要6个参数——前3个参数描述一个圆(开始圆),后3个参数描述另一个圆(结束圆)。 这两个圆本身不仅描述了方向及渐变的起止位置,而且还描述了渐变的形状。用于描述每一个圆的3个参数是圆心坐标(x,y)和半径。这些参数可以用字符串描述为:

createRadialGradient(x0, y0, r0, x1, y1, r1); 

实际的渐变效果是连接两个圆周的锥体,其中开始圆之前的锥体部分显示偏移值为0的颜色,而结束圆之后的锥体部分则显示偏移值为1的颜色。理解这个概念有一些难度,所以用一个图片来说明,希望你能够理解它的原理(参见图2)。

图2
画布中放射渐变工作原理的图形表示

使用画布代码编写的结果如下:

var gradient = context.createRadialGradient(300, 300, 10, 100, 100, 50); 
gradient.addColorStop(0, "rgb(0, 0, 0)"); 
gradient.addColorStop(1, "rgb(150, 150, 150)"); 
context.fillStyle = gradient; 
context.fillRect(0, 0, canvas.width(), canvas.height()); 

开始圆位于坐标位置(300,300),半径为10;结束圆的坐标位置为(100,100),半径为50。最终得到的锥体基本上与图2相似,开始圆为黑色(偏移值0),慢慢褪色为结束圆的灰色(偏移值1)(参见图3)。

绘制一个放射渐变锥体

但这并不是我想象的放射渐变效果!我想象的效果应该类似于图4。

绘制一个更常见的放射渐变

这种放射渐变其实非常容易实现,只需要将开始圆和结束圆放置在同一个位置即可。仅此而已!

var canvasCentreX = canvas.width()/2; 
var canvasCentreY = canvas.height()/2; 
var gradient = context.createRadialGradient(canvasCentreX, canvasCentreY, 0, canvasCentreX, canvasCentreY, 250); 
gradient.addColorStop(0, "rgb(0, 0, 0)"); 
gradient.addColorStop(1, "rgb(150, 150, 150)"); 
context.fillStyle = gradient; context.fillRect(0, 0, canvas.width(), canvas.height()); 

通过将两个圆叠放在一起,我们就可以将渐变锥体环绕360度,只要两个圆的大小不同,那么渐变效果就会从较小的圆延伸到较大的圆上。

注意:虽然渐变的效果很漂亮,但是使用cavans来创建渐变并非总是最好的方法,特别是在将它们作为背景使用时。我们应该考虑使用其他的方法,如专门用来完成这个任务的CSS3渐变背景。