本教程基于提供的代码示例,将带你了解如何在 Vue2 中集成 Three.js 并创建交互式 3D 场景。假设你已具备基本的 Three.js 知识,我们将重点讲解两者结合的关键点。
首先需要引入必要的库文件:
<!-- 引入Vue 2 -->
<script src='https://unpkg.com/vue@2.7.14/dist/vue.min.js'></script>
<!-- 引入Three.js核心库 -->
<script src="https://unpkg.com/three@0.128.0/build/three.min.js"></script>
<!-- 引入Three.js轨道控制器 -->
<script src="https://unpkg.com/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
<div id="app">
<div class="scene-container">
<!-- 3D场景容器 -->
<canvas id="three-container"></canvas>
<!-- 交互按钮 -->
<button class="add-button" @click="addRandomObject">+ 添加随机物体</button>
</div>
</div>
关键是设置容器尺寸和定位,确保 Three.js 渲染的画布能正确显示:
#three-container {
width: 100%;
height: 100%;
position: absolute;
}
.add-button {
position: absolute;
/* 其他样式... */
z-index: 10; /* 确保按钮在3D场景上方 */
}
在 Vue 实例的data中存储 Three.js 核心对象:
data: {
// Three.js相关变量
scene: null, // 场景
camera: null, // 相机
renderer: null, // 渲染器
controls: null, // 控制器
}
在 Vue 生命周期钩子中处理 Three.js 初始化和资源清理:
mounted() {
// 组件挂载时初始化场景
this.initThreeScene();
// 监听窗口大小变化
window.addEventListener('resize', this.onWindowResize);
},
beforeDestroy() {
// 组件销毁前清理资源
window.removeEventListener('resize', this.onWindowResize);
if (this.controls) this.controls.dispose();
if (this.renderer) this.renderer.dispose();
}
initThreeScene方法是整个 3D 场景的入口,包含以下关键步骤:
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0x0a0a1a); // 设置背景色
this.camera = new THREE.PerspectiveCamera(
75, // 视野角度
container.clientWidth / container.clientHeight, // 宽高比
0.1, // 近裁剪面
1000 // 远裁剪面
);
this.camera.position.set(5, 5, 10); // 设置相机位置
this.renderer = new THREE.WebGLRenderer({
canvas: container, // 绑定到指定canvas元素
antialias: true // 启用抗锯齿
});
this.renderer.setSize(container.clientWidth, container.clientHeight);
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.enableDamping = true; // 启用阻尼效果
this.controls.dampingFactor = 0.05;
this.createInitialObjects(); // 创建初始物体
this.createLights(); // 创建光源
this.animate(); // 启动动画循环
使用Mesh类创建物体,需要几何体(Geometry)和材质(Material):
// 创建立方体示例
const cubeGeometry = new THREE.BoxGeometry(2, 2, 2);
const cubeMaterial = new THREE.MeshPhongMaterial({
color: 0x4361ee
});
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
cube.position.set(-3, 1, 0);
this.scene.add(cube);
合适的光照是显示 3D 物体的关键:
// 环境光 - 均匀照亮所有物体
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
this.scene.add(ambientLight);
// 平行光 - 模拟太阳光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.0);
directionalLight.position.set(5, 10, 7);
this.scene.add(directionalLight);
Three.js 动画通过requestAnimationFrame实现:
animate() {
requestAnimationFrame(this.animate); // 递归调用形成循环
this.controls.update(); // 更新控制器状态
this.renderer.render(this.scene, this.camera); // 渲染场景和相机
}
通过 Vue 的事件绑定实现交互:
<!-- 模板中的按钮 -->
<button class="add-button" @click="addRandomObject">+ 添加随机物体</button>
// 方法实现
addRandomObject() {
// 添加随机物体的逻辑
}
确保场景在窗口大小改变时正确显示:
onWindowResize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
本节课展示了 Vue2 与 Three.js 结合的基本模式:
这种整合方式既保留了 Vue 的响应式和组件化特性,又能充分利用 Three.js 的 3D 渲染能力,适合开发交互式 3D 应用。
本教程展示了如何在 Vue2 中集成 Three.js 并创建基础的 3D 场景。通过结合 Vue 的响应式特性和 Three.js 的强大 3D 渲染能力,可以构建出丰富的交互式 3D 应用。