Canvas初学笔记

以前做的前端的动画都是基于CSS或者JS事件的,虽然一直知道HTML5中新增了画布Canvas用来在网页上实时生成图像,但是一直没机会用。近期毕设中期检查刚过,有一些空余时间,就学了点Canvas的基础用法。

Canvas基本用法

首先在body中添加一个canvas标签

1
2
3
<body>
<canvas id="canvas" width="1024" height="800" style="border: 1px solid #000; margin: 20px auto;">当前浏览器不支持Canvas</canvas>
</body>

上面的代码就是在网页中添加了一块宽1024高800并且左右居中的画布。
canvas标签中的文字用来验证浏览器是否支持Canvas。如果不支持Canvas,则显示文字;否则显示canvas画布不显示文字。

之后我们要在js代码中对画布进行编辑。

1
2
3
4
5
6
<script type="text/javascript">
window.onload = function () {
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
}
</script>

这样我们在js中获取了可以编辑的canvas的上下文。
我们也可以在js代码中设置canvas的宽高。具体方法是添加如下两行代码:

1
2
canvas.width = 1024;
canvas.height = 800;

之后我们开始在canvas中绘制一条直线。

1
2
3
4
5
context.moveTo(100,100);
context.lineTo(700,700);
context.lineWidth = 5;
context.strokeStyle = 'red';
context.stroke();

canvas从画布的起点开始,向右为x轴正方向,向下为y轴正方向。
我们先设置状态,之后再绘制图像。

Canvas绘制封闭图形

canvas绘制封闭图形使用如下代码:

1
2
3
4
5
6
7
8
context.moveTo(100,100);
context.lineTo(700,700);
context.lineTo(100,700);
context.lineTo(100,100);

context.lineWidth = 5;
context.strokeStyle = 'red';
context.stroke();

如果我们要填充绘制图形的空白部分,那我们就需要用到fill();
代码如下:

1
2
3
4
5
6
7
context.moveTo(100,100);
context.lineTo(700,700);
context.lineTo(100,700);
context.lineTo(100,100);

context.fillStyle = 'rgb(255, 0, 0)';
context.fill();

这样就给图形的空白部分填充了红色。
注意:用了context.fill()后无论路径是否封闭,绘制的图像的路径都将封闭。

Canvas绘制弧线和圆

canvas中绘制弧线和圆时使用如下函数:

1
context.arc(100, 100, 50, 0, 2*Math.PI, false);

其中前三个参数代表圆弧或者圆的圆心坐标和半径,第四和第五个参数代表圆弧的起始角度和结束角度,第六个参数默认false,代表顺时针方向画弧线。

beginPath()和closePath()的应用

因为canvas画图是基于状态的,所以当我们绘制时会将所有的状态都绘制一遍。比如以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
context.moveTo(100,100);
context.lineTo(700,700);
context.lineTo(100,700);
context.lineTo(100,100);

context.lineWidth = 5;
context.strokeStyle = 'red';
context.stroke();

context.moveTo(200,200);
context.lineTo(300,300);

context.lineWidth = 10;
context.strokeStyle = 'black';
context.stroke();

最终的结果是得到的三角形和直线都是黑色的线宽为10的图形,这显然不是我们想要的。
这时我们就要用到beginPath()和closePath()将每个图形包起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
context.beginPath();
context.moveTo(100,100);
context.lineTo(700,700);
context.lineTo(100,700);
context.lineTo(100,100);

context.lineWidth = 5;
context.strokeStyle = 'red';
context.stroke();
context.closePath();

context.beginPath();
context.moveTo(200,200);
context.lineTo(300,300);

context.lineWidth = 10;
context.strokeStyle = 'black';
context.stroke();
context.closePath();

这样上面的状态和下面的状态就分开了,也不会被下面的状态所覆盖。

照着教程做了一些canvas的demo,包括一个canvas实现的倒计时动画效果,放在github上。
canvas demo

睡觉啦,晚安啦!