说说在 Canvas 中如何填充渐变颜色

渐变颜色填充方式有两种:线性或径向。

  1. 线性渐变填充会创建一个水平 、 垂直或者对角线的填充图案。
  2. 径向渐变填充会自中心点创建一个放射状填充图案。

1 线性渐变

1.1 线性水平渐变

(1)基本形状

Steve Fulton 与 Jeff Fulton 举了一个示例,来说明如何设置线性水平渐变。

//创建渐变对象
var gr = context.createLinearGradient(0, 0, 100, 0);

//颜色断点
gr.addColorStop(0, 'rgb(255,0,0)');
gr.addColorStop(.5, 'rgb(0,255,0)');
gr.addColorStop(1, 'rgb(255,0,0)');

//设置渐变
context.fillStyle = gr;

//绘制矩形
context.fillRect(0, 0, 100, 100);

运行结果:

首先使用 context 的 createLinearGradient() 来创建渐变对象。语法为:context.createLinearGradient(x0,y0,x1,y1);

参数 描述
x0 渐变开始点的 x 坐标
y0 渐变开始点的 y 坐标
x1 渐变结束点的 x 坐标
y1 渐变结束点的 y 坐标

Linear /ˈlɪniə(r)/
Of, relating to, or resembling a line; straight.

gradient /ˈɡreɪdiənt/
Physics The rate at which a physical quantity, such as temperature or pressure, changes relative to change in a given variable, especially distance.

四个入参都是坐标,目的是确定渐变的范围。

注意:因为需要创建的是一个水平渐变,所以 y 值都是 0。

渐变对象创建好之后,就可以设置色标。语法:gradient.addColorStop(stop,color);

参数 描述
stop 介于 0.0 与 1.0 之间的值,表示渐变中开始与结束之间的位置。
color 在结束位置显示的 CSS 颜色值

可以多次调用 addColorStop() 方法来改变渐变。

比如示例代码中设置的渐变是起点 (0) 为红色 、 中心点 (0.5) 为绿色 、 终点 (1)为红色。所以最后的效果是出现一个 “ 红-绿-红 ” 渐变颜色。

为了说明渐变对象的影响范围,我们再添加两个矩形,一个窄,一个宽。

context.fillRect(0, 100, 50, 100);
context.fillRect(0, 200, 200, 100);

渲染结果:

从渲染结果中可以看出,只要有形状在水平渐变的垂直区域内,就会渲染出水平渐变效果。

综合运用这些方法,就可以做出非凡的彩虹效果。

var gr = context.createLinearGradient(0, 0, 300, 0);

gr.addColorStop(0, '#fff');
gr.addColorStop(0.15, '#8B00FF');
gr.addColorStop(0.25, '#0000FF');
gr.addColorStop(0.35, '#00FFFF');
gr.addColorStop(0.45, '#00FF00');
gr.addColorStop(0.55, '#FFFF00');
gr.addColorStop(0.65, '#FF7F00');
gr.addColorStop(0.75, '#FF0000');
gr.addColorStop(1, '#fff');
   
//生成渐变
context.fillStyle = gr;

context.fillRect(0, 0, 300, 300);

运行结果:

(2)边框

也可以对形状的边框应用渐变颜色。

var gr = context.createLinearGradient(0, 0, 100, 0);
gr.addColorStop(0, 'rgb(255,0,0)');
gr.addColorStop(.5, 'rgb(0,255,0)');
gr.addColorStop(1, 'rgb(255,0,0)');

context.strokeStyle=gr;
context.strokeRect(0,0,100,100);
context.strokeRect(0,100,50,100);
context.strokeRect(0,200,200,100);

运行结果:

这里的示例代码与之前示例的区别是:先把 strokeStyle 设置为渐变对象,接着调用 strokeRect() 来绘制边框。

stroke /strəʊk/
v.
To mark with a single short line.

(3)特殊形状

由点组成、封闭的特殊形状,也可以填充渐变颜色。只要形状的起止点相同,就是封闭的。

var gr = context.createLinearGradient(0, 0, 100, 0);

gr.addColorStop(0, 'rgb(255,0,0)');
gr.addColorStop(.5, 'rgb(0,255,0)');
gr.addColorStop(1, 'rgb(255,0,0)');

context.fillStyle = gr;

context.beginPath();
context.moveTo(0, 0);
context.lineTo(50, 0);
context.lineTo(100, 50);
context.lineTo(50, 100);
context.lineTo(0, 100);
context.lineTo(0, 0);

context.stroke();
context.fill();
context.closePath();

运行结果:

1.2 线性垂直渐变

(1)形状

线性垂直渐变与水平渐变类似,只不过 createLinearGradient() 中的 x 都为 0。

var gr = context.createLinearGradient(0, 0, 0, 300);

gr.addColorStop(0, '#fff');
gr.addColorStop(0.15, '#8B00FF');
gr.addColorStop(0.25, '#0000FF');
gr.addColorStop(0.35, '#00FFFF');
gr.addColorStop(0.45, '#00FF00');
gr.addColorStop(0.55, '#FFFF00');
gr.addColorStop(0.65, '#FF7F00');
gr.addColorStop(0.75, '#FF0000');
gr.addColorStop(1, '#fff');

context.fillStyle = gr;

context.fillRect(0, 0, 300, 300);

运行结果:

(2)边框

线性垂直渐变也可以应用与边框。

var gr = context.createLinearGradient(0, 0, 0, 100);
gr.addColorStop(0, 'rgb(255,0,0)');
gr.addColorStop(.5, 'rgb(0,255,0)');
gr.addColorStop(1, 'rgb(255,0,0)');

context.strokeStyle = gr;

context.beginPath();
context.moveTo(0, 0);
context.lineTo(50, 0);
context.lineTo(100, 50);
context.lineTo(50, 100);
context.lineTo(0, 100);
context.lineTo(0, 0);

context.stroke();
context.closePath();

运行结果:

(3)对角线

createLinearGradient() 方法中的起始点与终止点成斜 45 度对角,就可以做出对角线的渐变效果。当然也可以做成其它斜度。

var gr = context.createLinearGradient(0, 0, 100, 100);

gr.addColorStop(0, 'rgb(255,0,0)');
gr.addColorStop(.5, 'rgb(0,255,0)');
gr.addColorStop(1, 'rgb(255,0,0)');

context.fillStyle = gr;
context.beginPath();
context.moveTo(0, 0);
context.fillRect(0, 0, 100, 100);
context.closePath();

运行结果:

2 径向渐变

context 的 createLinearGradient() 方法可以创建放射状的径向渐变对象。

语法:context.createRadialGradient(x0,y0,r0,x1,y1,r1);

参数 描述
x0 渐变的开始圆的 x 坐标
y0 渐变的开始圆的 y 坐标
r0 开始圆的半径
x1 渐变的结束圆的 x 坐标
y1 渐变的结束圆的 y 坐标
r1 结束圆的半径

(1)基本形状

var gr = context.createRadialGradient(50, 50, 25, 50, 50, 100);

gr.addColorStop(0, 'rgb(255,0,0)');
gr.addColorStop(.5, 'rgb(0,255,0)');
gr.addColorStop(1, 'rgb(255,0,0)');

context.fillStyle = gr;
context.fillRect(0,0,200,200);

运行结果:

示例代码先在点 (50,50) 以半径为 25 长度,画出一个起始圆;接着在点 (50,50) 以半径为 100 长度,画出一个终止圆;最后在它们之间设置径向渐变。

如果终止圆的圆心在起始圆的圆心右下角,就会产生这样的效果。

context.createRadialGradient(50, 50, 25, 100, 100, 100);

(2)其它形状

除了对正方形应用径向渐变,也可以把径向渐变应用于其他形状的图形,比如圆形。

context.arc(100,100,100,(Math.PI/180)*0,(Math.PI/180)*360,false);
context.fill();

其他部分代码与上一例的代码相同。

运行结果:

(3)边框

也可以把径向渐变应用于边框。

context.strokeStyle = gr;

context.arc(100,100,50,(Math.PI/180)*0,(Math.PI/180)*360,false);
context.stroke();

其他部分代码与上一例的代码相同。

运行结果:

这里的圆会比前面示例中的圆小一半,这样才能得到径向渐变效果。


综合运用以上知识点,可以做出让人惊叹的效果。

var gr = context.createRadialGradient(50, 50, 25, 100, 100, 100);

gr.addColorStop(0, '#fff');
gr.addColorStop(0.15, '#8B00FF');
gr.addColorStop(0.25, '#0000FF');
gr.addColorStop(0.35, '#00FFFF');
gr.addColorStop(0.45, '#00FF00');
gr.addColorStop(0.55, '#FFFF00');
gr.addColorStop(0.65, '#FF7F00');
gr.addColorStop(0.75, '#FF0000');
gr.addColorStop(1, '#fff');

context.fillStyle = gr;
context.fillRect(0, 0, 200, 200);

运行结果:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351