Canvas API 提供了一个通过JavaScript 和 HTML的元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。Canvas API 主要聚焦于 2D 图形。而同样使用元素的 WebGL API 则用于绘制硬件加速的 2D 和 3D 图形。(以上关于Canvas的介绍来自于MDN)
对于Canvas其实大家都不会很陌生了,在数据图形化上非常有名的ECharts便是基于Canvas实现的,以及一些动画的绘制,比如一个Icon从无到有通过的一个线段绘制过程,可以通过Svg也可以通过Canvas进行绘制。
Canvas是HTML5新增的Api因此我们可以直接在HTML中进行调用,而不需要引入对应的cdn链接。那么首先我们需要在页面上有这么一个canvas元素
以保证在JavaScript
中能得到canvas元素。
<canvas id="canvas">canvas>
在HTML
添加了Canvas元素之后便可以在JavaScript中对Canvas进行宽高等属性的配置了,⚠️注意:虽然Canvas也是一个HTML元素,但我们不推荐使用CSS对Canvas的宽高进行设置。这是因为使用CSS对Canvas元素进行赋值会导致画布中的元素被拉伸,稍后会使用一个例子进行说明。
const oCanvas = document.getElementById('canvas'),
// 获取画布的上下文,你可以选择 '2d' 或者 'webgl' 以使用不同的上下文api
ctx = oCanvas.getContext('2d');
// 对于画布宽高的设置,我们应该通过JS属性赋值的方式完成,而不是使用CSS
// 因为使用CSS可能会导致画布被拉伸
const clientWidth = document.documentElement.clientWidth,
clientHeight = document.documentElement.clientHeight;
// 且给Canvas设置宽高时不需要加上'px',并不是给Canvas增加样式
// 而是给Canvas画布添加样式
oCanvas.width = clientWidth;
oCanvas.height = clientHeight;
我已经事先在Canvas画布中绘制了一个三角形与一个圆形,当我们使用CSS对Canvas元素的宽高进行修改时,只会影响于Canvas元素而不会作用于画布元素,那么画布中的内容将受到对应方向的缩放与拉伸,因此当宽高比改变的时候,原有的图片将发生形变。
上述的效果是通过修改画布的宽高比实现的,假设原有的比例为19:10,修改后的比例就是10:19,那么图片就会因为宽高比被修改而发生形变,这就不是我们希望得到的效果了。
而通过JavaScript对Canvas进行修改,不仅会修改Canvas元素的宽高,同时会作用于画布,不过这一点不容易看出来,因为每当你对Canvas“画布”尺寸进行修改的时候,都会触发Canvas都clearRect方法,会清除画布中存在的所有线条,因此我们得到的效果如下:
在认识了Canvas的尺寸设置之后,我们可以开始着手Canvas图形的绘制,那么首先我们需要认识的便是最简单的直线。我们在画板上绘制一条线会有哪些步骤呢?首先将笔移动到线的起点,接着向目标方向进行拖拽,接着便是抬起笔尖,绘制完成。
在Canvas中也是类似的,我们可以想象Context上下文便是一个画笔,我们首先要将笔尖移动到初始位置,接着向目标位置滑动,接着抬起笔尖。
// 绘制一条线段
// 首先我们需要调用beginPath方法,该方法会清除之前的路径
ctx.beginPath();
// 然后我们需要调用moveTo方法,将画笔移动到指定位置
ctx.moveTo(100, 100);
// 接着我们需要调用lineTo方法,从画笔位置开始画线,画到指定位置
ctx.lineTo(300, 300);
// 最后我们需要调用stroke方法,将线条绘制出来
ctx.stroke();
当完成上述方法后,我们便可以在页面中看到绘制出的一条线:
在知道如何绘制一个直线之后,我们就可以完成各种支线相关图形的绘制了,比如一个矩形、一个三角形。这里我们以一个等腰直角三角形为例,我们需要做的便是确定三角形的三个端点的坐标,打个比方:(300, 300)、(500, 300)、(300, 500)
便可以构建出一个等腰直角三角形,只需要将画笔移动至端点(300,300)并依次向另外两个顶点绘制一条直线:
ctx.beginPath();
ctx.moveTo(300, 300);
ctx.lineTo(500, 300);
ctx.lineTo(300, 500);
ctx.lineTo(300, 300);
ctx.stroke();
这样我们就得到了一个等腰直角三角形如下:
圆形的绘制则是通过对弧的绘制完成的,着Canvas中有这么一个Api:arc(cx, cy, radius, startAngle, endAngle, anticlockwise)
,可以在画布上绘制一个弧,它的参数分别是弧的圆心坐标,以及弧的半径、起始与终止的弧度。那么当我们想要绘制一个圆的时候,只需要让起始弧度与终止弧度的差值达到360度即可。举个例子:
// 开始绘制,清除之前的路径
ctx.beginPath();
// 配置圆弧的参数
ctx.arc(500, 500, 100, 0, Math.PI * 2, false);
// 绘制圆弧
ctx.stroke();
此处需要提醒一个各位,在配置圆弧参数的时候我们需要注意:
弧度使用的是弧度单位,而不是角度单位,即180°应使用Math.PI
进行表示。
在Canvas画布中的弧度是以顺时针方向绘制,即顺时针方向为正角。
默认的画弧是以顺时针的方式进行,也就是从startAngle顺时针旋转至endAngle的弧度,而当配置最后一个参数是否逆时针绘制为true时,将以逆时针的方式进行绘制,下面以0-60度为例:
a. 顺时针绘制:将以顺时针方向绘制60度
b. 逆时针方向:将以逆时针的方式旋转至60°,这样将绘制出一个大弧,也就是60°的周补角
// 默认顺时针方向旋转
ctx.arc(500, 500, 100, 0, Math.PI / 3, false);
// 设置为逆时针方向
ctx.arc(500, 500, 100, 0, Math.PI / 3, true);
以上便是本文全部的内容,本文简单介绍了Canvas及其两个简单图形的绘制,以及CSS、JavaScript修改样式对Canvas的影响。
下一篇将利用Canvas实现一个画板功能,感谢观看本文。