最前端|注意看!我用代码写了一个会动的3D地球

这篇具有很好参考价值的文章主要介绍了最前端|注意看!我用代码写了一个会动的3D地球。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、文章背景

二、实现方式

(一)方案

(二)实现细则

三、总结


一、文章背景

在我们负责的某个项目中有一个需求,其展馆的可视化大屏首屏需要 3D 地球作为载体,来展示各国贸易额的信息,因此催生了 3D 地球的需求。需求的侧重点更多在于美观,动态方面,对于数据展示层面的需求反而并不多。

基于这个3D地球的实现有了这篇文章。

最前端|注意看!我用代码写了一个会动的3D地球,前端开发,前端,3d,数据可视化

最终呈现效果展示

二、实现方式

(一)方案

  1. 通过 Three.js 画出球体
  2. 将准备好的地球纹理材质包导入并覆盖在球体上形成地球
  3. 通过设置光源形成光暗变化
  4. 通过旋转球体使其运动
  5. 飞线实现

(二)实现细则

//Step 1 创建地球

vargeometry = newTHREE.SphereGeometry(radius,radius,radius); // 创建球体模型
varloader = newTHREE.TextureLoader(); // 创建资源加载器
loader.load('./map.png', function(texture){ // 加载地球材质图片 参数为回调函数
varmaterial = newTHREE.MeshLambertMaterial( { map: texture } ); // 创建面材质并加入到屏中
global= newTHREE.Mesh(geometry, material)
scene.add( global)
})

//Step 2 设置光源

varpoint = newTHREE.PointLight(0xffffff);
point.position.set(400, 200, 300);
scene.add(point);

varambient = newTHREE.AmbientLight(0x444444);
scene.add(ambient);

point为点光源,特点是从一点开始往不同方向发散且不产生阴影。一般用来作为主光源。ambient为散射光,即笼罩在环境的光,一般用来作为主色调。详情可参考:初识ThreeJS中常见的光源

//Step 3 动画实现

functionanimate(){
requestAnimationFrame(animate);
if(global) {
global.rotation.y += 0.005;
}

renderer.render(scene, camera);
}

通过不断的增加球体的 y 轴使其不停的逆时针旋转

//Step 4 飞线实现

飞线的实现较为复杂,且方案较多,本文提供的方案并不一定是最优解,仅作为一种思路参考

1、数据准备

//mock数据
functionrandomLine(lineNum) {
constmockData = [];
Array.from({ length: lineNum }, (v, k) =>{
mockData.push({
line: [randomPos(), randomPos()],
});
});
returnmockData;
}

functionrandomPos() {
return[Math.random() * 360- 180, Math.random() * 180- 90];
}

randomPos 可以随机生成球体上的经纬度点,两点则生成一条线的基本轨迹。

functioncreatePosition(lnglat) {
constspherical = newTHREE.Spherical();
spherical.radius = 60;
constlng = lnglat[0];
constlat = lnglat[1];
consttheta = (lng + 90) * (Math.PI / 180);
constphi = (90- lat) * (Math.PI / 180);
spherical.phi = phi;
spherical.theta = theta;
constposition = newTHREE.Vector3();
position.setFromSpherical(spherical);
returnposition;
}

此方法将经纬度转换为屏幕中的空间坐标,实现方式是通过 Three.js 提供的setFromSpherical方法,提供球体半径以及经纬度则可以计算出空间坐标。

2、弧线计算

对于一条线来分析,我们得到了线的起点跟终点的坐标还不够。我们需要得到的是从起点到终点的绕着地球表面的弧线。要保证不与地球相交穿模且弧线优美。弧线的生成方法是通过 Three.js 提供的CatmullRomCurve3这个生成曲线来实现的,参数是多个表示顶点坐标的 Vector3 对象组成的数组 Array,我们至少要提供 8 个顶点坐标才能保证线条走向与我们的期待值一致。

这里使用的是二分法:

functiongetSplinePoints(positions) {
const[start, end] = positions;
constpoints = [];
points[0] = newTHREE.Vector3(start.x, start.y, start.z);

points[8] = newTHREE.Vector3(end.x, end.y, end.z);
constgetPoint = (point1, point2) =>{
consttempMiddle = newTHREE.Vector3(
0.5* (point1.x + point2.x),
0.5* (point1.y + point2.y),
0.5* (point1.z + point2.z)
);
consttempMiddleLength = Math.sqrt(
tempMiddle.x ** 2+ tempMiddle.y ** 2+ tempMiddle.z ** 2
);
constrate = (radius + 10) / tempMiddleLength;
constmiddle = newTHREE.Vector3(
rate * tempMiddle.x,
rate * tempMiddle.y,
rate * tempMiddle.z
);
returnmiddle;
};

points[4] = getPoint(points[0], points[8]);
points[2] = getPoint(points[0], points[4]);
points[1] = getPoint(points[0], points[2]);
points[3] = getPoint(points[2], points[4]);
points[6] = getPoint(points[4], points[8]);
points[5] = getPoint(points[4], points[6]);
points[7] = getPoint(points[6], points[8]);

returnpoints;
}

点的计算方式是先计算出两点的中点位置,再通过勾股定理计算出球体中心点到中点的斜边长,然后通过球体半径再加上我们设置的飞线距离球体的高度等比延伸计算出我们需要的位置。通过传入的起点和终点先确定第 4 个点的位置,然后通过起点和第四个点确定第二个点位置,依此类推,计算出 8 个点的坐标。然后调用CatmullRomCurve3即可得到弧线。

3、弧线生成

constlineBallList = newTHREE.Object3D();
constlineCurve = newTHREE.CatmullRomCurve3(
getSplinePoints(positions),
false
);
constlineGeometry = newTHREE.BufferGeometry();
constpoints = lineCurve.getPoints(50);
lineGeometry.setFromPoints(points);
constmatericalLine = newTHREE.LineBasicMaterial({ color });
constline = newTHREE.Line(lineGeometry, matericalLine);

for(letballIndex = 0; ballIndex < 100; ballIndex += 1) {
constballGeomtry = newTHREE.SphereGeometry(0.3);
constmaterialBall = newTHREE.MeshBasicMaterial({
color,
transparent: true,
opacity: 1- ballIndex / (100+ 10),
});
constlineBall = newTHREE.Mesh(ballGeomtry, materialBall);
lineBall.originOpacity = 1- ballIndex / (100+ 10);
lineBallList.add(lineBall);
}

lineCurve.getPoints(50)这个方法指定了一条弧线上具体生成多少个点,此方法会返回生成的点集。50 这个数字是需要通过具体需求调试的,对性能以及效果的影响很大。代码中的 color 是一个变量,这样可以实现不同线条颜色不同。最后我们通过循环点,给每一个点加上透明度渐变的材质包,就得到了一段慢慢变淡的拖着长尾巴的彗星状弧线。

4、动起来

functionanimate(){
requestAnimationFrame(animate);
constlineBalls = globalLineBalls.children;
lineBalls.forEach((balls) => {
constballCurve = balls.curve;
constballList = balls.children;
constballPos = balls.pos;
if(ballPos < 1.2) {
ballList.forEach((ball, index) => {
constnewPos =
ballPos - index * 0.002> 0? ballPos - index * 0.002: 0;
if(newPos >= 1) {
ball.opacity = 0;
} else{
ball.opacity = ball.originOpacity;
constballPosition = ballCurve.getPointAt(newPos);
ball.position.x = ballPosition.x;
ball.position.y = ballPosition.y;
ball.position.z = ballPosition.z;
}
ball.neepsUpdate = true;
});
balls.pos = ballPos + 0.008;
} else{
balls.pos = 0;
}
});
renderer.render(scene, camera);
}

这里的思路是设置了隐性的参数值pos,通过维护pos的数值大小来决定展示哪些点。

三、总结

通过上述案例,相信大家已经对数据可视化的思路和实现方式有了初步的了解。然而,实际的实现过程往往是复杂的,因为数据可视化涉及到许多数学问题。在解决这些问题时,我们可以尝试先建立模型,建立坐标系来分析具体问题,从而找到解决方案。数据可视化是一个既有挑战性又有创造性的领域,希望通过不断学习和实践,我们能够更好地应对和解决数据可视化中的难题。

版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。
公众号搜索神州数码云基地,了解更多技术干货。文章来源地址https://www.toymoban.com/news/detail-709145.html

到了这里,关于最前端|注意看!我用代码写了一个会动的3D地球的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • UE4材质(七):世界场景位置偏移——会动的材质

    摘自并整理自虚幻官方教程:https://learn.unrealengine.com/course/2449699 课程中的工程项目文件下载: 链接:https://pan.baidu.com/s/1o7m3pR7BvaCYAmlx57B9HQ 提取码:uenb 官方解释:世界位置偏移(World Position Offset) 输入允许网格体的顶点在世界空间中由材质操纵。这有助于实现使对象移动、

    2023年04月08日
    浏览(23)
  • MATLAB | 龙年大吉,使用MATLAB绘制会动的中国风神龙

    hey各位好久不见,龙年到了,这期画一期配色非常中国风的龙,这个造型的龙参考了某些html绘制龙的视频,但是由于html版全网都是也不咋给代码和代码出处,因此自己写了个MATLAB版本: 可以看到还是非常酷炫的! 代码原理非常简单,就是龙跟着鼠标走嘛,不就是加强版的贪

    2024年01月18日
    浏览(28)
  • 我用GPT-3.5写了一个关于C++排序的博客,大家看看和我手写的哪一个好

    手写版:你还不懂排序?那是你没看到这篇文章…_我爱OJ的博客-CSDN博客 以下内容来自GPT-3.5大模型: 目录 一、排序算法的基本概念 二、比较排序算法 1、冒泡排序 C++代码实现 2、选择排序 C++代码实现 3、插入排序 C++代码实现 4、希尔排序 C++代码实现 5、归并排序 C++代码实现

    2024年02月03日
    浏览(44)
  • 海王必备,我用python写了一个微信机器人和她聊天之后把我拉黑了

    事情是这样的,最近认识的一位小姐姐有每天早晨看天气预报的习惯。在我看来,很多人起床第一件事情就是看微信消息,既然这样,我就勉为其难每天早晨给小姐姐发送一则天气预报吧。 开始几天,我是使用很原始的方法,自己去获取天气预报截图,再手动发送给小姐姐。

    2023年04月21日
    浏览(31)
  • 怎么迅速做出高端、还会动的数据图表?来看看这五个大数据可视化神器!

    其实很简单。大数据可视化就是指通过 图表、图形、地图等视觉化方式 , 将庞大、复杂的大数据集合转化为直观、易于理解和分析的图像展示。 它的目的是 帮助人们更好地理解和解释大数据,发现数据中的模式、趋势和关联,从而支持决策和洞察。 大数据可视化可以将抽

    2024年02月13日
    浏览(30)
  • 【python】我用python写了一个可以批量查询文章质量分的小项目(纯python、flask+html、打包成exe文件)

    web 效果预览: 先去质量查询地址:https://www.csdn.net/qc 输入任意一篇文章地址进行查询,同时检查页面,在Network选项下即可看到调用的API的请求地址、请求方法、请求头、请求体等内容: 请求头里面很多参数是不需要的,我们用 ApiPost 这个软件来测试哪些是必要参数。 经过

    2024年02月13日
    浏览(25)
  • 深入分析物理引擎后,他写了一个轻量的 Cocos 3D 碰撞检测优化方案

    引言: 碰撞检测是游戏开发中一个非常重要的技术点,优化碰撞检测性能,是提升游戏体验不可或缺的一环。开发者「我叫98K」写了一个轻量碰撞系统,用以改善 3D 游戏在不同平台遇到的碰撞性能问题和包体问题。下载和在线体验地址见文末。 98K物理-轻量碰撞系统是一个高

    2024年02月03日
    浏览(27)
  • 我用chatgpt写了一篇关于2023 it 行业的发展的论文……

    我用chatgpt写了一篇关于2023 it 行业的发展的论文。我将从以下几个方面来探讨2023年IT行业的发展: 1.云计算技术在IT行业的应用:随着云计算技术的发展,2023年IT行业将受益于云计算技术在数据存储、计算能力和安全性方面的优势。 2.大数据技术在IT行业的应用:大数据技术的

    2024年02月07日
    浏览(35)
  • 花30分钟,我用ChatGPT写了一篇2000字文章(内附实操过程)

    有了ChatGPT之后,于我来说,有两个十分明显的变化: 1. 人变的更懒 因为生活、工作中遇到大大小小的事情,都可以直接找ChatGPT来寻求答案。 2. 工作产出量更大 之前花一天,甚至更久才能写一篇原创内容,现在有了主题、框架之后,ChatGPT 30分钟就能给我一篇「水准之上」

    2024年02月07日
    浏览(43)
  • ChatGPT教我用200行代码写一个简版Vue框架 - OpenTiny

    最近,我正在准备一份关于 Vue 基础的学习材料。期间我突发奇想:能否利用现在热门的 ChatGPT 帮我创建学习内容?其实 Vue 本身不难学,特别是基础用法,但是,如果你想深入掌握 Vue,就要通过阅读 Vue 的源码来了解其原理。然而,不是每个人都有足够的时间和耐心阅读 V

    2024年02月08日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包