Three.js 实现地球仪并标注城市教程(Trae实现)

本人最近在做一个全球地铁的导航网站------metrolinehub,于是就想做一个3D的旋转的地球,做3D的地球的话首先想到的是 Three.js。在三维可视化领域,Three.js 是一个强大且易用的 JavaScript 库,能够帮助开发者轻松创建各种炫酷的 3D 场景。本文将带你从零开始,使用 Three.js 实现一个精美的地球仪,并在地球仪上标注北京、上海、东京等城市。

网站

全球城市地铁地图: www.metrolinehub.com/zh

准备工作

在开始之前,你需要准备以下内容:

工具

  1. Trae工具:用于快速编写代码。
  2. three.js 库 :可以从官方网站(threejs.org/ ) 下载,也可以使用 CDN 引入。

原理

  1. 就是使用 SphereGeometry 来创建一个球体,它定义了地球的基本形状,通过贴图实现地球的渲染,通过调整参数能控制球体的细分程度。
  2. 利用 requestAnimationFrame 函数创建一个动画循环,该函数会在浏览器准备好重绘页面时被调用。在每一帧中,通过修改地球网格对象的 rotation 属性(如 rotation.y )来改变地球的旋转角度,最后调用渲染器的 render 方法更新画面,从而实现地球持续旋转的视觉效果。

简单的说就是一个旋转的球,它可以是地球,也可以是篮球、足球等

一、项目搭建

首先,我们需要创建一个基本的 HTML 页面,并引入 Three.js 库。可以通过 CDN 引入 Three.js,在 HTML 文件的标签中添加以下代码:

xml 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r151/three.min.js"></script>

接着,在标签中创建一个用于渲染 3D 场景的容器元素,例如:

bash 复制代码
<div id="canvas-container"></div>

然后,在 HTML 文件末尾引入我们的 JavaScript 代码文件(假设文件名为script.js):

xml 复制代码
<script src="script.js"></script>

二、创建地球仪

在script.js文件中,开始编写创建地球仪的代码。首先,创建一个场景、相机和渲染器:

javascript 复制代码
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.getElementById('canvas-container').appendChild(renderer.domElement);

接下来,创建地球的几何体和材质。我们使用SphereGeometry来创建球体几何体,并使用带有地球纹理的MeshStandardMaterial来赋予其地球外观。可以从网上下载合适的地球纹理图片,这里假设纹理图片文件名为earth.jpg:

ini 复制代码
// 创建地球几何体
const geometry = new THREE.SphereGeometry(2, 32, 32);
// 创建地球材质
const texture = new THREE.TextureLoader().load('earth.jpg');
const material = new THREE.MeshStandardMaterial({ map: texture });
// 创建地球模型
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);

最后,在一个渲染循环函数中不断更新场景并渲染:

scss 复制代码
function animate() {
    requestAnimationFrame(animate);
    // 可以在这里添加地球旋转等动画逻辑
    earth.rotateY(0.01);
    renderer.render(scene, camera);
}
animate();

此时,运行 HTML 文件,你应该能看到一个旋转的地球仪。

三、准备城市数据

为了在地球仪上标注城市,我们需要准备城市的相关数据,包括城市名称、经纬度坐标等。可以将这些数据存储在一个 JavaScript 数组中,示例如下:

yaml 复制代码
const cities = [
    { name: '北京', lat: 39.9042, lng: 116.4074 },
    { name: '上海', lat: 31.2304, lng: 121.4737 },
    { name: '东京', lat: 35.6895, lng: 139.6917 }
];

这里的经纬度坐标决定了城市在地球仪上的位置,需要根据实际情况准确获取。

四、在地球仪上标注城市

有了城市数据后,我们就可以将城市标注添加到地球仪上。首先,创建一个用于存放标注的组:

ini 复制代码
const cityMarkers = new THREE.Group();
scene.add(cityMarkers);

然后,遍历城市数据数组,为每个城市创建标注。标注可以使用Mesh或Sprite来实现,这里我们使用Sprite,它能始终面向相机,更适合做文字标注:

ini 复制代码
const fontLoader = new THREE.FontLoader();
fontLoader.load('https://cdnjs.cloudflare.com/ajax/libs/three.js/r151/fonts/helvetiker_regular.typeface.json', (font) => {
    cities.forEach((city) => {
        const textGeometry = new THREE.TextGeometry(city.name, {
            font: font,
            size: 0.2,
            height: 0.01
        });
        const textMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff });
        const textMesh = new THREE.Mesh(textGeometry, textMaterial);
        // 将经纬度坐标转换为三维空间中的位置
        const phi = (90 - city.lat) * Math.PI / 180;
        const theta = (city.lng - 180) * Math.PI / 180;
        const radius = 2.2; // 标注在地球表面外一定距离
        textMesh.position.x = radius * Math.sin(phi) * Math.cos(theta);
        textMesh.position.y = radius * Math.cos(phi);
        textMesh.position.z = radius * Math.sin(phi) * Math.sin(theta);
        cityMarkers.add(textMesh);
    });
});

上述代码中,首先加载了一个字体文件,然后为每个城市创建一个TextGeometry作为文字内容,设置好材质后创建Mesh。接着,通过经纬度坐标计算出城市在三维空间中的位置,并将标注添加到之前创建的cityMarkers组中。

五、优化与拓展

  1. 标注样式优化:可以为标注添加阴影、调整字体颜色和大小,使其更加美观醒目。

  2. 添加交互:可以添加鼠标悬停提示、点击跳转等交互功能,提升用户体验。例如,使用THREE.Raycaster实现鼠标点击检测,当点击到标注时弹出城市详细信息。

  3. 更多城市数据:可以从网络获取更多城市数据,丰富地球仪上的标注内容。

通过以上步骤,我们成功地使用 Three.js 实现了一个带有城市标注的地球仪。希望本文能帮助你在 Three.js 的学习和实践中有所收获,你可以根据自己的需求进一步拓展和完善这个项目。

其他文章

使用 Leaflet.js 生成北京地铁地图(Trae实现)

中国地铁导航

相关推荐
重生之我在火星学前端10 小时前
WebGL学习之路:1. 理论基础
前端·webgl·three.js
全栈小刘10 小时前
【震撼】🎉用字节全家桶手把手打造你的专属智能笔记平台
前端·trae
小厂永远得不到的男人12 小时前
突破编码思维定式:Trae智能编码工具深度体验报告
trae
星际码仔2 天前
Cursor v0.49 更新:自动生成规则、终端命令编辑和MCP识别图像
ai编程·cursor·trae
糖墨夕2 天前
【3】Threejs环境光、点光源、聚光灯等常见光源类型对比
前端·three.js·canvas
汪子熙2 天前
使用 Trae 快速开发能生成二维码的 SAP UI5 应用
前端·trae
创码小奇客2 天前
MongoDB 聚合操作,有手就行?
mysql·mongodb·trae
Mintopia3 天前
Three.js 学习第一天:基础搭建与核心概念
前端·javascript·three.js
QING6183 天前
Android Executor 与 Executors 详解 —— 新手指南
android·ai编程·trae