Canvas是HTML5中一个重要的组件,提供了一系列接口使得可以开发者可以利用Js绘制各种图表、动画。
Canvas浏览器检测
如果你的代码需要兼容旧的浏览器,则可以如下代码来检测:
const canvas = document.querySelector("#canvas");
if (canvas.getContext) {
// do something
} else {
// fallback
}
或者使用Modernizr库来识别浏览器是否支持Canvas:
if (Modernizr.canvas) {
// canvas code
} else {
// fallback code
}
不过对于大家常用的现代浏览器来说,Canvas已经算是标配了。所以上述代码加不加其实主要看产品的需求。
Canvas 特点
Canvas提供了一系列绘图接口,且都是基于像素的,所以我们可以利用Canvas实现很多有趣的功能,比如截图、图片渲染等。常用的接口主要有画图片,文本,线条以及gradients等,Canvas还支持和CSS3 的transform类似的变换操作,不过不支持动画(animation)。
我们在使用canvas时,主要有以下几个步骤:
- 定义一个canvas元素
- 设置canvas的一些属性(如宽高等)
- 获得2d context上下文对象
- 画图
例子如下:
const canvas = document.createElement("canvas");
canvas.width = 200;
canvas.height = 200;
const context = canvas.getContext("2d");
context.fillRect(0, 0, 20, 20);
document.body.appendChild(canvas);
基础知识
在Canvas中,画布的坐标空间是从左上角开始的:
[图片上传失败...(image-44c488-1578909996036)]
所有绘制的元素都会基于原点进行定位,不过canvas中也提供了接口来变换原点位置。
矩形和椭圆
在canvas中如果你想要画矩形的话,主要有以下3个方法:
- clearRect(x, y, width, height): 清除指定矩形区域
- fillRect(x, y, width, height): 绘制填充的矩形
- strokeRect(x, y, w, h): 绘制一个矩形边框
对于画布上下文的设置,主要利用fillStyle
和strokeStyle
两个属性设置颜色等样式。
const canvas = document.querySelector("#mycanvas");
const ctx = canvas.getContext("2d");
ctx.fillRect(20, 20, 100, 200); // 绘制一个宽100,高100的矩形
而要画一个椭圆的话,主要借助两个接口:
- arc(x, y, radius, startAngle, endAngle, antiClockwise): 画一个以(x, y)为圆心,radius为半径的圆弧,从startAngle开始到endAngle结束,antiClosewise为绘制方向,默认是顺时针
- arcTo(x1, y1, x2, y2, radius): 根据(x1, y1)和(x2, y2),已经半径来绘制圆弧,再以直线连接两个控制点
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.arc(50, 50, 10, 0, Math.PI * 0.5, false);
ctx.fill();
线段和路径
- 首先,你需要创建路径起始点。
- 然后你使用画图命令去画出路径。
- 之后你把路径封闭。
- 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
- beginPath(): 新建路径,生成之后,图形绘制命令被指向到路径上生成路径
- bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y): 三次贝塞尔曲线,(cp1x,cp1y)为控制点一,(cp2x,cp2y)为控制点二,(x,y)为结束点
- closePath(): 闭合路径
- moveTo(x, y): 移动到某个点,以这个点为基础来绘制图形
- quadraticCurveTo(cpx, cpy, x, y): 二次贝塞尔曲线,(cpx,cpy)为一个控制点,(x,y)为结束点
- stroke(): 绘制轮廓
- fill(): 填充路径内容区域
主要使用的属性有:
lineCap, lineJoin, lineWidth, miterLimit
以下是例子:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 绘制一个三角形
ctx.beginPath(); // 生成路径
ctx.moveTo(75, 50); // 以 (75, 50)这个坐标为起点开始绘制
ctx.lineTo(100, 75); // 移动到(100,75)这个坐标画一条线
ctx.lineTo(100, 25); // 再移动到 (100, 25)这个坐标画一条线
ctx.fill(); // 填充图形,没有闭合的图形会自动闭合,所以无需调用closePath接口
文本
绘制文本我们主要用以下两种接口:
- fillText(text, x, y, [maxWidth]): 在x, y处绘制指定文本,可以选择最大宽度
- strokeText(text, x, y, [maxWidth]): 在x, y处绘制指定文本的边框,可以选择最大宽度
ctx.font = "16px serif";
ctx.strokeText("Hello", 50, 50);
图片
图片绘制也是canvas中常用的功能,可以使用如下接口来实现:
- drawImage(image, x, y, [width], [height]): 其中
image
是 image 或者 canvas 对象,(x,y)为绘制的起点
const image = new Image();
image.onload(function() {
ctx.drawImage(image, 0, 0, 100, 100);
});
image.src = "http://xxxx";
动画
可以利用canvas绘制动画,一个动画由很多帧组成,每一帧都需要以下这些步骤:
- 清空canvas
- 保存canvas
- 绘制图形
- 恢复canvas
然后可以使用requestAnimationFrame来执行一个动画,对于旧的浏览器则使用setInterval来调用回调函数。
例子可以参考: https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Basic_animations
Path2D
Path2D 是一个比较新的对象,利用它可以缓存和记录已有的路径信息,以便在后续复用。
主要有以下三种方式新建一个Path2D对象:
- new Path(): 空的path对象
- new Path2D(path): 克隆一个新的Path对象
- new Path2D(d): 从SVG建立Path对象, d 为svg路径字符串如: "M10 10 h 80 v 80 h -80 Z"
const 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);
接口
最后来列举一下Canvasa中所有常见的接口以及对应的功能,在忘记的时候能够快速索引到:
接口 | 功能描述 |
---|---|
addColorStop | 绘制过渡效果是添加结束点的颜色 |
drawImage | 绘制图片 |
restore | 从栈中恢复上下文 |
arc | 绘制弧线 |
fill | 填充 |
rotate(angle) | 以原点为中心旋转canvas |
arcTo | 绘制圆弧 |
fillRect | 填充矩形 |
save | 将上下文保存到栈中 |
beginPath | 开始路径 |
fillText | 填充文本 |
scale(x, y) | 缩放画布 |
bezierCurveTo | 曲线 |
getImageData | 获得图片数据 |
setTransform(m11, m12, m21, m22, dx, dy) | 设置变换矩阵 |
clearRect | 清楚矩形区域 |
isPointInPath | 判断像素点是否在对应的路径上 |
stroke | 绘制轮廓 |
clip | 裁剪 |
lineTo | 绘制直线 |
strokeRect | 绘制矩形轮廓 |
closePath | 关闭路径 |
measureText | 返回一个包含指定文本宽度的对象(以像素为单位) |
strokeText | 绘制文本轮廓 |
createImageData | 创建图片像素数据 |
moveTo | 移动到某点,并以这个点为基础绘制图形 |
transform(m11, m12, m21, m22, dx, dy) | 使用变换矩阵 |
createLinearGradient | 创建一个线性过渡对象 |
putImageData | 将图像数据放回画布 |
translate | 移动canvas和原点到(x,y)上 |
createPattern | 图像填充,在指定的方向内重复指定的元素 |
quadraticCurveTo | 二次贝塞尔曲线 |
createRadialGradient | 创建一条放射颜色渐变 |
rect | 创建矩形 |
API 属性有:
属性 | 描述 |
---|---|
data | Uint8ClampedArray 类型的一维数组,包含着RGBA格式的整型数据,范围在0至255之间(包括255),ImageData对象的属性 |
miterLimit | miterLimit 属性就是用来设定外延交点与连接点的最大距离,如果交点距离大于此值,连接效果会变成了 bevel。 |
fillStyle | 填充颜色 |
shadowBlur | 阴影的模糊程度,默认为0 |
font | 绘制文本时的字体,默认的字体是 10px sans-serif |
shadowColor | 阴影颜色,默认是全透明的黑色 |
globalAlpha | 透明度,从0.0 到 1.0 |
globalCompositeOperation | 在画新图形时采用的遮盖策略,其值是一个标识12种遮盖方式的字符串,参考 |
lineCap | 线条末端样式,butt , round 和 square, 默认值是 butt` |
lineJoin | 线条与线条间接合处的样式,有3个值:round , bevel 和miter |
lineWidth | 线条宽度 |
shadowOffsetX | 用来设定阴影在X轴的延伸距离 |
shadowOffsetY | 用来设定阴影在Y 轴的延伸距离 |
strokeStyle | 图形轮廓颜色 |
textAlign | 绘制文本的对齐选项,可选的值包括:start , end , left , right or center . 默认值是 start |
textBaseline | 绘制文本时的基线对齐选项. 可选的值包括:top , hanging , middle , alphabetic , ideographic , bottom 。默认值是 alphabetic。 |
direction | 绘制文本的方向,可能的值包括:ltr , rtl , inherit 。默认值是 inherit |
参考资料
https://html.spec.whatwg.org/multipage/canvas.html
https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes