返回

canvas坐标变换的背后

前端

引言

canvas作为Web上的强大绘图引擎,提供了丰富的图形操作功能,其中坐标变换尤为重要。通过坐标变换,我们可以轻松地平移、旋转、缩放和扭曲画布上的元素,从而实现各种复杂的效果。本文将深入探讨canvas中的坐标变换,从2D到3D,分析canvas在变形时所执行的各种操作,并提供实际示例,帮助您掌握canvas坐标变换的精髓。

2D坐标变换

在2D canvas中,坐标变换主要通过canvas.translate(), canvas.rotate(), canvas.scale()canvas.transform()等方法实现。这些方法接受数字参数,分别用于平移、旋转、缩放和应用自定义的仿射变换。

例如,以下代码将画布平移100像素:

canvas.translate(100, 0);

3D坐标变换

除了2D变换,canvas还支持3D坐标变换,通过canvas.getContext('webgl')获得的WebGL上下文。WebGL是一个功能强大的3D图形API,允许我们在画布上绘制3D场景。

在WebGL中,坐标变换通过模型视图矩阵、投影矩阵和视口矩阵实现。模型视图矩阵控制对象的坐标,投影矩阵定义相机的视角,视口矩阵将3D坐标映射到2D画布。

实际示例

2D变形:

// 平移矩形
canvas.translate(50, 50);
canvas.fillRect(0, 0, 100, 100);

// 旋转矩形
canvas.rotate(Math.PI / 4);
canvas.fillRect(0, 0, 100, 100);

// 缩放矩形
canvas.scale(2, 2);
canvas.fillRect(0, 0, 100, 100);

3D变形:

// WebGL场景
const gl = canvas.getContext('webgl');

// 设置模型视图矩阵
const mvMatrix = mat4.create();
mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -10.0]);
mat4.rotate(mvMatrix, mvMatrix, degToRad(45), [0, 1, 0]);

// 设置投影矩阵
const pMatrix = mat4.create();
mat4.perspective(pMatrix, degToRad(45), canvas.width / canvas.height, 0.1, 100.0);

// 设置视口矩阵
gl.viewport(0, 0, canvas.width, canvas.height);

// 绑定顶点缓冲区和索引缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);

// 设置着色器程序
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);

// 设置顶点属性
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexPositionAttribute);

// 清除颜色缓冲区
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// 设置模型视图矩阵和投影矩阵
gl.uniformMatrix4fv(mvMatrixLocation, false, mvMatrix);
gl.uniformMatrix4fv(pMatrixLocation, false, pMatrix);

// 绘制物体
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

结论

canvas中的坐标变换提供了强大的工具,用于创建各种视觉效果。通过了解2D和3D坐标变换背后的机制,我们可以充分利用canvas来实现复杂的图形操作,提升Web应用的视觉表现力和交互性。