threejs 旋转的3d地球纹理效果,海面为深蓝色,陆地为浅黄色的纹理图。
动态效果
实例代码
/**
* @Author: 858834013@qq.com
* @Name: threejs地球
* @Date: 2023年09月19日07:01:13
* @Desc: 旋转的蓝色地球
*/
<template>
<div class="canvasGLTFBody">
<div ref='canvasGLTF' class="canvasGLTF">
</div>
</div>
</template>
<script>
import * as THREE from 'three'
import imgs from './assets/earth.jpg'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 加载地球的纹理
var img1 = new THREE.TextureLoader().load(imgs);
// 初始化用于记录动画帧ID的变量
var animationFrameId = null
// 初始化三维场景变量
var scene = null
// 初始化摄像机变量
var camera = null
// 初始化渲染器变量
var renderer = null
// 初始化ResizeObserver对象变量,用于监听DOM元素的大小变化
var resizeObserver = null
export default {
name: 'earth',
// 当组件被挂载到DOM后执行的函数
mounted: function () {
var that = this
// 获取canvas的宽度和高度
var width = that.$refs.canvasGLTF.offsetWidth
var height = that.$refs.canvasGLTF.offsetHeight
// 初始化用于旋转地球的步长
var step = 0;
// 创建新的三维场景
scene = new THREE.Scene();
// 创建透视摄像机
camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
// 创建WebGL渲染器,并启用抗锯齿和透明度
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
// 设置渲染器的大小
renderer.setSize(width, height);
// 创建材质数组并添加基础材质
var mats = [];
mats.push(new THREE.MeshBasicMaterial({map: img1}));
// 创建球体的几何形状
const geometry = new THREE.SphereGeometry(28.9, 60, 60);
// 创建地球的材质
var material = new THREE.MeshLambertMaterial({
color: 0xFFFFFF,
map: img1
});
// 创建地球的网格模型
var sphere = new THREE.Mesh(geometry, material);
// 设置地球的初始旋转值
sphere.rotation.x = 0.1;
// 将地球添加到场景中
scene.add(sphere);
// 创建并添加环境光
var ambientLight = new THREE.AmbientLight(0x666666);
scene.add(ambientLight);
// 创建并添加投影灯光
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 160, 100);
spotLight.castShadow = true;
scene.add(spotLight);
// 设置摄像机的位置和视点
camera.position.x = -50;
camera.position.y = 26;
camera.position.z = 50;
camera.lookAt(scene.position);
// 开始渲染循环
render();
// 渲染函数
function render() {
// 使地球绕Y轴旋转
sphere.rotation.y = step += 0.005;
// 请求下一帧的动画
animationFrameId = requestAnimationFrame(render);
// 渲染场景
renderer.render(scene, camera);
}
var controls = new OrbitControls(camera, renderer.domElement);
// 将渲染器的DOM元素添加到Vue组件中的相应位置
that.$refs.canvasGLTF.appendChild(renderer.domElement)
// 初始化尺寸观察者以监听canvas的大小变化
that.initResizeObserver()
},
beforeDestroy() {
// 在组件销毁之前,停止动画并释放资源
cancelAnimationFrame(animationFrameId);
renderer.dispose();
scene.dispose();
if (resizeObserver) {
resizeObserver.disconnect();
}
},
methods: {
// 窗口自适应
initResizeObserver() {
resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
if (entry.target === this.$refs.canvasGLTF) {
const width = entry.contentRect.width;
const height = entry.contentRect.height;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
renderer.render(this.scene, this.camera);
}
}
});
resizeObserver.observe(this.$refs.canvasGLTF);
},
}
}
</script>
<style lang="scss" scoped>
.canvasGLTFBody {
position: fixed;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
}
.canvasGLTF {
position: relative;
margin: 0 auto;
width: 80%;
height: 80%;
}
</style>
更多3d地球效果
实例下载地址
代码基于 vue3 vite js nodejs 16开发,请确认有一定的代码基础再进行购买