掌握Canvas,从这里开始

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): 绘制一个矩形边框

对于画布上下文的设置,主要利用fillStylestrokeStyle两个属性设置颜色等样式。

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();

线段和路径

  1. 首先,你需要创建路径起始点。
  2. 然后你使用画图命令去画出路径。
  3. 之后你把路径封闭。
  4. 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
  • 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绘制动画,一个动画由很多帧组成,每一帧都需要以下这些步骤:

  1. 清空canvas
  2. 保存canvas
  3. 绘制图形
  4. 恢复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, roundsquare, 默认值是butt`
lineJoin 线条与线条间接合处的样式,有3个值:round, bevelmiter
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

你可能感兴趣的:(掌握Canvas,从这里开始)