1 创建场景
2 创建相机
3 创建地球模型
4 创建卫星中心
5 创建卫星圆环及卫星
6 创建控制器
7 创建渲染器
<template>
<div class="home3dMap" id="home3dMap"></div>
</template>
<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
name:"home3dMap",
data(){
return {
scene:null, //场景
camera:null, //相机
meshMaterial:null, //网络模型
controls:null, //控制器
renderer:null, //渲染器
satellites:[], //卫星(数组)
}
},
components:{},
created(){},
beforeDestroy(){},
mounted(){
//初始化
this.init();
},
methods:{
init(){
this.createScene(); //创建场景
this.createMesh(); //创建几何体
this.createLight(); //创建光源
this.createCamera(); //创建相机
this.createRender(); //创建渲染器
this.createControls(); //创建轨道控制器
this.animate();
},
//创建场景
createScene(){
let scene = new THREE.Scene();
this.scene = scene;
},
//创建几何体
createMesh(){
//地球
let geometry = new THREE.SphereGeometry( 70, 32, 16);
let earthImgSrc = require('@/assets/img/home/home3dMapBackground.png');
//材质
let earthMater = new THREE.MeshPhongMaterial({
map: new THREE.TextureLoader().load(earthImgSrc),
transparent:true,
depthWrite:false,
});
//网络模型对象 -- 地球
let meshMaterial = new THREE.Mesh(geometry,earthMater);
//地球模型
this.meshMaterial = meshMaterial;
//添加到场景中
this.scene.add(meshMaterial);
//添加圆环
this.initSatellite(meshMaterial);
},
//添加圆环
initSatellite(meshMaterial){
//返回一个卫星和轨道的组合体
// satelliteSize/卫星大小 satelliteRadius/卫星旋转半径 rotation /组合体的旋转方向 speed/卫星运动速度
// 圆环图片
let sadImgSrc = require('@/assets/img/control/satellite.png');
//循环卫星 假设有3颗卫星
for(let i=0; i<3; i++){
let satelliteSize = 12,satelliteRadius=0,rotation={x:0,y:0,z:0},speed=0;
if(i==0){
satelliteRadius = 80;
rotation.x = -Math.PI * 0.35;
rotation.y = Math.PI * 0.25;
rotation.z = 0;
speed = 0.004;
}else if(i==1){
satelliteRadius =100;
rotation.x = -Math.PI * 0.35;
rotation.y = -Math.PI * 0.2;
rotation.z = 0;
speed = 0.005;
}else{
satelliteRadius = 86;
rotation.x = -Math.PI * 0.25;
rotation.y = Math.PI * 0.15;
rotation.z = 0;
speed = 0.003;
}
//卫星中心
let earthGeometry = new THREE.SphereGeometry(0,0,0);
//材质
let earthMater = new THREE.MeshPhongMaterial({
color:0xa0a0a0,
});
let centerMesh = new THREE.Mesh(earthGeometry,earthMater);
//卫星圆环
let circleGeometry = new THREE.RingGeometry(satelliteRadius, satelliteRadius + 0.3, 100, 1);
//材质
let circleMater = new THREE.MeshBasicMaterial({
color:0xffffff,
side: THREE.DoubleSide
})
//网络模型对象 -- 卫星圆环
let track = new THREE.Mesh(circleGeometry,circleMater);
let satellite = new THREE.Sprite(new THREE.SpriteMaterial({
map: new THREE.TextureLoader().load(sadImgSrc),
blending: THREE.AdditiveBlending
}));
//卫星大小
satellite.scale.x = satellite.scale.y = satellite.scale.z = 12;
//卫星旋转半径
satellite.position.set(satelliteRadius, 0, 0);
let pivotPoint = new THREE.Object3D();
pivotPoint.add(satellite);
pivotPoint.add(track);
//卫星中心模型添加卫星对象
centerMesh.add(pivotPoint);
centerMesh.rotation.set(rotation.x, rotation.y, rotation.z);
//添加到场景中
this.scene.add(centerMesh);
//添加卫星
this.satellites.push({satellite:centerMesh, speed:speed, address:rotation});
}
},
//创建光源
createLight(){
// 环境光
const ambientLight = new THREE.AmbientLight(0xcccccc, 2)
this.scene.add(ambientLight)
// 平行光
let directionalLight = new THREE.DirectionalLight(0xffffff, 0.2)
directionalLight.position.set(1, 0.2, 0).normalize()
// 平行光2
let directionalLight2 = new THREE.DirectionalLight(0xff2ffff, 0.2)
directionalLight2.position.set(1, 0.2, 0.1).normalize()
this.scene.add(directionalLight)
this.scene.add(directionalLight2)
// 平行光3
let directionalLight3 = new THREE.DirectionalLight(0xffffff, 0)
// 开启阴影
directionalLight3.castShadow = true
// 设置光边界
// directionalLight3.shadow.camera.top = 18
// directionalLight3.shadow.camera.bottom = -10
// directionalLight3.shadow.camera.left = -52
// directionalLight3.shadow.camera.right = 12
this.scene.add(directionalLight3)
},
//创建相机
createCamera(){
//渲染区域 宽高为 960/685
let camera = new THREE.PerspectiveCamera(60, 960 / 685, 1, 10000)
//设置相机位置
camera.position.set(50, -10, 200)
//设置相机方向
camera.lookAt(0, 0, 0)
this.camera = camera;
this.scene.add(this.camera);
},
//创建渲染器
createRender(){
let element = document.getElementById("home3dMap");
//创建渲染器
let renderer = new THREE.WebGLRenderer({antialias:true, alpha:true})
renderer.setSize(960,685) //设置渲染区域尺寸
renderer.shadowMap.enabled = true; //显示阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setClearColor(0x3f3f3f, 0); //设置背景颜色
this.renderer = renderer;
element.appendChild(this.renderer.domElement)
},
//创建轨道控制器
createControls(){
let controls = new OrbitControls(this.camera, this.renderer.domElement);
controls.enableDamping = true;
controls.maxZoom = Infinity;
this.controls = controls;
},
//循环
animate(){
this.controls.update(); //控制阻尼器
//地球自传
this.meshMaterial.rotation.y += 0.0015;
this.renderer.render(this.scene, this.camera);
for(let i=0; i<this.satellites.length; i++){
this.satellites[i].satellite.rotation.z -= this.satellites[i].speed;
}
requestAnimationFrame(this.animate.bind(this));
},
},
}
</script>
<style>
.home3dMap{
width:100%;
height:100%;
}
</style>