3D 地球仪
创作时间:
作者:
@小白创作中心
3D 地球仪
引用
CSDN
1.
https://blog.csdn.net/mmc123125/article/details/145206500
在网页上展示一个可以交互的 3D 地球,不仅酷炫,还能带来极佳的用户体验!Three.js 是一个强大的 WebGL 库,可以帮助我们轻松实现这一点。本教程将带你从零开始,构建一个交互式地球仪,并添加自定义的交互效果。
一、准备工作
在开始之前,确保你已具备以下条件:
- 安装了 Node.js 环境。
- 新建了一个项目文件夹并初始化 npm。
- 安装了 Three.js。
1. 安装 Three.js
使用 npm 安装 Three.js:
npm install three
二、构建基础场景
我们首先创建一个包含地球模型的简单 Three.js 场景。
1. 初始化场景
创建一个 HTML 文件作为入口:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D 地球仪</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script type="module" src="app.js"></script>
</body>
</html>
在 app.js 中编写基础场景代码:
import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
现在我们已经有了一个基础的 Three.js 场景。
三、绘制地球
1. 创建地球的球体
使用 THREE.SphereGeometry 创建一个球体,并加载地球纹理贴图。
const geometry = new THREE.SphereGeometry(1, 32, 32);
const textureLoader = new THREE.TextureLoader();
const earthTexture = textureLoader.load('https://example.com/earth_texture.jpg');
const material = new THREE.MeshStandardMaterial({ map: earthTexture });
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);
2. 添加光源
为地球添加光照以突出细节。
const ambientLight = new THREE.AmbientLight(0x404040); // 环境光
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(5, 5, 5);
scene.add(pointLight);
3. 让地球自转
在动画循环中更新地球的旋转:
function animate() {
requestAnimationFrame(animate);
earth.rotation.y += 0.01; // 让地球缓慢自转
renderer.render(scene, camera);
}
四、交互功能:拖拽与缩放
1. 引入 OrbitControls
使用 OrbitControls 实现场景的旋转、缩放和拖拽交互:
npm install three-orbitcontrols
然后在代码中引入:
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; // 启用阻尼效果(模拟惯性)
controls.dampingFactor = 0.05;
在 animate 函数中调用更新方法:
function animate() {
requestAnimationFrame(animate);
controls.update(); // 更新交互
renderer.render(scene, camera);
}
现在,你可以拖动地球和滚动鼠标进行缩放了!
五、添加点标记与点击事件
1. 创建点标记
使用 THREE.Mesh 添加一些标记点来表示地球上的位置。
function createMarker(lat, lon) {
const markerGeometry = new THREE.SphereGeometry(0.02, 16, 16);
const markerMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const marker = new THREE.Mesh(markerGeometry, markerMaterial);
// 将经纬度转换为 3D 坐标
const phi = (90 - lat) * (Math.PI / 180);
const theta = (lon + 180) * (Math.PI / 180);
const radius = 1.01; // 稍微高出地球表面
marker.position.set(
radius * Math.sin(phi) * Math.cos(theta),
radius * Math.cos(phi),
radius * Math.sin(phi) * Math.sin(theta)
);
scene.add(marker);
}
createMarker(37.7749, -122.4194); // 例如,标记旧金山的位置
2. 实现点击事件
使用 Raycaster 检测鼠标点击的地球表面坐标。
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
window.addEventListener('click', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObject(earth);
if (intersects.length > 0) {
console.log('点击了地球的坐标:', intersects[0].point);
}
});
六、性能优化与附加功能
1. 使用高清纹理
你可以使用 NASA 提供的高清地球纹理,例如:
- 地球表面纹理
- 云层纹理
2. 添加星空背景
使用一个大球体作为背景,加载星空纹理:
const starsGeometry = new THREE.SphereGeometry(50, 64, 64);
const starsMaterial = new THREE.MeshBasicMaterial({
map: textureLoader.load('https://example.com/stars_texture.jpg'),
side: THREE.BackSide,
});
const stars = new THREE.Mesh(starsGeometry, starsMaterial);
scene.add(stars);
七、完整代码
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 5);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
// 地球
const textureLoader = new THREE.TextureLoader();
const earthTexture = textureLoader.load('https://example.com/earth_texture.jpg');
const earthGeometry = new THREE.SphereGeometry(1, 32, 32);
const earthMaterial = new THREE.MeshStandardMaterial({ map: earthTexture });
const earth = new THREE.Mesh(earthGeometry, earthMaterial);
scene.add(earth);
// 光源
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const pointLight = new THREE.PointLight(0xffffff, 1);
pointLight.position.set(5, 5, 5);
scene.add(pointLight);
// 星空
const starsGeometry = new THREE.SphereGeometry(50, 64, 64);
const starsMaterial = new THREE.MeshBasicMaterial({
map: textureLoader.load('https://example.com/stars_texture.jpg'),
side: THREE.BackSide,
});
const stars = new THREE.Mesh(starsGeometry, starsMaterial);
scene.add(stars);
// 动画
function animate() {
requestAnimationFrame(animate);
earth.rotation.y += 0.005;
controls.update();
renderer.render(scene, camera);
}
animate();
八、总结
通过本文,你学会了如何使用 Three.js 绘制一个交互式地球仪。我们从基本的场景搭建,到实现交互和性能优化,一步步构建出一个完整的 3D 地球应用。接下来,你可以尝试:
- 添加更多标记和信息窗口。
- 实现地球表面动态数据展示。
- 优化性能,支持移动设备。
快动手试试吧!
热门推荐
《魔神创造传》吹响冒险篇章:救世主边直播边拯救世界
山蓝鸲:北美西部的蓝色精灵
秋季打卡黄果树瀑布,贵州最美时节!
加榜梯田:贵州最美天空之镜
“新四联”的用药秩序和用法用量?国家心力衰竭指南来了!
新加坡——东南亚文化与历史的交融
新加坡市场深度解析:经济概览与美妆市场潜力
非农前瞻:美国12月就业报告预计将显示招聘放缓,失业率稳定
怎么吃才能改善便秘?这些便秘的秘密,偷偷告诉你……
汉字logo设计之美,一绝!
肖战版《射雕英雄传》:争议与突破
肖战版郭靖能否超越经典?
肖战版郭靖能否超越经典?从票房到口碑的全面解析
肖战版郭靖:流量还是实力?
肖战版郭靖能否撑起春节档?
古装剧里的“叩首”礼仪,你真的懂吗?
iPad截图全攻略:7种实用截图方法详解
红焖甲鱼猪脚:一道美味与养生兼具的滋补佳肴
红焖甲鱼猪脚:秋冬滋补新宠
GIA教你用光谱分析鉴别培育钻石
GIA用AI鉴别培育钻石,靠谱吗?
揭秘乾隆皇帝的一天:从冰糖燕窝到龙袍朝服
甲午战争背后:清朝末年的诡异现象揭秘
多尔衮:从战场统帅到摄政王的传奇人生
防止AI系统受到提示注入攻击的五个方法
AI系统架构的组成
嫦娥六号启程月球背面:中国深空探测迈入新阶段
鋼筆保養指南:讓您的書寫工具歷久彌新
盘核桃的四个关键步骤:从打底到玉化的完整指南
美国24年来最严重空难:67人遇难,初步调查显示管制员配置不足