html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


Posted in HTML / CSS onJanuary 09, 2013

一般绘图的方式有两种,即填充和描边,前面的文章已经讲了描边的方法stroke,本文就讲一下Canvas中填充图形的方法。
填充即fill(),很直白吧?而且和strokeStyle表示描边样式一样,fillStyle即表示填充样式。
ctx.fillStyle = '颜色';默认的填充样式是不透明的黑色

提问:未闭合的路径可以填充吗?
可以。Canvas会从你当前路径的终点直接连接到起点,然后填充。如图:

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


但你可以发现,最后一段没有描边。
记得我们前一篇文章用4条线画了一个正方形,但canvas不会这么差劲,连直接绘制矩形的函数都没有。你可以使用fillRect()直接填充一个矩形:
复制代码
代码如下:

ctx.fillRect(x,y,width,height);

这里的x,y是指矩形的左上角起点的坐标,记住。
说到fillRect,就不得不提strokeRect,你猜对了,他的意思就是直接描边出一个矩形。
还有fillText与strokeText,至于作用嘛,你可能都猜到了,我这里先不讲,大家先预习吧。

Canvas填充渐变色
在Canvas中,渐变色同样分为两种,即线性渐变和径向渐变,而且创建他们的方法也是独立的。我们先看如何创建线性渐变。
创建线性渐变=createLinearGradient——看,依然很直接的单词。他的语法如下:
createLinearGradient(x1,y1,x2,y2)有4个参数呢!看起来好复杂,其实这个挺简单的,因为我们前面已经说了,平面世界里的一个点是由x坐标和y坐标确定的。所以,x1,y1就是表示线性渐变的起点坐标,x2,y2就表示终点坐标。
这样做的好处很明显,如果我们想创建一个斜着的线性渐变,很方便。但我们先创建一个水平的线性渐变试试吧。
var linear = ctx.createLinearGradient(100,100,200,100);渐变好像创建了,那么我们可以填充了吗?————这个渐变是空的,没有颜色。
往渐变条里加颜色的方法是addColorStop(位置,颜色).但要注意了,这个addColorStop不是加在画笔上,而是加在前面的那个保存渐变的变量上,我这里是linear.

复制代码
代码如下:

var linear = ctx.createLinearGradient(100,100,200,100);
linear.addColorStop(0,'#fff');
linear.addColorStop(0.5,'#f0f');
linear.addColorStop(1,'#333');

我这里用了3个addColorStop,即为渐变条加上了3个颜色。
注意:addColorStop的位置参数,永远是介于0-1之间的数字,可以是两位小数,表示百分比。他没法接收’3px’这样的参数。
这时候,我们就可以填充渐变色了,但我们必须先把定义好的渐变赋给fillStyle.
复制代码
代码如下:

var linear = ctx.createLinearGradient(100,100,200,100);
linear.addColorStop(0,'#fff');
linear.addColorStop(0.5,'#f0f');
linear.addColorStop(1,'#333');
ctx.fillStyle = linear; //把渐变赋给填充样式
ctx.fillRect(100,100,100,100);
ctx.stroke();

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


注意,fillRect与strokeRect画出的都是独立的路径,如上面的代码,在fillRect后调用描边,并不会把刚刚画出的矩形描边,strokeRect同理。
经过测试后,发现了一个很蛋疼的问题,就是线性渐变的坐标是相对于整个Canvas范围而言的。比如我这里,我的线性渐变起点就是100,100,如果我画了一个矩形在0,0的位置,用这个渐变来填充,就会发现没有填充——因为我的渐变的范围根本就超过了矩形的范围。
这真是一个坑爹的设定。

提问:渐变起点之前与渐变终点之后还会填充颜色吗?
会。起点之前的颜色就是起点色,终点之后的颜色一直是终点色。
如何终止终点色,你可以在结束色之后再填一个透明的结束色。如:

复制代码
代码如下:

linear.addColorStop(0.99,'#333');
linear.addColorStop(1,'rgba(51,51,51,0)');

依照前面的计划,我再建一个倾斜的线性渐变试试。只需要改createLinearGradient的参数即可.
复制代码
代码如下:

var linear = ctx.createLinearGradient(100,100,200,200);

效果如图:

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法

然后,让我们来试试径向渐变(圆形渐变)。与createLinearGradient类似,创建径向渐变的方法是:createRadialGradient,但他们的参数可大不相同:
createRadialGradient(x1,y1,r1,x2,y2,r2)其中的x1,y1,x2,y2依旧表示起点和终点,不过这里的起点和终点都是一个圆,而x,y则是圆心的坐标。所以,r1与r2分别是起点圆的半径和终点圆的半径。如图:

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


在我的印象中,貌似径向渐变就是一个圆,圆心就是起点,圆的半径就是终点。但canvas里面的径向渐变竟然搞的不一样了,起点一个圆,终点一个圆,和我的理解有差距。
我们从最简单的做起。首先,做一个很正规的径向渐变,即渐变圆形的圆心就是渐变的起点。由于正规的径向渐变,中心即圆心,所以我们应该尽量避免发生偏斜。那么,我们把终点圆的圆心与起点圆的圆心重合吧?
复制代码
代码如下:

var radial = ctx.createRadialGradient(55,55,10,55,55,55); //重合的圆心坐标
radial.addColorStop(0,'#fff');
radial.addColorStop(0.5,'#ff0');
radial.addColorStop(0.9,'#555');
radial.addColorStop(1,'#f00');

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


这里我设置的径向渐变起点圆和终点圆的圆心坐标相同,而起点圆半径为10,终点圆半径为55.最后画出的径向渐变范围是一个宽高110的圆形,说明渐变范围以终点圆的范围为准。
(可以看到终点圆范围之外还是有颜色,这个颜色就是终点色,但是,如果你企图使用radial.addColorStop(1.5,’#0f0′);这样来定义渐变范围之外的颜色,你还是会收到一个错误).
那么,起点圆的半径有什么用呢?——本来正常的径向渐变的中心(姑且称之为“变心”…吧)只是一个点,不应该是一个圆的。其实我们没错,这个起点圆就相当于一个圆点而已,只是可能比较大。
让我们把起点圆的半径变得很大,接近于终点圆的半径:
复制代码
代码如下:

var radial = ctx.createRadialGradient(55,55,50,55,55,55); //很接近

其他的colorStop都不变,然后图形就变成了这个样子。

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


也就是说,canvas中径向渐变的起点色,是从起点圆的范围之外绘制的,而起点圆的整个颜色都是起点色。
我们把起点圆的半径设为0,那径向渐变的“变心”,就真的是一个点了。
大部分时候我们都不需要很正规的径向渐变,反而希望他的变心是偏移的,类似下图:

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法

这个时候,canvas径向渐变两个圆的优势就出来了,只要我们起点圆与终点圆的圆心不重合,那变心也就会偏移:
var radial = ctx.createRadialGradient(75,75,0,55,55,55);但此时的渐变范围依然是终点圆的范围哈。
很多人天生就有一种搞破坏的心理,比如这里,终点圆的半径总比起点圆大,但如果把他们反过来会怎么样呢?
复制代码
代码如下:

var radial = ctx.createRadialGradient(75,75,55,55,55,0);

经测试,这样不会报错,只是原来的从内到外的渐变反过来变成了从外到内的渐变了。这是个好用法。

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


还有个问题,如果我们把起点圆的圆心偏移了,并且起点圆的范围超出了终点圆的范围,

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法

这时会发生什么?

html5 Canvas画图教程(4)—未闭合的路径及渐变色的填充方法


啊!?这是什么情况?!
当起点圆和终点圆只有部分重叠的时候,就会出现这种情况。所以,如果你需要正常的径向渐变,请保证其中一个圆完全包住了另一个圆。
另外,既然渐变可以赋给fillStyle,那么也可以赋给strokeStyle。效果你懂的。
HTML / CSS 相关文章推荐
Css3+Js制作漂亮时钟(附源码)
Apr 24 HTML / CSS
简单介绍CSS3中Media Query的使用
Jul 07 HTML / CSS
简单几步用纯CSS3实现3D翻转效果
Jan 17 HTML / CSS
CSS3中的弹性布局em运用入门详解 1em等于多少像素
Feb 08 HTML / CSS
socket.io 和canvas 实现的共享画板功能
May 22 HTML / CSS
html5指南-5.使用web storage存储键值对的数据
Jan 07 HTML / CSS
IE10 Error.stack 让脚本调试更加方便快捷
Apr 22 HTML / CSS
浅谈HTML5 服务器推送事件(Server-sent Events)
Aug 01 HTML / CSS
基于Html5 canvas实现裁剪图片和马赛克功能及又拍云上传图片 功能
Jul 09 HTML / CSS
HTML5 背景的显示区域实现
Jul 09 HTML / CSS
浅谈由position属性引申的css进阶讨论
May 25 HTML / CSS
CSS实现背景图片全屏铺满自适应的3种方式
Jul 07 HTML / CSS
html5 Canvas画图教程(3)—canvas出现1像素线条模糊不清的原因
Jan 09 #HTML / CSS
html5 Canvas画图教程(2)—画直线与设置线条的样式如颜色/端点/交汇点
Jan 09 #HTML / CSS
html5 Canvas画图教程(1)—画图的基本常识
Jan 09 #HTML / CSS
使用html5+css3来实现slider切换效果告别javascript+css
Jan 08 #HTML / CSS
几个解决兼容IE6\7\8不支持html5标签的几个方法
Jan 07 #HTML / CSS
html5 canvas-2.用canvas制作一个猜字母的小游戏
Jan 07 #HTML / CSS
html5 canvas-1.canvas介绍(hello canvas)
Jan 07 #HTML / CSS
You might like
CodeIgniter中实现泛域名解析
2014/07/19 PHP
ECSHOP完美解决Deprecated: preg_replace()报错的问题
2016/05/17 PHP
php实现的mongoDB单例模式操作类
2018/01/20 PHP
jquery 屏蔽一个区域内的所有元素,禁止输入
2009/10/22 Javascript
jquery的Tooltip插件 qtip使用详细说明
2010/09/08 Javascript
juqery 学习之三 选择器 子元素与表单
2010/11/25 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
鼠标滚轴控制文本框值的JS代码
2013/11/19 Javascript
简单讲解AngularJS的Routing路由的定义与使用
2016/03/05 Javascript
归纳下js面向对象的几种常见写法总结
2016/08/24 Javascript
javascript使用 concat 方法对数组进行合并的方法
2016/09/08 Javascript
走进javascript——不起眼的基础,值和分号
2017/02/24 Javascript
AngularJS基于factory创建自定义服务的方法详解
2017/05/25 Javascript
ZeroClipboard.js使用一个flash复制多个文本框
2017/06/19 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
Node 升级到最新稳定版的方法分享
2018/05/17 Javascript
Vue+axios实现统一接口管理的方法
2018/07/23 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
2019/02/28 Javascript
vue发送websocket请求和http post请求的实例代码
2019/07/11 Javascript
vue计算属性无法监听到数组内部变化的解决方案
2019/11/06 Javascript
Vue获取页面元素的相对位置的方法示例
2020/02/05 Javascript
ES6使用新特性Proxy实现的数据绑定功能实例
2020/05/11 Javascript
JavaScript缓动动画函数的封装方法
2020/11/25 Javascript
[01:08:32]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第二场 1月18日
2021/03/11 DOTA
python列表list保留顺序去重的实例
2018/12/14 Python
对python中Librosa的mfcc步骤详解
2019/01/09 Python
Python Pandas数据中对时间的操作
2019/07/30 Python
python实现广度优先搜索过程解析
2019/10/19 Python
pytorch dataloader 取batch_size时候出现bug的解决方式
2020/02/20 Python
python将音频进行变速的操作方法
2020/04/08 Python
Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性(推荐)
2020/07/03 Python
英国Boots旗下太阳镜网站:Boots Designer Sunglasses
2018/07/07 全球购物
信息与计算科学专业推荐信
2014/02/23 职场文书
建党伟业观后感
2015/06/01 职场文书
2015上半年个人工作总结
2015/07/27 职场文书
sql注入教程之类型以及提交注入
2021/08/02 MySQL