一、简介

1、Canvas

Canvas是依赖分辨率的位图画布,它绘制的图形是不可缩放的。在网页中,Canvas是一块矩形区域,默认的宽高为:300 * 150。可以使用Javascript在canvas中书写文字、绘图和实现一些动画等。

每个canvas都有一个上下文环境,使用canvas编程时,要先获取此上下文(context),然后在上下文中执行动作,最后将动作应用到上下文中。

var canvas = document.querySelector("#drawing-board");
var context = canvas.getContext("2d");
context.beginPath();
context.moveTo(50, 30);
context.lineTo(150, 30);
context.stroke();

2、坐标

canvas的坐标是从左上角开始(0,0),x轴(按像素)沿水平方向向右延伸,y轴没垂直方向向下延伸。

3、替换内容

可以在<canvas>标签中添加替换内容作为浏览器不支持canvas时的显示内容:

<canvas>
您的浏览器不支持canvas!
</canvas>

二、基础API

1、检查是否支持

参考:特性检测

2、路径

  • beginPath()

开始绘制新路径。

在绘制路径前,首先都要调用beginPath(),canvas需要根据此来计算图形的内部和外部范围,以便完成后续的描边和填充。

  • moveTo(x,y)

不绘制图形,只是将画笔移动到新的坐标(x,y)

  • lineTo(x,y)

绘制一条从当前坐标到(x,y)的直线

  • closePath()

将路径的起始坐标作为目标坐标,将当前路径闭合

  • stroke()

使用线条绘制图形

  • fill()

填充路径的内容区域(生成实心图形)

注:当调用fill()时,所有没有闭合的形状都会自动闭合,因此不需要调用closePath()
  • arc(x, y, radius, startAngle, endAngle, anticlockwise)

以(x,y)为圆心,以radius为半径,以startAngle为起始弧度endAngle为结束弧度,按anticlockwise指定的方向(默认为false,表示按顺时针方向)绘制圆弧。

context.beginPath();
context.arc(80, 80, 50, 0, 0.79, false);
context.stroke();
注:arc()函数中的度数为弧度。角度与弧度的换算:弧度=π/180角度;角度=180/π弧度
  • arcTo(x1, y1, x2, y2, radius)

在(x1, y1)和(x2, y2)之间画一条半径为radius的弧,并用直线连接前两个点(画弧前画笔位置和(x1, y1))。

注:当弧的半径过大时会调整两个控制点的x和y。
context.beginPath();
context.moveTo(150, 20);
context.arcTo(150, 100, 50, 100, 20);
context.stroke();

3、矩形

以(x,y)为矩形左上角顶点坐标,绘制一个width宽、height高的矩形:

  • strokeRect(x, y, width, height)

绘制一个矩形

  • fillRect(x, y, width, height)

绘制一个填充的矩形

  • clearRect(x, y, width, height)

清除指定的矩形区域,使此部分完全透明

context.fillRect(25, 25, 100, 100);
context.clearRect(45, 45, 60, 60);
context.strokeRect(50, 50, 50, 50);
  • rect(x, y, width, height)

将一个矩形路径添加到当前路径上

context.beginPath();
context.rect(10, 10, 50, 50);
context.stroke();

三、文本

1、绘制

  • fillText(text, x, y [, maxWidth])

在(x,y)位置绘制填充的text文本(实心字);maxWidth为绘制的最大宽度,可选

  • strokeText(text, x, y [, maxWidth])

在(x,y)位置绘制text文本轮廓(空心字);maxWidth为绘制的最大宽度,可选

2、样式

  • font = value

设置绘制文本的字体,和CSS的font属性相同;默认字体为:10px sans-serif

  • textAlign = value

设置文本的对齐方式,可选值为:start、end、left、right、center;默认值是:start

  • textBaseline = value

设置文本的基线,可选值为:top、hanging、middle、alphabetic、ideographic、bottom;默认值是:alphabetic

  • direction = value

设置文本的方向,可选值为:ltr、rtl、inherit;默认值是:inherit

ctx.font = "48px serif";
ctx.textBaseline = "hanging";
ctx.strokeText("Hello world", 0, 100);

3、尺寸

  • measureText()

返回文本的尺寸信息,返回值为TextMetrics对象

var metrics = ctx.measureText("foo"); // TextMetrics object
metrics.width; // 16;

四、样式

1、颜色(Colors)

  • fillStyle = color

设置图形的填充颜色

  • strokeStyle = color

设置图形的轮廓颜色

context.strokeStyle = "red";
context.stroke();
color的值可以是:CSS颜色值字符串、渐变对象或图案;默认值为黑色(#000000)。

2、透明度(Transparency)

  • globalAlpha = transparencyValue

设置canvas中所有图形的透明度,范围:0.0(完全透明) ~ 1.0(完全不透明)。

context.globalAlpha = 0.1;

也可以通过设置strokeStylefillStyle的值为rgba()颜色,并设置最后一个参数(透明度)来调整图形填充颜色或轮廓颜色的透明度。

context.fillStyle = "rgba(255, 0, 0, 0.1)";

3、线的样式(Line Styles)

  • lineWidth = value

设置线的宽度,值必须为正数,默认值为1.0

  • lineCap = type

设置线末端的样式,属性值为:butt、round或square,默认值为butt

  • lineJoin = type

设定线与线连接处的样式,属性值为:round、bevel或miter,默认值为miter

  • miterLimit = value

当两条线相交时,设置交接处(尖角)的最大长度,默认值为10.0。

当两条线的夹角较大时,交点不会太远;不夹角较小时,交点距离增大。因此,此属性值的效果在两条线夹角较小时比较明显。

  • getLineDash()

当前的虚线样式,返回长度为非负偶数的数组。

  • setLineDash(segments)

设置虚线样式,参数为一个数组,来设置线与空白间隔的距离。

如果数组为空,则线按实线绘制;如果数组是奇数,那么此数组的值为原数组拼接一份副本的结果,例如:[5, 15, 25]会变成[5, 15, 25, 5, 15, 25]。

ctx.setLineDash([4, 2]);
  • lineDashOffset = value

设置虚线的起始偏移量

4、渐变(Gradients)

  • createLinearGradient(x1, y1, x2, y2)

以(x1,y1)为起点,(x2,y2)为终点,创建线性渐变对象

  • createRadialGradient(x1, y1, r1, x2, y2, r2)

用以(x1,y1)为圆心、r1为半径和以(x2,y2)为圆心、r2为半径的圆初始化一个径向渐变对象。

  • gradient.addColorStop(position, color)

给渐变对象创建一个新的颜色的停止点。position为0.0到1.0的数值,表示渐变颜色的相对位置;color为一个有效的CSS颜色值。

//创建渐变对象
var lineargradient = ctx.createLinearGradient(0,0,150,150);

//设置相对位置上的渐变颜色,下面设置了从开始到½的位置是由白色渐变到黄色,从½位置到结束是由黄色渐变到黑色
lineargradient.addColorStop(0,'white');
lineargradient.addColorStop(0.5,'yellow');
lineargradient.addColorStop(1,'black');

//设置context的fillStyle或strokeStyle为该渐变对象
ctx.fillStyle = lineargradient;//radgrad;
ctx.fillRect(0, 0, 150, 150);

5、图案(Patterns)

  • createPattern(image, type)

创建并返回一个新的canvas图案对象。

imageCanvasImageSource类型,可以是一个Image对象或另一个canvas对象等。

type:值必须为repeat、repeat-x、repeat-y或no-repeat

//使用方式与渐变类似,都是先创建一个(图案)对象,
var img = new Image();
img.src = 'images/wallpaper.png';
img.onload = function(){
	//图片加载完后开始绘制
	drawSomething();
};

//再赋值给fillStyle或strokeStyle属性
ctx.fillStyle = ctx.createPattern(img,'repeat');
ctx.fillRect(0,0,150,150);

6、阴影(Shadows)

  • shadowColor = color

设置阴影颜色的效果,默认是全透明的黑色;color为标准的CSS颜色值

  • shadowBlur = float

设置阴影的模糊程度,默认值为0;此值越大,阴影边缘越模糊

  • shadowOffsetX = float

设置阴影在X轴上的延伸距离;值为正数时,阴影向右移动;值为负数时,阴影向左移动

  • shadowOffsetY = float

设置阴影在Y轴上的延伸距离;值为正数时,阴影向下移动;值为负数时,阴影向上移动

context.shadowColor = "rgba(0, 0, 0, 0.5)";
context.shadowBlur = 2;
context.shadowOffsetX = 2;
context.shadowOffsetY = -10;

context.fillText("Hello World!", 5, 30);

7、填充规则

当使用fillclipisPointInPath时,可以使用填充规则,填充规则的算法是根据某个点是处于路径的外面还是里面来决定是否被填充。

  • nonzero

非零环绕规则(默认的填充规则):首先使路径(多边形的边)变为矢量(有方向),然后从任意一点作一条射线,当从该点沿射线方向移动时,对每个方向上穿过射线的路径计数:当路径从右到左穿过射线时,环绕数加1;从左到右穿过射线时,环绕数减1。处理完所有路径(边)之后,若环绕数非零,则表示该点为内部点,要填充;否则为外部点,不填充。

  • evenodd

奇偶规则:从任意一点作一条射线,如果与该射线相交的路径个数为奇数,则表示该点在路径内部,要填充;否则,表示该点在路径外部,不填充。

参考资料