创建文件:index.html
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>第一个Three.js程序:旋转立方体</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
color: #fff;
}
#info-panel {
position: absolute;
top: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
padding: 20px;
border-radius: 12px;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
max-width: 400px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
z-index: 100;
}
#info-panel h1 {
margin-bottom: 10px;
color: #4facfe;
font-size: 24px;
}
#info-panel p {
margin-bottom: 8px;
line-height: 1.5;
color: #aaa;
}
#info-panel code {
background: rgba(79, 172, 254, 0.1);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Monaco', 'Consolas', monospace;
}
#controls {
position: absolute;
bottom: 20px;
left: 20px;
display: flex;
gap: 10px;
z-index: 100;
}
.control-btn {
background: rgba(79, 172, 254, 0.2);
border: 1px solid rgba(79, 172, 254, 0.3);
color: white;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
}
.control-btn:hover {
background: rgba(79, 172, 254, 0.4);
transform: translateY(-2px);
}
.control-btn.active {
background: rgba(79, 172, 254, 0.6);
box-shadow: 0 0 20px rgba(79, 172, 254, 0.4);
}
#stats {
position: absolute;
top: 20px;
right: 20px;
z-index: 100;
}
#fullscreen-btn {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(255, 255, 255, 0.1);
border: none;
color: white;
width: 40px;
height: 40px;
border-radius: 50%;
cursor: pointer;
font-size: 18px;
z-index: 100;
}
#fps-counter {
position: absolute;
top: 60px;
right: 20px;
background: rgba(0, 0, 0, 0.5);
padding: 5px 10px;
border-radius: 4px;
font-family: 'Monaco', 'Consolas', monospace;
font-size: 12px;
z-index: 100;
}
</style>
</head>
<body>
<!-- 信息面板 -->
<div id="info-panel">
<h1>🎯 第一个Three.js程序</h1>
<p><strong>✨ 旋转立方体 ✨</strong></p>
<p>这是Three.js的入门程序</p>
</div>
<!-- Three.js库引入 -->
<script src="https://cdn.jsdelivr.net/npm/three@0.135.0/build/three.min.js"></script>
<!-- 性能监控库 -->
<script src="https://cdn.jsdelivr.net/npm/three@0.135.0/examples/js/libs/stats.min.js"></script>
<!-- 控制器 -->
<script src="https://cdn.jsdelivr.net/npm/three@0.135.0/examples/js/controls/OrbitControls.js"></script>
<!-- 主程序 -->
<script>
// 主程序开始...
</script>
</body>
</html>
创建项目结构:
text
my-first-threejs/
├── index.html
├── css/
│ └── style.css
├── js/
│ ├── main.js
│ └── utils.js
├── textures/ # 纹理图片
│ ├── wood.jpg
│ └── metal.jpg
├── models/ # 3D模型(可选)
└── README.md
bash
# 创建项目
npm create vite@latest my-threejs-app -- --template vanilla
# 进入项目目录
cd my-threejs-app
# 安装Three.js
npm install three
# 启动开发服务器
npm run dev
javascript
// 在主script标签中编写以下代码:
// ============ 1. 初始化基础组件 ============
// 创建场景(容器)
const scene = new THREE.Scene();
// 创建相机(视角)
const camera = new THREE.PerspectiveCamera(
75, // 视野角度(FOV)
window.innerWidth / window.innerHeight, // 宽高比
0.1, // 近裁剪面
1000 // 远裁剪面
);
// 创建渲染器(画布)
const renderer = new THREE.WebGLRenderer({
antialias: true, // 开启抗锯齿
alpha: true // 开启透明度
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// ============ 2. 创建立方体 ============
// 创建立方体几何体(宽, 高, 深)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 创建立方体材质
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00, // 绿色
wireframe: false // 非线框模式
});
// 创建网格(几何体 + 材质)
const cube = new THREE.Mesh(geometry, material);
// 将立方体添加到场景中
scene.add(cube);
// 设置相机位置(否则什么都看不到)
camera.position.z = 5;
// ============ 3. 创建动画循环 ============
function animate() {
// 请求下一帧动画
requestAnimationFrame(animate);
// 旋转立方体
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
// 渲染场景
renderer.render(scene, camera);
}
// 启动动画
animate();
// ============ 4. 响应窗口大小变化 ============
window.addEventListener('resize', () => {
// 更新相机宽高比
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
// 更新渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
});
javascript
// 场景 (Scene) - 容器,存放所有3D对象
const scene = new THREE.Scene();
// 相机 (Camera) - 观察者的视角
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// 渲染器 (Renderer) - 将3D场景渲染到2D画布上
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
javascript
// 几何体 (Geometry) - 定义物体的形状
// BoxGeometry(宽度, 高度, 深度, 宽度分段数, 高度分段数, 深度分段数)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 材质 (Material) - 定义物体的外观
// MeshBasicMaterial 是最基础的材质,不受光照影响
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// 网格 (Mesh) - 几何体和材质的结合体
const cube = new THREE.Mesh(geometry, material);
// 添加到场景
scene.add(cube);
javascript
// 默认相机在原点(0,0,0),立方体也在原点(0,0,0)
// 所以我们需要将相机向后移动才能看到立方体
camera.position.z = 5;
javascript
// 动画循环函数
function animate() {
// 1. 请求下一帧动画(浏览器优化的动画API)
requestAnimationFrame(animate);
// 2. 更新立方体的旋转
cube.rotation.x += 0.01; // 绕X轴旋转
cube.rotation.y += 0.01; // 绕Y轴旋转
// 3. 渲染场景
renderer.render(scene, camera);
}
// 启动动画
animate();
javascript
// 监听窗口大小变化
window.addEventListener('resize', () => {
// 更新相机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix(); // 必须调用此方法更新
// 更新渲染器大小
renderer.setSize(window.innerWidth, window.innerHeight);
});
text
first-threejs-project/
├── index.html # 主页面
├── css/
│ └── style.css # 样式文件
├── js/
│ ├── main.js # 主逻辑
│ ├── cube.js # 立方体类
│ ├── controls.js # 控制逻辑
│ └── utils.js # 工具函数
├── textures/ # 纹理图片
│ ├── wood.jpg
│ ├── metal.jpg
│ └── stone.jpg
├── fonts/ # 字体文件(可选)
├── models/ # 3D模型(可选)
└── README.md # 项目说明
通过这个"旋转立方体"项目,你已经学会了:
✅ Three.js的基础架构
✅ 创建3D对象和材质
✅ 设置相机和渲染器
✅ 实现动画循环
这是Three.js学习的起点,掌握了这些基础概念后,你就可以继续学习更高级的功能了。记住,实践是最好的学习方法,尝试修改代码参数,看看会发生什么变化!
学习资源推荐:
祝你学习顺利! 🚀