canvas元素简易教程(8)(大部分转自火狐,自己只写了简单的代码分析)
欢迎回来,上次我们具体的分析了canvas中对于线段的绘制,今天我们要接触的是渐变。首先,什么是渐变。你看到过彩虹么?对了,彩虹的颜色过渡不是一段是红色一段是黄色对吗?它是一点一点的变化的颜色,由红色一点一点变到黄色的。彩虹的颜色就是一个渐变,也就是说这种色彩逐渐变化的过渡效果就是一个渐变效果。
就好像一般的绘图软件一样,我们可以用线性或者径向的渐变来填充或描边。我们用下面的方法新建一个canvasGradient对象,并且赋给图形的fillStyle或strokeStyle属性。
createLinearGradient(x1,y1,x2,y2)
createRadialGradient(x1,y1,r1,x2,y2,r2)
createLinearGradient方法接受4个参数,表示渐变的起点(x1,y1)与终点(x2,y2)。
createRadialGradient方法接受6个参数,前三个定义一个以(x1,y1)为原点,半径为r1的圆,后三个参数则定义另一个以(x2,y2)为原点,半径为r2的圆。让我们来个例子:
var lineargradient = ctx.createLinearGradient(0,0,150,150);
var radialgradient = ctx.createRadialGradient(75,75,0,75,75,100);
这个东西是啥意思呢?好吧,其实很简单,就是第一种是给予渐变起点与终点的一个渐变效果,也就是一个指向性的渐变,也就是说,给你两个点,连一条线,这个渐变效果就是由起点向终点这个方向渐变的。第二种呢是圆形的渐变,啥意思?好吧,就是用前三个坐标给你一个圆,后三个坐标给你第二个圆,渐变是由第一个圆向第二个圆的方向的。有个小的建议,第一个圆一定要保证与第二个圆是包含或者被包含的关系,前者效果会绘制在第二个圆中,像一个圆形的渐变,而后者的效果恰恰相反,是以第二个圆中心为白色,对其外围进行渲染。
如果违背这两个可能性,那么效果就是一块是圆形渲染,一块是以两圆交点为第二个圆切点的外侧渲染。不理解试试就好。总之,最好第一个圆包含于第二个圆中间。
创建出canvasGradient对象后,我们就可以用addColorStop方法给它上色了。
addColorStop(position, color)
addColorStop方法接受2个参数,position参数必须是一个0.0与1.0之间的数值,表示渐变中颜色所在的相对位置。例如,0.5表示颜色会出现在正中间。color参数必须是一个有效的CSS颜色值(如#FFF,rgba(0,0,0,1),等等)。
这个比较好理解,就是着色嘛,但是我需要告诉你一点,比如说如何绘制一个彩虹的渐变就不只是着色一次的问题,从红到紫的渲染一定不会是彩虹的。所以,尝试很重要。
下面附上一段类似彩虹色直线渲染与圆形渲染的代码,可能有点难看,大家见谅吧。。。废话不说了,看代码:
function draw1() {
var ctx = document.getElementById('canvas').getContext('2d');
var lingrad = ctx.createLinearGradient(0,0,0,150);
lingrad.addColorStop(0, '#FF0000');
lingrad.addColorStop(0.15, '#FF8800');
lingrad.addColorStop(0.3, '#FFFF00');
lingrad.addColorStop(0.45, '#77FF00');
lingrad.addColorStop(0.6, '#00FF99');
lingrad.addColorStop(0.75, '#0066FF');
lingrad.addColorStop(0.9, '#9900FF');
lingrad.addColorStop(1, '#660077');
ctx.fillStyle = lingrad;
ctx.fillRect(10,10,20,130);
var radgrad = ctx.createRadialGradient(105,105,20,105,105,70);
radgrad.addColorStop(0, '#FF0000');
radgrad.addColorStop(0.15, '#FF8800');
radgrad.addColorStop(0.3, '#FFFF00');
radgrad.addColorStop(0.45, '#77FF00');
radgrad.addColorStop(0.6, '#00FF99');
radgrad.addColorStop(0.75, '#0066FF');
radgrad.addColorStop(0.9, '#9900FF');
radgrad.addColorStop(1, 'rgba(1,159,98,0)');
ctx.fillStyle = radgrad;
ctx.fillRect(0,0,300,300);
}
好了,通过反复的多次的渲染我们获得了一个彩虹渐变的效果,下面我给出两个渐变的例子,希望大家可以动手敲一敲代码,看看真正的效果。
首先是线性黑白色渐变的例子:
var lineargradient = ctx.createLinearGradient(0,0,150,150);
lineargradient.addColorStop(0,'white');
lineargradient.addColorStop(1,'black');
这个例子绘制了一个线性的黑白渐变,没有什么可多说的了。下面我们来看下一个例子:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
// Create gradients
var lingrad = ctx.createLinearGradient(0,0,0,150);
lingrad.addColorStop(0, '#00ABEB');
lingrad.addColorStop(0.5, '#fff');
//lingrad.addColorStop(0.5, '#26C000');
//lingrad.addColorStop(1, '#fff');
var lingrad2 = ctx.createLinearGradient(0,50,0,95);
lingrad2.addColorStop(0.5, '#000');
lingrad2.addColorStop(1, 'rgba(0,0,0,0)');
// assign gradients to fill and stroke styles
ctx.fillStyle = lingrad;
ctx.strokeStyle = lingrad2;
// draw shapes
ctx.fillRect(10,10,130,130);
ctx.strokeRect(50,50,50,50);
}
本例中,我弄了两种不同的渐变。第一种是背景色渐变,你会发现,我给同一位置设置了两种颜色,你也可以用这来实现突变的效果,就像这里从白色到绿色的突变。一般情况下,色标的定义是无所谓顺序的,但是色标位置重复时,顺序就变得非常重要了。所以,保持色标定义顺序和它理想的顺序一致,结果应该没什么大问题。
第二种渐变,我并不是从0.0位置开始定义色标,因为那并不是那么严格的。在0.5处设一黑色色标,渐变会默认认为从起点到色标之间都是黑色。
你会发现,strokeStyle和fillStyle属性都可以接受canvasGradient对象。
然后再看一个圆形渲染的例子:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
// Create gradients
var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
radgrad.addColorStop(0, '#A7D30C');
radgrad.addColorStop(0.9, '#019F62');
radgrad.addColorStop(1, 'rgba(1,159,98,0)');
var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
radgrad2.addColorStop(0, '#FF5F98');
radgrad2.addColorStop(0.75, '#FF0188');
radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
radgrad3.addColorStop(0, '#00C9FF');
radgrad3.addColorStop(0.8, '#00B5E2');
radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
radgrad4.addColorStop(0, '#F4F201');
radgrad4.addColorStop(0.8, '#E4C700');
radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
// draw shapes
ctx.fillStyle = radgrad4;
ctx.fillRect(0,0,150,150);
ctx.fillStyle = radgrad3;
ctx.fillRect(0,0,150,150);
ctx.fillStyle = radgrad2;
ctx.fillRect(0,0,150,150);
ctx.fillStyle = radgrad;
ctx.fillRect(0,0,150,150);
}
这个例子,我定义了 4 个不同的径向渐变。由于可以控制渐变的起始与结束点,所以我们可以实现一些比(如在Photoshop中所见的)经典的径向渐变更为复杂的效果。(经典的径向渐变是只有一个中心点,简单地由中心点向外围的圆形扩张)
这里,我让起点稍微偏离终点,这样可以达到一种球状3D效果。但最好不要让里圆与外圆部分交叠,那样会产生什么效果就真是不得而知了。
4 个径向渐变效果的最后一个色标都是透明色。如果想要两色标直接的过渡柔和一些,只要两个颜色值一致就可以了。代码里面看不出来,是因为我用了两种不同的颜色表示方法,但其实是相同的,#019F62 = rgba(1,159,98,1)。
好了,渐变就讲到这里,大家能够理解么?如果不能理解,没关系,请多敲几遍代码,设下注释,自己去看一下。如果您还是不能理解或者有什么疑问的话,请加我的QQ514971819,我们共同学习。亲爱的,下次见~