import * as THREE from 'three'
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'//控制器
import {CSS2DRenderer,CSS2DObject} from 'three/examples/jsm/renderers/CSS2DRenderer.js'
//three.js使用npm安装
//声明全局变量
let camera,scene,renderer,labelRenderer;
let moon,earth;
let clock = new THREE.Clock();
let nt = clock.getDelta();
const textureLoader = new THREE.TextureLoader();//实例化纹理加载器
export default {
// 注册
components: {},
// 定义变量
data() {
return {
}
},
// 计算属性 当里面的数据发生变化时,会自动触发重新计算
computed: {},
// 监控data中的变量变化
watch: {},
// 方法集合
methods: {
init(){
//地球和月球半径大小
const EARTH_RADIUS = 2.5;
const MOON_RADIUS = 0.27;
//实例化相机
camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200);
//设置相机位置
camera.position.set(10,5,20);
//实例化场景
scene = new THREE.Scene();
//添加坐标轴
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
//创建聚光灯光源
const dirLight = new THREE.SpotLight(0xffffff);
//设置光源位置
dirLight.position.set(0,0,10);
dirLight.intensity = 5;
dirLight.castShadow = true;//开启光源阴影
scene.add(dirLight);//将点光源添加到场景中
// 添加环境光
const aLight = new THREE.AmbientLight(0xffffff);
aLight.intensity=0.3;//光照的强度。缺省值为 1。
scene.add(aLight);
//创建月球
const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS,16,16);
//设置月球材质
const moonMaterial = new THREE.MeshPhongMaterial({
map:textureLoader.load(require('../assets/textures/planets/moon_1024.jpg')),
});
moon = new THREE.Mesh(moonGeometry,moonMaterial);
moon.receiveShadow = true;
moon.castShadow = true;
scene.add(moon);
//创建地球
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS,16,16);
const earthMaterial = new THREE.MeshPhongMaterial({
shininess: 5,//调节镜面反射光 高亮的程度,越高的值越闪亮。默认值为 30。
map:textureLoader.load(require('../assets/textures/planets/earth_atmos_2048.jpg')),
specularMap:textureLoader.load(require('../assets/textures/planets/earth_specular_2048.jpg')),
normalMap:textureLoader.load(require('../assets/textures/planets/earth_normal_2048.jpg')),
});
earth = new THREE.Mesh(earthGeometry,earthMaterial);
earth.castShadow = true;
earth.receiveShadow = true;
scene.add(earth);
//创建标签div
const earthDiv = document.createElement('div');
earthDiv.className = 'label';
earthDiv.textContent = 'Earth';
earthDiv.style.marginTop = '-1em';
const earthLable = new CSS2DObject(earthDiv);//创建标签对象
earthLable.position.set(0,EARTH_RADIUS + 0.5,0);
earth.add(earthLable);
const moonDiv = document.createElement('div');
moonDiv.className = 'label';
moonDiv.textContent = 'Moon';
moonDiv.style.marginTop = '-1em';
var moonLabel = new CSS2DObject(moonDiv);
moonLabel.position.set(0, MOON_RADIUS, 0);
moon.add(moonLabel);
//创建渲染器
renderer = new THREE.WebGLRenderer({
alpha: true//显示background-image
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth,window.innerHeight);
//渲染阴影
renderer.shadowMap.enabled = true;
//追加
document.body.appendChild(renderer.domElement);
//创建标签渲染器
labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth,window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0';
document.body.appendChild(labelRenderer.domElement);
//绑定控制器和摄像头
const controls = new OrbitControls(camera,renderer.domElement);
},
async animate (){
const elapsed = clock.getElapsedTime();
moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5);
//地球自转
var axis = new THREE.Vector3(0,1,0);
earth.rotateOnAxis(axis, Math.PI / 1000);
renderer.render(scene,camera);
labelRenderer.render(scene,camera);
requestAnimationFrame(this.animate);
},
//调整尺寸
resizeSize(){
window.onresize = function(){
camera.aspect = window.innerWidth/window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth,window.innerHeight);
}
}
},
// --------------------------- 生命周期 start -----------------------------------
// 创建完成(可以访问当前this实例)
created() {},
// 挂载完成(可以访问DOM元素)
mounted() {
this.init();
this.animate();
this.resizeSize();
},
// 创建之前
beforeCreate() {},
// 挂载之前
beforeMount() {},
// 更新之前
beforeUpdate() {},
// 更新之后
updated() {},
// 销毁之前
beforeDestroy() {},
// 销毁完成
destroyed() {},
// --------------------------- 生命周期 end -----------------------------------
// 如果页面有keep-alive缓存功能,这个函数会触发
activated() {}
}
* {
margin: 0;
padding: 0;
}
canvas {
/* background-image: 'url(' + "'" + require('../assets/imgs/star.jpg') + "'" + ')'; */
background-image:url(../assets/imgs/star.jpg);
background-size: cover;
}
#app{
display: none;
}
.label{
color: #fff;
font-size: 16px;
}