文档
Three.js 旋转地球仪
目标
用 Three.js 创建 3D 旋转地球仪:纹理贴图 + 星空粒子 + 鼠标交互旋转缩放。
完整代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>3D 地球仪</title>
<style>
body { margin: 0; overflow: hidden; background: #000; }
canvas { display: block; }
.info { position: fixed; bottom: 20px; left: 20px; color: white; font-family: system-ui; opacity: 0.7; }
</style>
</head>
<body>
<div class="info">🌍 拖拽旋转 · 滚轮缩放</div>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/"
}
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
// 场景
const scene = new THREE.Scene();
// 相机
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 4);
// 渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// 控件
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.minDistance = 1.5;
controls.maxDistance = 10;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.5;
// 星空粒子
const starsGeom = new THREE.BufferGeometry();
const starsCount = 2000;
const positions = new Float32Array(starsCount * 3);
for (let i = 0; i < starsCount * 3; i++) {
positions[i] = (Math.random() - 0.5) * 30;
}
starsGeom.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const starsMat = new THREE.PointsMaterial({ color: 0xffffff, size: 0.02 });
const stars = new THREE.Points(starsGeom, starsMat);
scene.add(stars);
// 地球
const geometry = new THREE.SphereGeometry(1, 64, 64);
// 使用纹理贴图(在线纹理)
const textureLoader = new THREE.TextureLoader();
const earthMap = textureLoader.load('https://threejs.org/examples/textures/planets/earth_atmos_2048.jpg');
const earthSpec = textureLoader.load('https://threejs.org/examples/textures/planets/earth_specular_2048.jpg');
const earthBump = textureLoader.load('https://threejs.org/examples/textures/planets/earth_normal_2048.jpg');
const material = new THREE.MeshPhongMaterial({
map: earthMap,
specularMap: earthSpec,
bumpMap: earthBump,
bumpScale: 0.05,
specular: new THREE.Color('grey'),
shininess: 10,
});
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);
// 光照
const ambientLight = new THREE.AmbientLight(0x333333);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
directionalLight.position.set(5, 3, 5);
scene.add(directionalLight);
// 动画循环
function animate() {
requestAnimationFrame(animate);
stars.rotation.y += 0.0001;
controls.update();
renderer.render(scene, camera);
}
animate();
// 响应式
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>
运行步骤
- 复制代码保存为
index.html - 用 Live Server 打开(纹理需要 HTTP 协议加载)
- 或用
npx serve .启动
预期输出
- 3D 地球自动缓慢旋转
- 鼠标拖拽旋转视角,滚轮缩放
- 背景星空粒子缓慢移动
- 光照渲染立体效果(海洋有反光)
毕设扩展方向
- 添加标记点(城市标注)
- 实现点击高亮某国家
- 接入数据展示全球分布
- 做成校园 3D 导览的基底