Canvas 简单入门小教程

简介: 前端西瓜哥

大家好,我是前端西瓜哥。今天简单说说 Canvas 入门的基础知识。

Canvas 是以 <Cavnas> 作为显示载体,并通过 JavaScript 脚本来绘制位图的技术。

canvas 元素

canvas,画布,这个名字就非常形象,是我们绘制图像的地方。对应的 DOM 元素就是 <canvas>

我们通过 width 和 height 来设置 canvas 元素的宽高。

<canvas width="500" height="500"></canvas>

width 和 height 只支持数字,单位为 CSS 像素值(px),默认值分别为 300 和 150。

如果你提供的是 "100%",它会转换为 100;如果你提供的是非数字,结果就是设置失败,然后拿到默认值。

你可以认为 canvas 获取宽高时进行了类似 parseInt 的处理。

另外,如果你手动修改了 canvas 的宽或高,canvas 的内容会全部清空。

需要特别注意的是,canvas 的宽高不能通过 style 属性来设置。style.widthstyle.height 其实是在设置了宽高的 canvas 上再进行了缩放。某种意义上,你可以把 canvas 元素当作 img 元素。

canvas 的宽高并不是可以设置为无限大的,不同的浏览器允许的最大宽高不同。一旦超过,就会啪地一下变成了 0。一般来说我们没有设置很大的宽高的需求,通常最大为显示屏的宽高就差不多了。

渲染上下文

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

在绘制图形之前,我们需要做一些准备工作,通过 canvas 元素调用 getContext,拿到一个渲染上下文 context。

就好比是拿到只能在特定画布上的画布的画笔。

坐标系

对于计算机来说,坐标系的原点位于屏幕的左上角,向下为 y 轴正方向,向右为 x 轴正方向。

这点和我们学数学坐标系有点不同,要注意一下。

下面我们来看看怎么绘制各种图形。

画个矩形

ctx.fillStyle = '#f04'; // 红色
ctx.fillRect(10 , 10, 200, 100); // 矩形(填充)
ctx.strokeStyle = 'black';
ctx.lineWidth = 4;
ctx.strokeRect(10, 10, 200, 100); // 矩形(描边)

这两个方法都要传入矩形的左上角位置 (10, 10) 和宽高(200 和 100)。

fillRect 用于填充矩形区域,strokeRect 则是描边。

fillStyle 用于设置填充的颜色,strokeStyle 用于设置描边的颜色,lineWidth 只用描边的线宽。

绘制的结果如下:

image.png

可以类比给 Div 元素设置 border 和 background。

Dom 和 Canvas 两种渲染方式的对比

我们不妨将 Cavans 和 Div 展现一个矩形的绘制过程进行对比。

首先,Div 是声明式的,它保留在 Dom 树下,随时可以修改属性,修改后渲染引擎对其进行重新绘制。

而 Canvas 绘制矩形则是命令式的,一旦它被画到画布上,Canvas 就不再管这是不是矩形了,Canvas 只是根据命令画出了一系列像素点,自身并不维护一个被绘制图形形成的树。

如果你要记录曾经画的图形,以及形成的层级,都要开发者自己去维护。

相比 Dom 自动地维护,隐形造成的非必要的回流重绘消耗性能的操作,Canvas 会更原始,把决定是否重绘还是局部冲毁堤岸的权利让渡给开发者,让开发者做性能优化有更大的空间。

但这也让开发者需要做更多的底层基础工作。

绘制圆形

Canvas 并没有提供直接绘制一个圆形的 API,而是提供一个绘制圆弧的 API。

ctx.fillStyle = '#519D36'; // 绿色
ctx.beginPath();
ctx.arc(100, 40, 20, 0, Math.PI * 2); // 0 为从右方为起点,
ctx.fill();
ctx.stroke();

绘制图形通常需要先通过各种 API 描述的子路径组合出一个路径,然后再进行 fill(填充) 和 stroke(描边)。arc 方法就是其中一种描述子路径的 API。

arc 接受的参数依次为:

圆心位置 (100, 40)半径(20);起始的弧度(0,对应圆最右侧的点)结束的弧度(Math.PI * 2,刚好一圈)是否为逆时针绘制的布尔值,是可选值。默认为 false,即顺时针。

arc 方法执行完后,Canvas 心里就记住了这个路径。然后调用 fill 方法将路径填充,以及 stroke 方法沿着路径绘制线条。

beginPath 是表示我们后面要绘制新的路径的意思,可以防止描边时和上一次的路径相连。就好比把画笔提起来,准备画下一个图形。

当然我们画圆之前没有画过其他路径,所以这里不执行 beginPath 也是可以的。

绘制的结果如下:

image.png

绘制三角形

圆弧会画了,我们再来看看线条怎么画。以画三角形为例:

ctx.moveTo(20, 20);
ctx.lineTo(60, 20);
ctx.lineTo(40, 40);
ctx.fill();
ctx.closePath();
ctx.stroke();

首先是 moveTo 到坐标 (20, 20)

moveTo 其实就是将画笔抬起,放到对应的位置。它可以做到 beginPath 的效果:摆脱和之前的路径的关系。

然后是 lineTo 从当前位置沿着直线到达下一个点。接着又来一个 lineTo,此时我们画出了三角形的两条边。

此时如果你 fill(填充)其实是可以画出一个三角形的,因为填充逻辑是会将路径用直线封闭然后在填充的,第三条边存不存在效果相同。

但对 stroke(描边)就不同了,就导致只画出两条边。

于是我们调用 closePath 方法,将当前点和刚刚起笔的点(moveTo 时的点)进行直线相连。其实你可以再调用用一次 moveTo(20, 20) 来替代这个方法,这两个方法是等效的。

绘制的效果为:

image.png

结尾

本文介绍了 Canvas 的一些基础知识,并演示了绘制矩形、圆形、三角形比较基础的操作。

晚点我会再写其他介绍其他基础绘制操作的文章。


相关文章
|
7月前
|
前端开发
Canvas简介与基本使用(下)
Canvas简介与基本使用
44 0
|
7月前
|
XML 移动开发 前端开发
Canvas简介与基本使用(上)
Canvas简介与基本使用
42 0
|
前端开发 API
canvas深入浅出(三)| 小册免费学
所有的内容都是手动绘制还是有点麻烦,好在canvas支持导入图片,createPattern(image, type),该方法接受两个参数。Image 可以是一个 Image 对象的引用,或者另一个 canvas 对象。Type 必须是下面的字符串值之一:repeat,repeat-x,repeat-y 和 no-repeat。
69 0
canvas深入浅出(三)| 小册免费学
|
存储 前端开发 API
canvas深入浅出(四)| 小册免费学
之前三节我们铺垫了canvas的相关知识,这一节我们来“落地”,实现一个五子棋的小游戏
65 0
|
前端开发 API
canvas深入浅出(二)| 小册免费学
上一节最后我们说了一个绘制曲线的API——arc(那个API并不是专门用来绘制圆形,只是使用曲线可以绘制圆形),他还有一个兄弟——arcTo(x1, y1, x2, y2, r),根据当前描点与给定的控制点1连接的直线,和控制点1与控制点2连接的直线,作为使用指定半径的圆的切线,画出两条切线之间的弧线路径
61 0
canvas深入浅出(二)| 小册免费学
|
XML 前端开发 JavaScript
canvas深入浅出(一)| 小册免费学
canvas是为了解决页面只能显示静态图片而出现的一种可以使用JavaScript绘制的HTML标签,它可以接受两个参数width和height(原来有三个,还有一个moz-opaque控制透明度,已经废弃了)
60 0
|
Web App开发 前端开发 JavaScript
canvas 快速入门
canvas 快速入门
canvas 快速入门
|
前端开发
Canvas入门(一)
Canvas入门(一)
219 0
|
前端开发 JavaScript
Canvas入门(三)
Canvas入门(三)
110 0
|
前端开发
Canvas入门(二)
Canvas入门(二)
139 0