HTML本身是标记语言,并不具备直接绘图的能力,但HTML5引入的Canvas元素让浏览器变成了一个真正的画板。Canvas提供了一块像素级的画布,配合JavaScript可以绘制任意图形,小到一个简单的矩形,大到完整的数据图表、游戏画面和粒子特效。这篇教程会从零开始讲解Canvas的核心概念和常用绘图API,并通过一个鼠标画板的小实战把知识点落地。

Canvas是什么:先搞懂画布和绘图上下文
Canvas翻译过来就是画布,它在页面中就是一个普通的HTML元素,用法和<div>、<img>没有本质区别。但它特殊的地方在于,元素内部封装了一块绘图区域,你可以通过JavaScript获取这块区域的控制权,在上面自由绘制。
要开始在Canvas上作画,第一步是获取绘图上下文(context)。上下文可以理解为画笔工具箱,Canvas目前主要使用的是2D上下文,通过getContext('2d')获得。所有绘制动作都是通过这个上下文对象的方法完成的,比如fillRect画矩形、arc画圆弧、fillText写文字。
<canvas id="myCanvas" width="600" height="400"></canvas>
<script>
// 获取画布元素
const canvas = document.getElementById('myCanvas');
// 获取2D绘图上下文,后续所有绘制都基于它
const ctx = canvas.getContext('2d');
</script>这里有一个非常容易踩的坑需要特别说明:画布的宽高必须通过width和height属性设置,而不是用CSS设置。如果用CSS去控制宽高,实际像素区域还是默认的300乘150,画面会被拉伸变形,画出来的图形全是模糊的。正确做法是直接写在标签属性里,或者用JavaScript给canvas.width赋值。
另外要理解Canvas的坐标系:原点在画布左上角,x轴向右增大,y轴向下增大。这和数学课上的坐标系方向不同,y轴是反的,刚开始用的时候很容易画反位置,务必记牢。
基础图形绘制:矩形、路径与圆弧
矩形是Canvas中最简单的图形,上下文直接提供了三个方法:fillRect绘制填充矩形,strokeRect绘制描边矩形,clearRect清除指定区域。三个方法都接收四个参数,分别是起点的x、y坐标以及宽和高。
<script>
const ctx = document.getElementById('myCanvas').getContext('2d');
// 填充矩形:参数为 x, y, 宽, 高
ctx.fillRect(20, 20, 120, 80);
// 描边矩形
ctx.strokeRect(160, 20, 120, 80);
// 清除一块区域,露出背景
ctx.clearRect(40, 40, 60, 30);
</script>更复杂的图形要靠路径(path)来完成。路径绘制的套路是固定的四步:先用beginPath开始一条新路径,再用moveTo和lineTo规划线条走向,然后用closePath闭合路径(需要时),最后调用fill填充或stroke描边。只有最后这一步执行了,图形才会真正出现在画布上,前面都只是在规划路线。
画圆和圆弧用arc方法,它接收六个参数:圆心x、圆心y、半径、起始角度、结束角度、是否逆时针。角度单位是弧度,一个完整的圆是从0到Math.PI * 2。很多初学者画圆时忘了调用beginPath,结果新画的圆会和之前的路径连在一起,出现奇怪的连线,这就是原因所在。
<script>
const ctx = document.getElementById('myCanvas').getContext('2d');
// 绘制三角形
ctx.beginPath();
ctx.moveTo(50, 200);
ctx.lineTo(150, 200);
ctx.lineTo(100, 100);
ctx.closePath(); // 闭合后自动连接首尾
ctx.fillStyle = '#4a90d9';
ctx.fill();
// 绘制圆形
ctx.beginPath();
ctx.arc(250, 150, 60, 0, Math.PI * 2);
ctx.strokeStyle = '#e74c3c';
ctx.lineWidth = 4;
ctx.stroke();
</script>颜色、渐变与文字让画面更丰富
设置颜色主要靠fillStyle和strokeStyle两个属性,它们不仅支持普通的十六进制颜色,还支持rgba形式,也就是带透明度的颜色。比如rgba(255, 0, 0, 0.5)表示半透明红色,做叠加效果时非常好用。线宽通过lineWidth控制,数值越大线条越粗。
渐变色是提升画面质感的关键。Canvas支持线性渐变和径向渐变两种,以线性渐变为例,先调用createLinearGradient创建渐变对象,指定起点和终点坐标,再用addColorStop添加颜色节点,最后把这个对象赋给fillStyle。整个过程可以理解为先调制颜料,再拿起画笔。
<script>
const ctx = document.getElementById('myCanvas').getContext('2d');
// 创建线性渐变,从左到右
const gradient = ctx.createLinearGradient(0, 0, 400, 0);
gradient.addColorStop(0, '#ff6b6b'); // 起点颜色
gradient.addColorStop(1, '#4ecdc4'); // 终点颜色
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 400, 150);
</script>绘制文字使用fillText和strokeText,绘制前先通过font属性设置字号和字体,语法和CSS的font简写一致。还可以用textAlign控制对齐方式。文字在数据可视化场景里几乎必不可少,坐标轴标签、数值提示都离不开它。
实战:做一个可以随手涂鸦的鼠标画板
掌握了上面的基础之后,我们把这些知识点组合起来,做一个经典的鼠标画板应用。思路是监听鼠标的按下、移动、抬起三个事件:按下时记录起点并开始路径,移动时不断画线到当前位置,抬起时结束绘制。
这里有一个关键技巧:每次鼠标移动都会触发绘制,如果不做处理,之前画的线会保留在画布上,松手后再画新线时会和旧线连起来。解决办法是在每次开始新笔画时调用beginPath,并且只在按下状态下才执行lineTo和stroke。
<canvas id="paint" width="600" height="400" style="border:1px solid #ccc;"></canvas>
<script>
const canvas = document.getElementById('paint');
const ctx = canvas.getContext('2d');
let drawing = false;
// 鼠标按下:开始画画
canvas.addEventListener('mousedown', function(e) {
drawing = true;
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
});
// 鼠标移动:持续画线
canvas.addEventListener('mousemove', function(e) {
if (!drawing) return;
ctx.lineTo(e.offsetX, e.offsetY);
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.lineCap = 'round'; // 线条端点圆滑
ctx.stroke();
});
// 鼠标抬起:结束本笔
canvas.addEventListener('mouseup', function() {
drawing = false;
});
</script>代码中用到的offsetX和offsetY是鼠标相对于画布左上角的坐标,正好可以直接传给绘图方法,省去了繁琐的位置换算。属性lineCap设为round可以让笔画转折处更圆润,写字画画的效果会好很多。
在此基础上还可以继续扩展,比如加一个颜色选择器动态修改strokeStyle,加一个滑块控制lineWidth实现笔刷粗细切换,或者加一个清除按钮调用clearRect清空整个画布。这些功能的核心逻辑都在本篇讲过的基础API之内,动手试试就能做出来。
最后提一点学习方向:Canvas还支持绘制图片、像素操作、图形变换以及配合requestAnimationFrame制作动画,这些属于进阶内容。把本篇的基础打牢,再去看图表库或者小游戏开发时,你会发现它们底层的绘制原理和这里完全一致。学习Canvas最好的方式就是多动手,打开编辑器把上面的代码跑一遍,改改参数看看效果,比看十篇教程都有用。
Canvas绘图HTML5画布JavaScript图形绘制修改时间:2026-09-14 14:03:15