Do what you do

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,我们共同学习。亲爱的,下次见~

posted @ 2012-05-07 16:45  key yao  阅读(332)  评论(0编辑  收藏  举报
学会做事 学会做人