在 Web 前端绘图中,我们通常使用 Canvas 2D API 来绘制图形。Canvas 是二维的,无法直接进行三维建模和旋转。但如果我们希望一个简单的三角形能像 3D 物体一样「绕 X 轴翻转」或「绕 Y 轴旋转」,可以通过数学变换在 2D 平面里模拟这种效果。
本文将介绍实现思路,并给出 JavaScript 示例代码。
一、二维平面旋转 vs 三维旋转
在二维平面中,常见的旋转公式是 绕 Z 轴旋转:
x=(x−cx)cosθ−(y−cy)sinθ+cx
y =(x−cx)sinθ+(y−cy)cosθ+cy
这只是平面内的转动。
但在三维空间中,还存在 绕 X 轴 和 绕 Y 轴 的旋转:
- 绕 X 轴:y 与 z 发生变化,看起来图形会「上下翻转」。
- 绕 Y 轴:x 与 z 发生变化,看起来图形会「左右摇摆」。
由于 Canvas 是 2D 的,我们不能真正使用 z 坐标。但我们可以通过对 x 或 y 做 余弦缩放 来模拟这种效果。
二、核心数学思路
-
绕 X 轴旋转(上下翻转):
-
在三维中,y 会随角度压缩或伸展。
-
在二维里,我们可以这样近似:
y′=(y−cy)cosθ+cy
-
-
绕 Y 轴旋转(左右摇摆):
-
在三维中,x 会随角度压缩或伸展。
-
在二维里,我们可以这样近似:
x′=(x−cx)cosθ+cx
-
其中 (cx,cy) 是旋转中心点。
三、Canvas 实现代码
ini
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const w = canvas.width;
const h = canvas.height;
// 定义三角形
let triangle = [
{x: 200, y: 200},
{x: 300, y: 200},
{x: 250, y: 100}
];
// 旋转中心(画布中心)
const cx = w / 2;
const cy = h / 2;
// 绕 X 轴旋转(模拟:改变 y)
function rotateX2D(p, angle) {
return {
x: p.x,
y: (p.y - cy) * Math.cos(angle) + cy
};
}
// 绕 Y 轴旋转(模拟:改变 x)
function rotateY2D(p, angle) {
return {
x: (p.x - cx) * Math.cos(angle) + cx,
y: p.y
};
}
// 绘制三角形
function drawTriangle(points) {
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
ctx.lineTo(points[1].x, points[1].y);
ctx.lineTo(points[2].x, points[2].y);
ctx.closePath();
ctx.fillStyle = "rgba(0,150,255,0.6)";
ctx.fill();
ctx.stroke();
}
let angleX = 0;
let angleY = 0;
function animate() {
ctx.clearRect(0, 0, w, h);
// 先绕 X 再绕 Y
let rotated = triangle.map(p => rotateX2D(p, angleX));
rotated = rotated.map(p => rotateY2D(p, angleY));
drawTriangle(rotated);
angleX += 0.02; // 控制绕 X 旋转
angleY += 0.015; // 控制绕 Y 旋转
requestAnimationFrame(animate);
}
animate();
</script>
四、效果与扩展
运行后可以看到:
- 绕 X 轴:三角形上下压缩,像是「翻书」。
- 绕 Y 轴:三角形左右压缩,像是「开门」。
- 两个叠加,就能产生类似 3D 物体的旋转感。
进一步扩展:
- 可以改旋转中心为三角形重心,实现「绕自身旋转」。
- 可以结合鼠标拖拽或键盘按键,动态控制旋转角度。
- 可以给多个点应用同样的变换,实现更复杂的多边形或图形旋转。
五、总结
虽然 Canvas 2D 本身没有三维功能,但通过 余弦缩放 的方式,我们能在二维平面里模拟绕 X/Y 轴旋转的效果。这是一种简化的「伪 3D」方法,足以满足一些轻量级的动画和视觉效果需求。
如果需要更真实的 3D 效果,可以考虑使用 WebGL 或 Three.js 等三维引擎;但在学习和小型项目中,使用纯数学和 Canvas 就能实现有趣的旋转体验。