跳到主要内容

太阳系

预览

安装

yarn add three

实现

:::details 点击查看 Vue 实现

<template>
<div id="planet"></div>
</template>
<script lang="ts">
import {
Group,
Mesh,
MeshBasicMaterial,
PerspectiveCamera,
PointCloud,
PointCloudMaterial,
Scene,
SphereGeometry,
TextureLoader,
Vector3,
WebGLRenderer,
} from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
export default {
data() {
return {
width: '',
height: 800,
loader: null,
scene: null,
camera: null,
renderer: null,
group: null,
controls: null,
sun: null,
sunParent: null,
mercury: null,
mercuryParent: null,
venus: null,
venusParent: null,
earth: null,
earthParent: null,
mars: null,
marsParent: null,
jupiter: null,
jupiterParent: null,
saturn: null,
saturnParent: null,
uranus: null,
uranusParent: null,
neptune: null,
neptuneParent: null,
sunJpg: require('./images/sun.jpg'),
earthJpg: require('./images/earth.jpg'),
jupiterJpg: require('./images/jupiter.jpg'),
marsJpg: require('./images/mars.jpg'),
mercuryJpg: require('./images/mercury.jpg'),
neptuneJpg: require('./images/neptune.jpg'),
saturnJpg: require('./images/saturn.jpg'),
uranusJpg: require('./images/uranus.jpg'),
venusJpg: require('./images/venus.jpg'),
};
},
mounted() {
this.width = this.$el.clientWidth;
this.loader = new TextureLoader();
this.init();
},
watch: {},
methods: {
init() {
this.setScene(); //设置场景
this.setCamera(); //设置相机
this.setSun(); // 设置太阳
this.setMercury(); //设置水星
this.setVenus(); //设置金星
this.setEarth(); // 地球
this.setMars(); //火星
this.setJupiter(); // 木星
this.setSaturn(); // 土星
this.setUranus(); // 天王星
this.setNeptune(); //海王星
this.starForge(); //设置满天星背景
this.setControls(); //设置可旋转控制
this.loop(); // 循环动画
},
// 创建场景
setScene() {
this.scene = new Scene();
this.renderer = new WebGLRenderer({
antialias: true,
});
this.renderer.setSize(this.width, this.height);
document
.querySelector('#planet')
.appendChild(this.renderer.domElement);
},
// 创建相机
setCamera() {
this.camera = new PerspectiveCamera(
60,
this.width / this.height,
1,
100000,
);
this.camera.position.set(0, 500, 2000);
this.camera.lookAt(this.scene.position);
},
// 设置模型控制
setControls() {
this.controls = new OrbitControls(
this.camera,
this.renderer.domElement,
);
},
// 添加设置太阳
setSun() {
this.sun = new Group(); //建立一个组
this.sunParent = new Group();
this.scene.add(this.sunParent); //把组都添加到场景里
this.loader.load(this.sunJpg, (texture) => {
const geometry = new SphereGeometry(500, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.sun.add(mesh); //添加到组里
this.sunParent.add(this.sun);
});
},
// 设置水星
setMercury() {
this.mercury = new Group(); //建立一个组
this.mercuryParent = new Group();
this.scene.add(this.mercuryParent);
this.loader.load(this.mercuryJpg, (texture) => {
const geometry = new SphereGeometry(25, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.mercury.position.x -= 600;
this.mercury.add(mesh); //添加到组里
this.mercuryParent.add(this.mercury);
});
},
//设置金星
setVenus() {
this.venus = new Group(); //建立一个组
this.venusParent = new Group();
this.scene.add(this.venusParent);
this.loader.load(this.venusJpg, (texture) => {
const geometry = new SphereGeometry(100, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.venus.position.x -= 700;
this.venus.add(mesh); //添加到组里
this.venusParent.add(this.venus);
});
},
//设置地球
setEarth() {
this.earth = new Group(); //建立一个组
this.earthParent = new Group();
this.scene.add(this.earthParent);
this.loader.load(this.earthJpg, (texture) => {
const geometry = new SphereGeometry(100, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.earth.position.x -= 900;
this.earth.add(mesh); //添加到组里
this.earthParent.add(this.earth);
});
},
//设置火星
setMars() {
this.mars = new Group(); //建立一个组
this.marsParent = new Group();
this.scene.add(this.marsParent);
this.loader.load(this.marsJpg, (texture) => {
const geometry = new SphereGeometry(85, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.mars.position.x -= 1200;
this.mars.add(mesh); //添加到组里
this.marsParent.add(this.mars);
});
},
// 设置木星
setJupiter() {
this.jupiter = new Group(); //建立一个组
this.jupiterParent = new Group();
this.scene.add(this.jupiterParent);
this.loader.load(this.jupiterJpg, (texture) => {
const geometry = new SphereGeometry(150, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.jupiter.position.x -= 1500;
this.jupiter.add(mesh); //添加到组里
this.jupiterParent.add(this.jupiter);
});
},
// 设置土星
setSaturn() {
this.saturn = new Group(); //建立一个组
this.saturnParent = new Group();
this.scene.add(this.saturnParent);
this.loader.load(this.saturnJpg, (texture) => {
const geometry = new SphereGeometry(120, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.saturn.position.x -= 1800;
this.saturn.add(mesh); //添加到组里
this.saturnParent.add(this.saturn);
});
},
//设置天王星
setUranus() {
this.uranus = new Group();
this.uranusParent = new Group();
this.scene.add(this.uranusParent);
this.loader.load(this.uranusJpg, (texture) => {
const geometry = new SphereGeometry(50, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.uranus.position.x -= 2100;
this.uranus.add(mesh); //添加到组里
this.saturnParent.add(this.uranus);
});
},
//设置海王星
setNeptune() {
this.neptune = new Group();
this.neptuneParent = new Group();
this.scene.add(this.neptuneParent);
this.loader.load(this.neptuneJpg, (texture) => {
const geometry = new SphereGeometry(50, 20, 20); //球体模型
const material = new MeshBasicMaterial({map: texture}); //材质 将图片解构成THREE能理解的材质
const mesh = new Mesh(geometry, material); //网孔对象 第一个参数是几何模型(结构),第二参数是材料(外观)
this.neptune.position.x -= 2300;
this.neptune.add(mesh); //添加到组里
this.neptuneParent.add(this.neptune);
});
},
onWindowResize() {
const WIDTH = this.$el.clientWidth,
HEIGHT = this.height;
this.camera.aspect = WIDTH / HEIGHT;
this.camera.updateProjectionMatrix();
this.renderer.setSize(WIDTH, HEIGHT);
},
//设置公转函数
revolution() {
this.mercuryParent.rotation.y += 0.015;
this.venusParent.rotation.y += 0.0065;
this.earthParent.rotation.y += 0.05;
this.marsParent.rotation.y += 0.03;
this.jupiterParent.rotation.y += 0.01;
this.saturnParent.rotation.y += 0.02;
this.uranusParent.rotation.y += 0.09;
this.neptuneParent.rotation.y += 0.01;
},
//设置自转
selfRotation() {
this.sun.rotation.y += 0.004;
this.mercury.rotation.y += 0.002;
this.venus.rotation.y += 0.005;
this.earth.rotation.y += 0.01;
this.mars.rotation.y += 0.01;
this.jupiter.rotation.y += 0.08;
this.saturn.rotation.y += 1.5;
this.uranus.rotation.y += 1;
this.neptune.rotation.y += 0.1;
},
// 设置太阳系背景
starForge() {
const starQty = 10000;
const geometry = new SphereGeometry(10000, 100, 50);
const materialOptions = {};
const starStuff = new PointCloudMaterial(materialOptions);
geometry.vertices = [];
for (let i = 0; i < starQty; i++) {
const starVertex = new Vector3();
starVertex.x = Math.random() * 20000 - 10000;
starVertex.y = Math.random() * 20000 - 10000;
starVertex.z = Math.random() * 20000 - 10000;
geometry.vertices.push(starVertex);
}
const stars = new PointCloud(geometry, starStuff);
this.scene.add(stars);
},
// 循环场景 、相机、 位置更新
loop() {
requestAnimationFrame(this.loop);
this.revolution();
this.selfRotation();
this.renderer.render(this.scene, this.camera);
this.camera.lookAt(this.scene.position);
},
},
};
</script>

:::