绘制形状
canvas元素默认被网格所覆盖。通常来说网格中的一个单元相当于canvas元素中的一像素。栅格的起点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X轴)x像素,距离上边(Y轴)y像素(坐标为(x,y))。
路径path
路径绘制图形步骤:
- 创建路径起始点,
beginPath()
新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。 - 使用画图命令去画出路径,如:
ctx.strokeRect(50, 50, 50, 50)
- 封闭路径,
closePath()
闭合路径之后图形绘制命令又重新指向到上下文中,不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。 - 一旦路径生成,就能通过描边或填充路径区域来渲染图形。
stroke()
通过线条来绘制图形轮廓;fill()
通过填充路径的内容区域生成实心的图形。
直线lineTo
语法:
context.lineTo(x, y);
参数 | 描述 |
---|---|
x | 路径的目标位置x坐标 |
y | 路径的目标位置y坐标 |
var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); // 填充三角形 ctx.beginPath(); ctx.moveTo(25,25); ctx.lineTo(105,25); ctx.lineTo(25,105); ctx.fill(); // 描边三角形 ctx.beginPath(); ctx.moveTo(125,125); ctx.lineTo(125,45); ctx.lineTo(45,125); ctx.closePath(); ctx.stroke(); }
矩形rect
语法:
context.rect(x, y, width, height); context.fillRect(x, y, width, height); context.clearRect(x, y, width, height); context.strokeRect(x, y, width, height);
参数值:
参数 | 描述 |
---|---|
x | 矩形左上角的 x 坐标 |
y | 矩形左上角的 y 坐标 |
width | 矩形的宽度,以像素计 |
height | 矩形的高度,以像素计 |
var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.fillRect(25, 25, 100, 100); ctx.clearRect(45, 45, 60, 60); ctx.strokeRect(50, 50, 50, 50); // 红色矩形 ctx.beginPath(); ctx.lineWidth="6"; ctx.strokeStyle="red"; ctx.rect(0,0,150,150); ctx.stroke(); }
fillRect()
函数绘制了一个边长为100px的黑色正方形。clearRect()
函数从正方形的中心开始擦除了一个6060px的正方形,接着strokeRect()
在清除区域内生成一个5050的正方形边框。
绘制三角形
var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.moveTo(75, 50); //moveTo(x, y) 将笔触移动到指定的坐标x以及y上。 ctx.lineTo(100, 75); ctx.lineTo(100, 25); ctx.fill(); }
圆形arc
语法:
context.arc(x,y,r,sAngle,eAngle,counterclockwise);
参数值:
参数 | 描述 |
---|---|
x | 圆的中心的 x 坐标。 |
y | 圆的中心的 y 坐标。 |
r | 圆的半径。 |
sAngle | 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。 |
eAngle | 结束角,以弧度计。 |
counterclockwise | 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。 |
var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(75,75,50,0,Math.PI*2,true); // 绘制 ctx.moveTo(110,75); ctx.arc(75,75,35,0,Math.PI,false); // 口(顺时针) ctx.moveTo(65,65); ctx.arc(60,65,5,0,Math.PI*2,true); // 左眼 ctx.moveTo(95,65); ctx.arc(90,65,5,0,Math.PI*2,true); // 右眼 ctx.stroke(); // 无moveTo则展现完整路径 ctx.beginPath(); ctx.strokeStyle="red"; ctx.arc(175,75,50,0,Math.PI*2,true); // 绘制 //ctx.moveTo(210,75); ctx.arc(175,75,35,0,Math.PI,false); // 口(顺时针) //ctx.moveTo(165,65); ctx.arc(160,65,5,0,Math.PI*2,true); // 左眼 //ctx.moveTo(195,65); ctx.arc(190,65,5,0,Math.PI*2,true); // 右眼 ctx.stroke(); }
圆弧arcTo
语法:
arcTo(x1, y1, x2, y2, radius)
参数 | 描述 |
---|---|
x1 | 切线起点的 x 坐标。 |
y1 | 切线起点的 y 坐标。 |
x2 | 切线终点的 x 坐标。 |
y2 | 切线终点的 y 坐标。 |
r | 圆的半径。 |
点(x1, y1)
分别与点(x2, y2)
及当前笔触点(x0, y0)
构成两条切线,绘制的弧线是两个切点之间以r为半径的最短圆弧。
/* * * ctx 画布 * x , y 左上角坐标 * width, height 矩形宽高 * r 弧形半径 * */ function drawRoundedRect(ctx, x, y, width, height, r) { ctx.save(); ctx.beginPath(); // draw top and top right corner ctx.moveTo(x + r, y); ctx.arcTo(x + width, y, x + width, y + r, r); // draw right side and bottom right corner ctx.arcTo(x + width, y + height, x + width - r, y + height, r); // draw bottom and bottom left corner ctx.arcTo(x, y + height, x, y + height - r, r); // draw left and top left corner ctx.arcTo(x, y, x + r, y, r); ctx.fill(); ctx.stroke(); ctx.restore(); } var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); drawRoundedRect(ctx, 20, 20, 100, 100, 10); }
贝塞尔曲线
贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,
二阶贝塞尔
原理:AD/AB = BE/BC = DF/DE
语法:
context.quadraticCurveTo(cpx,cpy,x,y);
参数值:
|参数|描述|
|:-|:-|
|cpx |贝塞尔控制点的 x 坐标|
|cpy |贝塞尔控制点的 y 坐标|
|x |结束点的 x 坐标|
|y |结束点的 y 坐标|
var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); // 二次贝塞尔曲线 ctx.beginPath(); ctx.moveTo(75,25); ctx.quadraticCurveTo(25,25,25,62.5); ctx.quadraticCurveTo(25,100,50,100); ctx.quadraticCurveTo(50,120,30,125); ctx.quadraticCurveTo(60,120,65,100); ctx.quadraticCurveTo(125,100,125,62.5); ctx.quadraticCurveTo(125,25,75,25); ctx.stroke(); }
三阶贝塞尔
语法:
context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
参数值:
|参数|描述|
|:-|:-|
|cp1x |第一个贝塞尔控制点的 x 坐标|
|cp1y |第一个贝塞尔控制点的 y 坐标|
|cp2x |第二个贝塞尔控制点的 x 坐标|
|cp2y |第二个贝塞尔控制点的 y 坐标|
|x |结束点的 x 坐标|
|y |结束点的 y 坐标|
四阶贝塞尔
五阶贝塞尔
Path2D 对象
Path2D用来缓存或记录绘画命令,这样你将能快速地回顾路径。
Path2D()会返回一个新初始化的Path2D对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含SVG path数据的字符串作为变量)。
new Path2D(); // 空的Path对象 new Path2D(path); // 克隆Path对象 new Path2D(d); // 从SVG建立Path对象
所有的路径方法比如moveTo, rect, arc或quadraticCurveTo等,如我们前面见过的,都可以在Path2D中使用。
Path2D API 添加了 addPath作为将path结合起来的方法。当你想要从几个元素中来创建对象时,这将会很实用。比如:
Path2D.addPath(path [, transform])
添加了一条路径到当前路径(可能添加了一个变换矩阵)。
Path2D可以使用SVG path data来初始化canvas上的路径。
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); var rectangle = new Path2D(); rectangle.rect(10, 10, 50, 50); var circle = new Path2D(); circle.moveTo(125, 35); circle.arc(100, 35, 25, 0, 2 * Math.PI); ctx.stroke(rectangle); ctx.fill(circle); }