Canvas API:绘制图形
Canvas 画布提供了一个作图的平面空间,该空间的每个点都有自己的坐标。原点(0, 0)
位于图像左上角,x
轴的正向是原点向右,y
轴的正向是原点向下。
路径
以下方法和属性用来绘制路径。
CanvasRenderingContext2D.beginPath()
:开始绘制路径。CanvasRenderingContext2D.closePath()
:结束路径,返回到当前路径的起始点,会从当前点到起始点绘制一条直线。如果图形已经封闭,或者只有一个点,那么此方法不会产生任何效果。CanvasRenderingContext2D.moveTo()
:设置路径的起点,即将一个新路径的起始点移动到(x,y)
坐标。CanvasRenderingContext2D.lineTo()
:使用直线从当前点连接到(x, y)
坐标。CanvasRenderingContext2D.fill()
:在路径内部填充颜色(默认为黑色)。CanvasRenderingContext2D.stroke()
:路径线条着色(默认为黑色)。CanvasRenderingContext2D.fillStyle
:指定路径填充的颜色和样式(默认为黑色)。CanvasRenderingContext2D.strokeStyle
:指定路径线条的颜色和样式(默认为黑色)。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(100, 200);
上面代码只是确定了路径的形状,画布上还看不出来,因为没有颜色。所以还需要着色。
ctx.fill()
// 或者
ctx.stroke()
上面代码中,这两个方法都可以使得路径可见。fill()
在路径内部填充颜色,使之变成一个实心的图形;stroke()
只对路径线条着色。
这两个方法默认都是使用黑色,可以使用fillStyle
和strokeStyle
属性指定其他颜色。
ctx.fillStyle = 'red';
ctx.fill();
// 或者
ctx.strokeStyle = 'red';
ctx.stroke();
上面代码将填充和线条的颜色指定为红色。
线型
以下的方法和属性控制线条的视觉特征。
CanvasRenderingContext2D.lineWidth
:指定线条的宽度,默认为1.0。CanvasRenderingContext2D.lineCap
:指定线条末端的样式,有三个可能的值:butt
(默认值,末端为矩形)、round
(末端为圆形)、square
(末端为突出的矩形,矩形宽度不变,高度为线条宽度的一半)。CanvasRenderingContext2D.lineJoin
:指定线段交点的样式,有三个可能的值:round
(交点为扇形)、bevel
(交点为三角形底边)、miter
(默认值,交点为菱形)。CanvasRenderingContext2D.miterLimit
:指定交点菱形的长度,默认为10。该属性只在lineJoin
属性的值等于miter
时有效。CanvasRenderingContext2D.getLineDash()
:返回一个数组,表示虚线里面线段和间距的长度。CanvasRenderingContext2D.setLineDash()
:数组,用于指定虚线里面线段和间距的长度。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(100, 200);
ctx.lineWidth = 3;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.setLineDash([15, 5]);
ctx.stroke();
上面代码中,线条的宽度为3,线条的末端和交点都改成圆角,并且设置为虚线。
矩形
以下方法用来绘制矩形。
CanvasRenderingContext2D.rect()
:绘制矩形路径。CanvasRenderingContext2D.fillRect()
:填充一个矩形。CanvasRenderingContext2D.strokeRect()
:绘制矩形边框。CanvasRenderingContext2D.clearRect()
:指定矩形区域的像素都变成透明。
上面四个方法的格式都一样,都接受四个参数,分别是矩形左上角的横坐标和纵坐标、矩形的宽和高。
CanvasRenderingContext2D.rect()
方法用于绘制矩形路径。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.rect(10, 10, 100, 100);
ctx.fill();
上面代码绘制一个正方形,左上角坐标为(10, 10)
,宽和高都为100。
CanvasRenderingContext2D.fillRect()
用来向一个矩形区域填充颜色。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 100, 100);
上面代码绘制一个绿色的正方形,左上角坐标为(10, 10)
,宽和高都为100。
CanvasRenderingContext2D.strokeRect()
用来绘制一个矩形区域的边框。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.strokeStyle = 'green';
ctx.strokeRect(10, 10, 100, 100);
上面代码绘制一个绿色的空心正方形,左上角坐标为(10, 10)
,宽和高都为100。
CanvasRenderingContext2D.clearRect()
用于擦除指定矩形区域的像素颜色,等同于把早先的绘制效果都去除。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(10, 10, 100, 100);
ctx.clearRect(15, 15, 90, 90);
上面代码先绘制一个 100 x 100 的正方形,然后在它的内部擦除 90 x 90 的区域,等同于形成了一个5像素宽度的边框。
弧线
以下方法用于绘制弧形。
CanvasRenderingContext2D.arc()
:通过指定圆心和半径绘制弧形。CanvasRenderingContext2D.arcTo()
:通过指定两根切线和半径绘制弧形。
CanvasRenderingContext2D.arc()
主要用来绘制圆形或扇形。
// 格式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
// 实例
ctx.arc(5, 5, 5, 0, 2 * Math.PI, true)
arc()
方法的x
和y
参数是圆心坐标,radius
是半径,startAngle
和endAngle
则是扇形的起始角度和终止角度(以弧度表示),anticlockwise
表示做图时应该逆时针画(true
)还是顺时针画(false
),这个参数用来控制扇形的方向(比如上半圆还是下半圆)。
下面是绘制实心圆形的例子。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(60, 60, 50, 0, Math.PI * 2, true);
ctx.fill();
上面代码绘制了一个半径50,起始角度为0,终止角度为 2 * PI 的完整的圆。
绘制空心半圆的例子。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.arc(100, 20, 50, 0, Math.PI, false);
ctx.stroke();
CanvasRenderingContext2D.arcTo()
方法主要用来绘制圆弧,需要给出两个点的坐标,当前点与第一个点形成一条直线,第一个点与第二个点形成另一条直线,然后画出与这两根直线相切的弧线。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arcTo(50, 50, 100, 0, 25);
ctx.lineTo(100, 0);
ctx.stroke();
上面代码中,arcTo()
有5个参数,前两个参数是第一个点的坐标,第三个参数和第四个参数是第二个点的坐标,第五个参数是半径。然后,(0, 0)
与(50, 50)
形成一条直线,然后(50, 50)
与(100, 0)
形成第二条直线。弧线就是与这两根直线相切的部分。
文本
以下方法和属性用于绘制文本。
CanvasRenderingContext2D.fillText()
:在指定位置绘制实心字符。CanvasRenderingContext2D.strokeText()
:在指定位置绘制空心字符。CanvasRenderingContext2D.measureText()
:返回一个 TextMetrics 对象。CanvasRenderingContext2D.font
:指定字型大小和字体,默认值为10px sans-serif
。CanvasRenderingContext2D.textAlign
:文本的对齐方式,默认值为start
。CanvasRenderingContext2D.direction
:文本的方向,默认值为inherit
。CanvasRenderingContext2D.textBaseline
:文本的垂直位置,默认值为alphabetic
。
fillText()
方法用来在指定位置绘制实心字符。
CanvasRenderingContext2D.fillText(text, x, y [, maxWidth])
该方法接受四个参数。
text
:所要填充的字符串。x
:文字起点的横坐标,单位像素。y
:文字起点的纵坐标,单位像素。maxWidth
:文本的最大像素宽度。该参数可选,如果省略,则表示宽度没有限制。如果文本实际长度超过这个参数指定的值,那么浏览器将尝试用较小的字体填充。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.fillText('Hello world', 50, 50);
上面代码在(50, 50)
位置写入字符串Hello world
。
注意,fillText()
方法不支持文本断行,所有文本一定出现在一行内。如果要生成多行文本,只有调用多次fillText()
方法。
strokeText()
方法用来添加空心字符,它的参数与fillText()
一致。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.strokeText('Hello world', 50, 50);
上面这两种方法绘制的文本,默认都是10px
大小、sans-serif
字体,font
属性可以改变字体设置。该属性的值是一个字符串,使用 CSS 的font
属性即可。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.font = 'Bold 20px Arial';
ctx.fillText('Hello world', 50, 50);
textAlign
属性用来指定文本的对齐方式。它可以取以下几个值。
left
:左对齐right
:右对齐center
:居中start
:默认值,起点对齐(从左到右的文本为左对齐,从右到左的文本为右对齐)。end
:结尾对齐(从左到右的文本为右对齐,从右到左的文本为左对齐)。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.font = 'Bold 20px Arial';
ctx.textAlign = 'center';
ctx.fillText('Hello world', 50, 50);
direction
属性指定文本的方向,默认值为inherit
,表示继承<canvas>
或document
的设置。其他值包括ltr
(从左到右)和rtl
(从右到左)。
textBaseline
属性指定文本的垂直位置,可以取以下值。
top
:上部对齐(字母的基线是整体上移)。hanging
:悬挂对齐(字母的上沿在一根直线上),适用于印度文和藏文。middle
:中部对齐(字母的中线在一根直线上)。alphabetic
:默认值,表示字母位于字母表的正常位置(四线格的第三根线)。ideographic
:下沿对齐(字母的下沿在一根直线上),使用于东亚文字。bottom
:底部对齐(字母的基线下移)。对于英文字母,这个设置与ideographic
没有差异。
measureText()
方法接受一个字符串作为参数,返回一个 TextMetrics 对象,可以从这个对象上面获取参数字符串的信息,目前主要是文本渲染后的宽度(width
)。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var text1 = ctx.measureText('Hello world');
text.width // 49.46
ctx.font = 'Bold 20px Arial';
text2.width // 107.78
上面代码中,10px
大小的字符串Hello world
,渲染后宽度为49.46
。放大到20px
以后,宽度为107.78
。
渐变色和图像填充
以下方法用于设置渐变效果和图像填充效果。
CanvasRenderingContext2D.createLinearGradient()
:定义线性渐变样式。CanvasRenderingContext2D.createRadialGradient()
:定义辐射渐变样式。CanvasRenderingContext2D.createPattern()
:定义图像填充样式。
createLinearGradient()
方法按照给定直线,生成线性渐变的样式。
ctx.createLinearGradient(x0, y0, x1, y1)
ctx.createLinearGradient(x0, y0, x1, y1)
方法接受四个参数:x0
和y0
是起点的横坐标和纵坐标,x1
和y1
是终点的横坐标和纵坐标。通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。
该方法的返回值是一个CanvasGradient
对象,该对象只有一个addColorStop()
方向,用来指定渐变点的颜色。addColorStop()
方法接受两个参数,第一个参数是0到1之间的一个位置量,0表示起点,1表示终点,第二个参数是一个字符串,表示 CSS 颜色。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var gradient = ctx.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, 'green');
gradient.addColorStop(1, 'white');
ctx.fillStyle = gradient;
ctx.fillRect(10, 10, 200, 100);
上面代码中,定义了渐变样式gradient
以后,将这个样式指定给fillStyle
属性,然后fillRect()
就会生成以这个样式填充的矩形区域。
createRadialGradient()
方法定义一个辐射渐变,需要指定两个圆。
ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
createRadialGradient()
方法接受六个参数,x0
和y0
是辐射起始的圆的圆心坐标,r0
是起始圆的半径,x1
和y1
是辐射终止的圆的圆心坐标,r1
是终止圆的半径。
该方法的返回值也是一个CanvasGradient
对象。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var gradient = ctx.createRadialGradient(100, 100, 50, 100, 100, 100);
gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'green');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 200, 200);
上面代码中,生成辐射样式以后,用这个样式填充一个矩形。
createPattern()
方法定义一个图像填充样式,在指定方向上不断重复该图像,填充指定的区域。
ctx.createPattern(image, repetition)
该方法接受两个参数,第一个参数是图像数据,它可以是<img>
元素,也可以是另一个<canvas>
元素,或者一个表示图像的 Blob 对象。第二个参数是一个字符串,有四个可能的值,分别是repeat
(双向重复)、repeat-x
(水平重复)、repeat-y
(垂直重复)、no-repeat
(不重复)。如果第二个参数是空字符串或null
,则等同于null
。
该方法的返回值是一个CanvasPattern
对象。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'https://example.com/pattern.png';
img.onload = function( ) {
var pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 400, 400);
};
上面代码中,图像加载成功以后,使用createPattern()
生成图像样式,然后使用这个样式填充指定区域。
阴影
以下属性用于设置阴影。
CanvasRenderingContext2D.shadowBlur
:阴影的模糊程度,默认为0
。CanvasRenderingContext2D.shadowColor
:阴影的颜色,默认为black
。CanvasRenderingContext2D.shadowOffsetX
:阴影的水平位移,默认为0
。CanvasRenderingContext2D.shadowOffsetY
:阴影的垂直位移,默认为0
。
下面是一个例子。
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.shadowOffsetX = 10;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 5;
ctx.shadowColor = 'rgba(0,0,0,0.5)';
ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 100, 100);