vue实现3d宇宙
Vue实现3D宇宙效果
使用Three.js库
Three.js是一个强大的JavaScript 3D库,可以轻松集成到Vue项目中。安装Three.js依赖:
npm install three
创建一个Vue组件,初始化Three.js场景:
<template>
<div ref="container" class="three-container"></div>
</template>
<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
export default {
mounted() {
this.initThree();
},
methods: {
initThree() {
const container = this.$refs.container;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild(renderer.domElement);
// 添加星空背景
const starGeometry = new THREE.BufferGeometry();
const starMaterial = new THREE.PointsMaterial({ color: 0xffffff });
const starVertices = [];
for (let i = 0; i < 10000; i++) {
const x = (Math.random() - 0.5) * 2000;
const y = (Math.random() - 0.5) * 2000;
const z = (Math.random() - 0.5) * 2000;
starVertices.push(x, y, z);
}
starGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starVertices, 3));
const stars = new THREE.Points(starGeometry, starMaterial);
scene.add(stars);
// 添加行星
const planetGeometry = new THREE.SphereGeometry(5, 32, 32);
const planetMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const planet = new THREE.Mesh(planetGeometry, planetMaterial);
scene.add(planet);
camera.position.z = 15;
new OrbitControls(camera, renderer.domElement);
const animate = () => {
requestAnimationFrame(animate);
planet.rotation.x += 0.01;
planet.rotation.y += 0.01;
renderer.render(scene, camera);
};
animate();
}
}
};
</script>
<style>
.three-container {
width: 100%;
height: 100vh;
}
</style>
使用A-Frame框架
A-Frame是专门为WebVR设计的框架,但也可以用于普通3D场景。安装A-Frame Vue插件:
npm install aframe vue-aframe
在Vue项目中使用:
<template>
<a-scene>
<a-sky color="#000000"></a-sky>
<a-entity
v-for="(star, index) in stars"
:key="index"
:position="star.position"
geometry="primitive: sphere; radius: 0.05"
material="color: white"
></a-entity>
<a-sphere
position="0 0 -5"
radius="1"
color="blue"
animation="property: rotation; to: 0 360 0; loop: true; dur: 10000"
></a-sphere>
</a-scene>
</template>
<script>
export default {
data() {
return {
stars: []
};
},
created() {
for (let i = 0; i < 500; i++) {
this.stars.push({
position: {
x: (Math.random() - 0.5) * 10,
y: (Math.random() - 0.5) * 10,
z: (Math.random() - 0.5) * 10 - 5
}
});
}
}
};
</script>
性能优化技巧
对于大规模3D场景,考虑使用实例化渲染提高性能。Three.js中可以使用InstancedMesh:
const geometry = new THREE.SphereGeometry(0.05, 8, 8);
const material = new THREE.MeshBasicMaterial({ color: 0xffffff });
const mesh = new THREE.InstancedMesh(geometry, material, 10000);
const matrix = new THREE.Matrix4();
for (let i = 0; i < 10000; i++) {
matrix.setPosition(
(Math.random() - 0.5) * 2000,
(Math.random() - 0.5) * 2000,
(Math.random() - 0.5) * 2000
);
mesh.setMatrixAt(i, matrix);
}
scene.add(mesh);
添加交互功能
实现鼠标点击选择行星的功能:
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function onMouseClick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
console.log('选中了物体', intersects[0].object);
}
}
window.addEventListener('click', onMouseClick, false);
响应式设计
确保3D场景适应不同屏幕尺寸:
function onWindowResize() {
camera.aspect = container.clientWidth / container.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(container.clientWidth, container.clientHeight);
}
window.addEventListener('resize', onWindowResize);






