Canvas 和 WebGL 入门教程
在前端开发中,绘图已经成为一种重要的技能,而 Canvas 和 WebGL 是实现图形绘制的两个重要工具。本文将带你入门 Canvas 和 WebGL,帮助你理解如何使用它们在浏览器中绘制图形。
一、Canvas 入门
Canvas 是 HTML5 提供的一个绘图容器,可以用于图形、动画和游戏开发。通过 Canvas API,你可以直接使用 JavaScript 绘制图像、矩形、圆形等图形。
1. 基本结构
首先,在 HTML 文件中添加一个 canvas 标签,并设置它的宽度和高度。
<canvas id="myCanvas" width="500" height="500"></canvas>
2. 获取绘图上下文
要在 canvas 上绘图,我们需要获取绘图上下文。一般使用 2D 上下文 (getContext('2d')),然后通过这个上下文调用各种绘图方法。
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
3. 绘制基本图形
-
绘制矩形
ctx.fillStyle = 'blue'; ctx.fillRect(50, 50, 100, 100); -
绘制线条
ctx.beginPath(); ctx.moveTo(200, 200); ctx.lineTo(300, 300); ctx.stroke(); -
绘制圆形
ctx.beginPath(); ctx.arc(150, 150, 50, 0, Math.PI * 2); ctx.fillStyle = 'red'; ctx.fill();
二、WebGL 入门
WebGL 是基于 OpenGL ES 2.0 的一个 JavaScript API,支持硬件加速的 3D 绘图,适合开发游戏、数据可视化和 3D 应用。相比 Canvas,WebGL 能渲染更为复杂和高性能的图形。
1. 基本结构
和 Canvas 一样,首先需要在 HTML 中添加 canvas 标签:
<canvas id="webglCanvas" width="500" height="500"></canvas>
2. 获取 WebGL 上下文
使用 getContext('webgl') 方法获取 WebGL 上下文:
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.log("WebGL not supported, falling back on experimental-webgl");
gl = canvas.getContext("experimental-webgl");
}
3. 创建和编译着色器
在 WebGL 中,绘图通过顶点着色器(vertex shader)和片段着色器(fragment shader)进行。以下代码展示了如何创建和编译一个简单的着色器:
const vertexShaderSource = `
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const fragmentShaderSource = `
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}
`;
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
return shader;
}
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
attribute vec2 position;
-
含义:
position是一个二维向量(vec2),表示顶点的坐标。 -
来源:
attribute是用于从 CPU 传递给 GPU 顶点着色器的数据。它通常由用户通过 WebGL API 设置,比如通过缓冲区传递顶点数据。 -
数据类型:二维向量(
vec2),通常表示顶点在 2D 平面中的位置,例如(x, y)。
void main()
- 含义:这是顶点着色器的主函数,GPU 会为每个顶点调用一次。
gl_Position = vec4(position, 0.0, 1.0);
-
作用:定义顶点在裁剪空间的坐标。
-
gl_Position是内建变量,表示顶点在裁剪空间中的坐标,是一个四维向量(vec4)。 -
vec4(position, 0.0, 1.0)将二维的position转换为四维向量:x, y:来自传入的position。z = 0.0:假设顶点位于 z=0 平面。w = 1.0:用于齐次坐标的规范化。
-
-
结果:将二维顶点坐标
position映射到 OpenGL 的裁剪空间,其中 z 坐标为0.0。
precision mediump float;
-
含义:定义浮点数的精度。
precision:用于指定变量(如float类型)的精度。mediump:表示中等精度(medium precision)。
-
用途:片段着色器中的浮点数计算可能影响最终渲染结果,因此需要明确指定精度。常用的精度有:
lowp:低精度,适合节能或性能优先的简单计算。mediump:中等精度,适合大部分常规用途。highp:高精度,通常用于需要高细节的效果(如 3D 渲染的深度计算等)。
在片段着色器中,中等精度通常够用,尤其是对于颜色计算。
4. 创建着色器程序并绘制三角形
将着色器链接到一个着色器程序中,然后在画布上绘制一个简单的三角形。
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0.5,
-0.5, -0.5,
0.5, -0.5
]), gl.STATIC_DRAW);
const positionLocation = gl.getAttribLocation(program, "position");
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
const colorLocation = gl.getUniformLocation(program, "color");
gl.uniform4f(colorLocation, 1.0, 0.0, 0.0, 1.0); // 红色
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.drawArrays
-
功能:WebGL 的绘制函数,基于顶点缓冲区中的数据绘制图形。
-
签名:
gl.drawArrays(mode, first, count);mode:指定绘制的图元类型,例如点、线、三角形。first:从顶点缓冲区中的哪个索引开始读取数据。count:要绘制的顶点数量。
参数说明
gl.drawArrays(gl.TRIANGLES, 0, 3);
-
gl.TRIANGLES-
含义:绘制三角形。
-
工作原理:
- 每 3 个连续的顶点定义一个三角形。
- 如果顶点数量不是 3 的倍数,多余的顶点将被忽略。
-
示例:
-
如果缓冲区中有顶点数据
[v0, v1, v2, v3, v4, v5]:- 第一个三角形:
[v0, v1, v2] - 第二个三角形:
[v3, v4, v5]
- 第一个三角形:
-
-
-
0- 含义:从顶点缓冲区的第一个顶点开始读取。
- 作用:指定从第
0个顶点开始绘制。
-
3-
含义:绘制 3 个顶点。
-
作用:
- GPU 将读取缓冲区中的前 3 个顶点。
- 因为
mode是gl.TRIANGLES,这 3 个顶点将组成一个三角形。
-
三、Canvas 和 WebGL 的区别与选择
| 特性 | Canvas | WebGL |
|---|---|---|
| 绘制维度 | 2D | 2D 和 3D |
| 性能 | 适合简单图形,性能较低 | 硬件加速,高性能 |
| 使用难度 | 简单,适合初学者 | 较复杂,适合需要高性能的项目 |
| 适用场景 | 简单图表、动画 | 游戏、3D 数据可视化、复杂动画 |
选择 Canvas 还是 WebGL 主要取决于项目需求:如果仅需绘制简单的图表或动画,可以选择 Canvas;如果需要绘制复杂的 3D 场景或高性能动画,则 WebGL 是更好的选择。
四、进阶学习
学习 Canvas 和 WebGL 的基础后,你可以逐步深入探索一些高级技术和工具:
- Canvas 高级技术:掌握
CanvasAPI 的高级特性,如图像处理、动画优化、路径和文本处理等。 - WebGL 框架:可以学习
Three.js等 WebGL 框架,简化 3D 图形渲染工作,并进一步探索GLSL着色器编程。
希望通过本教程,你能更好地理解 Canvas 和 WebGL,并灵活运用它们在网页中绘制图形。