上一节最后我们说了一个绘制曲线的API——arc
(那个API并不是专门用来绘制圆形,只是使用曲线可以绘制圆形),他还有一个兄弟——arcTo(x1, y1, x2, y2, r)
,根据当前描点与给定的控制点1连接的直线,和控制点1与控制点2连接的直线,作为使用指定半径的圆的切线,画出两条切线之间的弧线路径
- x1:第一个控制点x坐标
- y1:第一个控制点y坐标
- x2:第二个控制点x坐标
- y2:第二个控制点y坐标
- r:曲线半径
示意图如下
路径
先来熟悉一下必用的路径相关的API
- beginPath():新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
- closePath():闭合路径之后图形绘制命令又重新指向到上下文中。
- stroke():通过线条来绘制图形轮廓。
- fill():通过填充路径的内容区域生成实心的图形。
接下来从点开始
moveTo(x, y)——移动当前描点到指定坐标
然后是线
lineTo(x, y)——绘制从当前描点到指定点的直线
到这里我们可以来做一个小练习,绘制一个圆角矩形的一个角
首先画一条线,然后画一条曲线,然后再画一条直线
ctx.beginPath(); ctx.moveTo(20, 20) ctx.lineTo(60, 20) ctx.arcTo(120, 20, 120, 40, 50) ctx.lineTo(120, 80) ctx.stroke(); 复制代码
这里在绘制曲线的时候要需要计算曲线半径,曲线半径设置错误之后效果体现不出来了
绘制矩形,有三个API与绘制矩形有关,分别是:
- fillRect(x, y, width, height)绘制一个填充的矩形
- strokeRect(x, y, width, height)绘制一个矩形的边框
- clearRect(x, y, width, height)清除指定矩形区域,让清除部分完全透明。
- rect(x, y, width, height)绘制一个左上角坐标为(x,y),宽高为width以及height的矩形。
参数:x——矩形的起点x坐标,y——矩形的起点y坐标,width——矩形的宽,height——矩形的高
ctx.fillRect(25, 25, 100, 100); ctx.clearRect(45, 45, 60, 60); ctx.strokeRect(50, 50, 50, 50); 复制代码
注意:重头戏要来了——二次贝塞尔曲线和三次贝塞尔曲线
如果你使用过PhotoShop的钢笔工具,你一定不会陌生贝塞尔曲线,放一个简书的链接,如果你对数学感兴趣可以看看
- quadraticCurveTo(cp1x, cp1y, x, y)绘制二次贝塞尔曲线,
cp1x,cp1y
为一个控制点,x,y为
结束点。 - bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)绘制三次贝塞尔曲线,
cp1x,cp1y
为控制点一,cp2x,cp2y
为控制点二,x,y
为结束点。
这里再贴一张MDN的图片,红点代表控制点,蓝点代表起始点和结束点
总之,贝塞尔曲线用于绘制不规则曲线,当然这可能需要你有耐心去计算,因为绘制的曲线没有给我们提供直接的视觉反馈
有关路径的API基本就是这些,但是在绘制过程中不可能一个路径一个路径地去绘制,canvas也提供了路径服用的方法——Path2D
Path2D是一个构造函数,可以用来克隆路径,比如
const path1 = new Path2D() path1.rect(10, 10, 100,100) const path2 = new Path2D(path1) path2.arc(225, 55, 55, 0, 2 * Math.PI) ctx.fill(path2); 复制代码
创建一个路径path1,绘制一个矩形,然后创建一个path2克隆path1,在此基础上绘制一个圆,最后只渲染path2,可以看到path1的内容也有了
样式和颜色
fillStyle = color
设置图形的填充颜色。strokeStyle = color
设置图形轮廓的颜色。
color的值跟css色彩的值是一样的,可以是16进制色彩、色彩英文单词、RGB以及RGBA,如
fillStyle = 'red' fillStyle = '#409eff' fillStyle = 'rgb(255, 255, 0)' fillStyle = 'rgba(255, 255, 255, 0.1)' 复制代码
rgba的最后一个参数是透明度,除此之外还提供了专门的API来设置透明度,globalAlpha
取值介于0(全透)-1(不透)之间,设置globalAlpha 之后透明度可以叠加,叠加越多透明度越低。
下面的API可以用来设置线条的样式
lineWidth = value
设置线条宽度。lineCap = type
设置线条末端样式。取值有butt(平齐),round(超出圆头)和 square(超出方形)。默认是 buttlineJoin = type
设定线条与线条间接合处的样式。miterLimit = value
限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。getLineDash()
返回一个包含当前虚线样式,长度为非负偶数的数组。setLineDash(segments)
设置当前虚线样式。接受一个数组,来指定线段与间隙的交替lineDashOffset = value
设置虚线样式的起始偏移量。
渐变作为一种比较炫酷的样式当然不能少了
createLinearGradient(x1, y1, x2, y2)
createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。createRadialGradient(x1, y1, r1, x2, y2, r2)
createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆
createLinearGradient 是线性渐变,createRadialGradient 是圆形渐变
在创建渐变对象之后就可以给他上色了,使用gradient.addColorStop(position, color)
方法给渐变对象上色,posotion是一个介于0-1的值,0.5表示在正中心渐变
var lineargradient = ctx.createLinearGradient(0,0,150,150); lineargradient.addColorStop(0,'white'); lineargradient.addColorStop(1,'black'); ctx.fillStyle = lineargradient ctx.fillRect(10,10,130,130) 复制代码
阴影也是一个非常好看的效果:
shadowOffsetX = float
:shadowOffsetX 用来设定阴影在 X 轴的延伸距离,不受变换矩阵所影响。负值表示阴影会往左延伸,正值则表示会往右延伸,默认为0
。shadowOffsetY = float
:shadowOffsetY用来设定阴影在 Y 轴的延伸距离,不受变换矩阵所影响。负值表示阴影会往上,正值则表示会往下,默认为0
。shadowBlur = float
:shadowBlur 用于设定阴影的模糊程度,默认为0
。shadowColor = color
:shadowColor 用于设定阴影颜色效果,默认是全透明的黑色。
在我们上一个渐变的基础上加上阴影
ctx.shadowOffsetX = 8; ctx.shadowOffsetY = 8; ctx.shadowBlur = 2; ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; 复制代码
填充规则fill(),填充我们之前已经用到很多了,他有两个规则,也就是参数nonzero
(默认路径内部)和evenodd
(路径外部),这是相对于当前路径来说的,在路径嵌套式效果明显