three.js 是渲染基础地球模型的可行方案,需用 canvas 作画布、等经纬度贴图、本地服务解决 cors、orbitcontrols 限制旋转角度并禁用缩放、自转用 requestanimationframe、移动端需设置 touch-action 和触摸模式。

用 Three.js 渲染基础地球模型,别碰原生 WebGL
纯 HTML 做不了 3D 地球仪——它没 3D 渲染能力。真正能落地的方案是 Three.js + HTMLCanvasElement,把 canvas 当画布,用 JavaScript 控制三维场景。想绕过库直接写 shader?调试成本高、光照/投影/纹理映射全得手撸,99% 的需求没必要。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 引入
three@0.160.1(稳定版,避免新版WebGLRenderer兼容性问题) - 地球贴图用
world.topo.bathy.200401.jpg这类等经纬度投影图(非墨卡托),否则陆地会拉伸变形 - 必须调用
renderer.setPixelRatio(window.devicePixelRatio),否则高清屏上地球边缘发虚
加载地球贴图时常见的 CORS 和黑屏问题
本地双击打开 HTML 文件时,new TextureLoader().load('earth.jpg') 会静默失败,控制台报 Cross-Origin Request Blocked——浏览器禁止 file:// 协议跨文件加载图片。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 开发阶段用
npx http-server起个本地服务,让页面走http://localhost:8080 - 贴图路径别用相对路径如
./img/earth.jpg,改用绝对路径/img/earth.jpg,避免路由嵌套导致加载 404 - 如果地球渲染出来是纯黑,先检查
scene.add(light)是否漏了添加DirectionalLight或AmbientLight
让地球自转+响应鼠标拖拽的关键参数
OrbitControls 是最省事的交互方案,但它默认带缩放和俯仰,而地球仪通常只需水平旋转+轻微倾斜。直接用会导致北极点被“掀开”或赤道扭曲。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 初始化后立刻限制旋转角度:
controls.minPolarAngle = Math.PI / 4(约 45°,挡住极点) - 禁用缩放:
controls.enableZoom = false,否则滚轮会让地球忽大忽小,失去比例感 - 自转用
requestAnimationFrame持续更新mesh.rotation.y += 0.001,别用setInterval,帧率不稳会导致转动卡顿 - 若需点击城市高亮,别在地球几何体上直接加事件监听——要用
Raycaster投射到mesh,否则坐标映射会错位
移动端触摸拖拽失效或延迟的修复点
默认 OrbitControls 对 touchstart/touchmove 的处理太粗糙,iOS 上经常一碰就跳、拖拽跟手性差,甚至触发页面滚动。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 给 canvas 加样式:
touch-action: none,阻止浏览器默认手势干扰 - 实例化 controls 后补一句:
controls.touches.ONE_FINGER = THREE.TOUCH.ROTATE,强制单指滑动=旋转 - 在
touchmove事件里加event.preventDefault()(需绑定到 canvas 元素本身,不是 window) - 别用
mesh.material.wireframe = true查问题——移动端开启线框模式会严重掉帧,换用material.color.set(0x4488ff)快速验证是否渲染成功
真正难的是贴图精度和地理坐标对齐:比如把北京坐标 [39.9, 116.4] 转成球面顶点,需要算 phi = (90 - lat) * Math.PI / 180,这个转换一旦写错,所有标记点都会偏移上千公里。没人会盯着公式看,但数据一错,整个地球就“歪”了。










