手把手教你用Three.js打造沉浸式3D地球展示,让页面生动起来!🌟

2,044 阅读9分钟

引言

今天,我们来探讨一个引人入胜的话题——如何使用前端技术创建一个3D地球。在这个信息爆炸的时代,视觉效果的重要性不言而喻,尤其是在网页设计和开发中。通过结合HTML5的Canvas元素和强大的Three.js库,我们可以将地球的三维模型栩栩如生地带到用户的屏幕上。

为了直观地展现最终效果,请参见以下动态演示😎😎:

屏幕录制 2024-12-31 110538.gif

从这段动画中可以看到,用户可以通过鼠标交互轻松地旋转地球,探索其不同的面貌。

这种沉浸式的体验让静态页面瞬间生动起来,极大地提升了用户参与度和互动乐趣。接下来,我们将一步步引导你实现这一效果,带你从零开始构建一个引人入胜的3D地球展示。🥳

11.jpg

源码展示如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D 地球</title>
    <!-- 画地球 选择框架 加速 -->
    <script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>
</head>
<body>
    <canvas id="webglcanvas"></canvas>
    <script>
        // 3D 世界就是镜头拍出的世界
        let canvas,   //3D 容器
            camera,   // 镜头
            scene,    // 场景
            renderer, // 渲染器
            group;    // 组

        let mouseX = 0, mouseY = 0;  //mousemove 坐标
        let windowHalfx = window.innerWidth / 2;   //确认球心  窗口宽度的一半
        let windowHalfy = window.innerHeight / 2;
        init();
        animate();

        function init() {
            // 3D 容器
            canvas = document.getElementById('webglcanvas'); // DOM
            camera = new THREE.PerspectiveCamera(60,   // 视野角度 FOV
                window.innerWidth / window.innerHeight   // 宽高比
                , 1, 2000); //实例化 相机
            // 相机离scene场景的距离
            camera.position.z = 500;
            
            scene = new THREE.Scene();   // 实例化 场景
            scene.background = new THREE.Color(0xffffff); // 背景色
            
            group = new THREE.Group(); // 实例化 组
            scene.add(group);

            // 纹理加载器
            let loader = new THREE.TextureLoader();
            loader.load('land_ocean_ice_cloud_2048.jpg', function (texture) {
                let geometry = new THREE.SphereGeometry(200, 20, 20); // 球体 半径 宽 高
                let metarial = new THREE.MeshBasicMaterial({  //材质
                    map: texture
                });
                let mesh = new THREE.Mesh(geometry, metarial); // 网格
                group.add(mesh);
                
                // 实例化渲染器 目标元素是canvas
                renderer = new THREE.WebGLRenderer({
                    canvas: canvas,
                    antialias: true
                });
                // 渲染器 尺寸
                renderer.setSize(window.innerWidth, window.innerHeight);
                // 监听 鼠标移动
                document.addEventListener('mousemove', onDocumentMouseMove, false);
            })
        }
        function onDocumentMouseMove(event) {
            mouseX = (event.clientX - windowHalfx);
            mouseY = (event.clientY - windowHalfy);
        }
        function animate() {
            // 递归 屏幕的刷帧率 60帧/s
            requestAnimationFrame(animate);
            reder()
        }
        function reder() {
            // 渲染器 渲染
            camera.position.x += (mouseX -camera.position.x) * 0.05;
            camera.position.y += (mouseY -camera.position.y) * 0.05;
            camera.lookAt(scene.position)
            group.rotation.y += 0.005;
            renderer.render(scene, camera);
        }
    </script>
</body>

</html>

通过详细的步骤和实用的代码示例,我们不仅会让你见证页面从静态到动态的转变,还将帮助你掌握Three.js的核心技巧,开启更多创意可能。准备好了吗?让我们一起踏上这段激动人心的技术探索之旅吧! 🚀✨

要实现一个3D地球,要怎么做呢?

17.jpg

简单的准备

首先,要构建一个逼真的3D地球,我们需要一些基础资源和工具。具体来说:

  1. 地球图片准备:为了给地球添加纹理,我们需要一张高清的地球图像。这里选择了一张分辨率为2048x2048像素的图片,它包含了陆地、海洋、冰川以及云层的细节,能够提供足够的真实感。 land_ocean_ice_cloud_2048.jpg

  2. 在HTML中准备一个空画布

    <canvas id="webglcanvas"></canvas>
    
  3. 引入Three.js库:Three.js是目前最成熟且功能丰富的前端3D图形库之一。它简化了WebGL编程,让开发者可以专注于创建惊人的视觉效果,而不是纠结于底层API的复杂性。

    <script src="https://cdn.bootcss.com/three.js/r83/three.min.js"></script>
    

这是目前一个前端最成熟的一个3D库,非常酷炫,利用这个库,我们很快就可以实现3D地球的案例

准备工作虽然简短,但每一步都是实现最终目标的关键。接下来,我们将深入探讨如何利用这些资源和技术,打造出一个令人印象深刻的3D地球。

实现逻辑

试想一下,如果你要实现一个引人入胜的3D地球展示,你会需要些什么工具和技术?在引入了three.js库之后,我们已经拥有了构建3D模型的基础。在这个框架中,创建一个3D模型就像是通过镜头捕捉世界的真实画面。而承载这个世界的容器——画布(canvas),则是我们准备工作的关键一步。

接下来,想象自己是一名导演,正在规划拍摄一部关于地球的电影。首先,我们需要搭建场景(scene),这如同为电影搭建舞台,通过new THREE.Scene(),我们创建了一个三维空间,等待着主角登场。然后,安置摄像机(camera)就如安排摄影师的位置和视角,使用透视摄像机(THREE.PerspectiveCamera),模拟出人类视觉的深度感,调整其视野角度、宽高比等参数,确保地球能以最佳姿态呈现。

启动渲染器(renderer)就如同电影拍摄完成后将底片洗出来,Three.js推荐的WebGLRenderer能够高效利用现代浏览器的强大图形处理能力,把我们的3D场景转换成可视的画面。设置好渲染器尺寸并与页面中的容器相匹配后,我们就准备好迎接观众的目光了。

现在,是时候让主角登场——引入地球模型(Group or Mesh)。可以使用球体几何(THREE.SphereGeometry)并搭配纹理贴图来手工制作一个逼真的地球,或者加载现成的3D模型文件。为了方便管理地球,我们可以将它们添加到一个THREE.Group对象中,并最终加入到场景里。

最后,为了让地球“活”起来,比如实现自转效果,我们需要设立一个动画循环(Animation Loop)。利用JavaScript的requestAnimationFrame函数,我们可以创建一个持续更新的循环,在每次迭代中调整地球的位置或旋转状态,并调用渲染器的render方法刷新画面,使地球看起来像是在不停地转动。

通过这些精心设计的步骤,从选择合适的工具到布置每个元素的位置,直至让整个场景鲜活起来,我们完成了使用three.js创建一个简单而引人入胜的3D地球视图的基本框架。

每一个环节都是不可或缺的一部分,共同构成了这场虚拟的视觉盛宴。

关键代码解释

现在,让我们深入探讨一些关键的代码片段,并详细解析它们的工作原理。通过这些代码,我们可以更清晰地理解如何构建和优化3D地球展示的关键步骤和技术细节。🤓🤓

1.确定球心坐标

 let mouseX = 0, mouseY = 0;  //mousemove 坐标
        let windowHalfx = window.innerWidth / 2;   //确认球心  窗口宽度的一半
        let windowHalfy = window.innerHeight / 2;

这段代码初始化了鼠标的相对坐标和屏幕中心点的位置。mouseXmouseY 将用来存储鼠标相对于屏幕中心的偏移量。而 windowHalfXwindowHalfY 则是计算出来的屏幕中心坐标。

这为后续处理用户交互提供了基础数据,使得用户可以通过移动鼠标来改变视角,增强了互动性和沉浸感。

2. 使用init封装

 function init() {
            // 3D 容器
            canvas = document.getElementById('webglcanvas'); // DOM

            camera = new THREE.PerspectiveCamera(60,   // 视野角度 FOV
                window.innerWidth / window.innerHeight   // 宽高比
                , 1, 2000); //实例化 相机
            // 相机离scene场景的距离
            camera.position.z = 500;

            scene = new THREE.Scene();   // 实例化 场景
            scene.background = new THREE.Color(0xffffff); // 背景色

            group = new THREE.Group(); // 实例化 组
            scene.add(group);

            // 纹理加载器
            let loader = new THREE.TextureLoader();
            loader.load('land_ocean_ice_cloud_2048.jpg', function (texture) {
                let geometry = new THREE.SphereGeometry(200, 20, 20); // 球体 半径 宽 高
                let metarial = new THREE.MeshBasicMaterial({  //材质
                    map: texture
                });
                let mesh = new THREE.Mesh(geometry, metarial); // 网格
                group.add(mesh);

                // 实例化渲染器 目标元素是canvas
                renderer = new THREE.WebGLRenderer({
                    canvas: canvas,
                    antialias: true
                });
                // 渲染器 尺寸
                renderer.setSize(window.innerWidth, window.innerHeight);
                // 渲染器 渲染
                // renderer.render(scene, camera);
                // 监听 鼠标移动
                document.addEventListener('mousemove', onDocumentMouseMove, false);
            })
        }

在构建3D地球视图时,我们首先创建了一个60度视野角的透视相机(THREE.PerspectiveCamera),模拟人类视觉,并根据浏览器窗口尺寸设定宽高比以确保渲染比例正确。摄像机放置在距离原点500单位处,保证地球既不因过近而失真也不因过远而模糊。

场景设为所有3D对象的空间容器,并设定了白色背景色以突出地球模型。使用THREE.Group组织多个物体,便于统一管理和操作。通过THREE.TextureLoader异步加载地球纹理,完成后调用回调函数构建地球模型。采用THREE.SphereGeometry创建球体几何体,定义其大小和表面细节,形成逼真的地球表面。

为了保持视觉真实性同时简化渲染,选择了直接显示纹理的THREE.MeshBasicMaterial材质类型。网格(Mesh)作为几何体和材质的组合,代表实际绘制的对象。使用THREE.WebGLRenderer将3D场景转换为2D图像,指定<canvas>元素为渲染目标并开启抗锯齿功能,提升视觉质量。

最后,通过绑定鼠标移动事件监听器,允许用户拖动鼠标改变地球视角,增强了交互体验。

3. 鼠标事件
function onDocumentMouseMove(event) {
            mouseX = (event.clientX - windowHalfx);
            mouseY = (event.clientY - windowHalfy);
        }

每当鼠标在页面上移动时,都会触发这个函数,更新mouseXmouseY变量,这两个变量用于存储鼠标相对于屏幕中心的偏移量。注意,我们对mouseY取反,这是因为通常情况下,屏幕坐标系的Y轴向下为正,而在Three.js中,Y轴向上为正,所以需要调整一下符号以匹配用户的直觉。

4. 地球转起来的关键
function animate() {
            // 递归 屏幕的刷帧率 60帧/s
            requestAnimationFrame(animate);
            reder()
        }
        function reder() {
            // 渲染器 渲染
            camera.position.x += (mouseX -camera.position.x) * 0.05;
            camera.position.y += (mouseY -camera.position.y) * 0.05;
            camera.lookAt(scene.position)
            group.rotation.y += 0.005;
            renderer.render(scene, camera);
        }
  • 动画循环requestAnimationFrame是一个浏览器API,它会在下一次重绘前调用指定的回调函数,在这里是animate函数本身。这形成了一个无限循环,保证了每秒钟大约60次的刷新率,从而实现了平滑的动画效果。
  • 相机跟随:在render函数内部,我们通过逐步调整相机的位置来响应鼠标的移动。0.05是一个阻尼系数,它控制了相机跟随速度,使得运动更加自然流畅。
  • 自转效果:为了让地球看起来像是在旋转,我们持续增加group的Y轴旋转角度。每次增加0.005弧度(约等于0.286度),这样的速率既不会太快也不会太慢,给人一种稳定而真实的转动感。
  • 渲染命令:最后一步是调用renderer.render()方法,告诉Three.js去绘制当前场景。它接受两个参数——场景和相机,分别表示要渲染的内容和从哪个视角观察。

综上所述,这些技术细节共同作用,确保了3D地球模型不仅视觉上引人入胜,而且操作起来也十分顺滑自然,真正做到了技术和艺术的完美结合。

结语

感谢你的阅读,期待你在Three.js的世界中创造出更多精彩的作品! 15.jpg