我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!
声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。
背景
近期工作有涉及到数字大屏的需求,于是利用业余时间,结合 Three.js
和 CSS实现赛博朋克2077风格视觉效果 实现炫酷 3D
数字地球大屏页面。页面使用 React + Three.js + Echarts + stylus
技术栈,本文涉及到的主要知识点包括:THREE.Spherical
球体坐标系的应用、Shader
结合 TWEEN
实现飞线和冲击波动画效果、dat.GUI
调试工具库的使用、clip-path
创建不规则图形、Echarts
的基本使用方法、radial-gradient
创建雷达图形及动画、GlitchPass
添加故障风格后期、Raycaster
网格点击事件等。
效果
如下图 👇
所示,页面主要头部、两侧卡片、底部仪表盘以及主体 3D
地球 🌐
构成,地球外围有 飞线
动画和 冲击波
动画效果 🌠
,通过 🖱
鼠标可以旋转和放大地球。点击第一张卡片的 START
⬜
按钮会给页面添加故障风格后期 ⚡
,双击地球会弹出随机提示语弹窗。
💻
本页面仅适配PC
端,大屏访问效果更佳。👁🗨
在线预览地址1:3d-eosin.vercel.app/#/earthDigi…👁🗨
在线预览地址2:dragonir.github.io/3d/#/earthD…
码上掘金
实现
📦
资源引入
引入开发必备的资源,其中除了基础的 React
和样式表之外,dat.gui
用于动态控制页面参数,其他剩余的主要分为两部分:Three.js相关, OrbitControls
用于镜头轨道控制、TWEEN
用于补间动画控制、mergeBufferGeometries
用户合并模型、EffectComposer
RenderPass
GlitchPass
用于生成后期故障效果动画、 lineFragmentShader
是飞线的 Shader
、Echarts相关按需引入需要的组件,最后使用 echarts.use
使其生效。
1 | js复制代码import './index.styl'; |
📃
页面结构
页面主要结构如以下代码所示,.webgl
用于渲染 3D
数字地球;.header
是页面顶部,里面包括时间、日期、星际坐标、Cyberpunk 2077 Logo
、本人 Github
仓库地址等;.aside
是左右两侧的图表展示区域;.footer
是底部的仪表盘,展示一些雷达动画和文本信息;如果仔细观察,可以看出背景有噪点效果,.bg
就是用于生成噪点背景效果。
1 | js复制代码<div className='earth_digital'> |
🔩
场景初始化
定义一些全局变量和参数,初始化场景、相机、镜头轨道控制器、页面缩放监听、添加页面重绘更新动画等进行场景初始化。
1 | js复制代码const renderer = new THREE.WebGLRenderer({ |
🌐
创建点状地球
具体思路是使用 THREE.Spherical
创建一个球体坐标系 〽
,然后创建 10000
个平面网格圆点,将它们的空间坐标转换成球坐标,并使用 mergeBufferGeometries
将它们合并为一个网格。然后使用一张如下图所示的地图图片作为材质,在 shader
中根据材质图片的颜色分布调整圆点的大小和透明度,根据传入的参数调整圆点的颜色和大小比例。然后创建一个球体 SphereGeometry
,使用生成的着色器材质,并将它添加到场景中。到此,一个点状地球 🌐
模型就完成了,具体实现如下。
1 | js复制代码// 创建球类坐标 |
🔧
添加调试工具
为了实时调整球体的样式和后续飞线和冲击波的参数调整,可以使用工具库 dat.GUI
。它可以创建一个表单添加到页面,通过调整表单上面的参数、滑块和数值等方式绑定页面参数,参数值更改后可以实时更新画面,这样就不用一边到编辑器调整代码一边到浏览器查看效果了。基本用法如下,本例中可以在页面通过点击键盘 ⌨
H键显示或隐藏参数表单,通过表单可以修改 🌐
地球背景色、飞线颜色、冲击波幅度大小等效果。
1 | js复制代码const gui = new dat.GUI(); |
📌
如果想要了解更多关于dat.GUI
的属性和方法,可以访问本文末尾提供的官方文档地址
💫
添加飞线和冲击波
这部分内容实现地球表层的飞线和冲击波效果 🌠
,基本思路是:使用 THREE.Line
创建 10
条随机位置的飞线路径,通过 setPath
方法设置飞线的路径 然后通过 TWEEN
更新飞线和冲击波扩散动画,一条动画结束后,在终点的位置基础上重新调整飞线开始的位置,通过更新 Shader
参数 实现飞线和冲击波效果,并循环执行该过程,最后将飞线和冲击波关联到地球 🌐
上,具体实现如以下代码所示:
1 | js复制代码let maxImpactAmount = 10, impacts = []; |
添加动画过渡效果
1 | js复制代码for (let i = 0; i < maxImpactAmount; i++) { |
📟 创建头部
头部机甲风格的形状是通过纯 CSS
实现的,利用 clip-path
属性,使用不同的裁剪方式创建元素的可显示区域,区域内的部分显示,区域外的隐藏。
1 | stylus复制代码.header |
📌
如果想了解关于clip-path
的更多知识,可以访问文章末尾提供的MDN
地址。
📊 添加两侧卡片
两侧的 卡片
🎴
,也是机甲风格形状,同样由 clip-path
生成的。卡片有实心、实心点状背景、镂空背景三种基本样式。
1 | stylus复制代码.box |
卡片上的图表 📊
,直接使用的是 Eachrts
插件,通过修改每个图表的配置来适配 赛博朋克 2077
的样式风格。
1 | js复制代码const chart_1 = echarts.init(document.getElementsByClassName('chart_1')[0], 'dark'); |
📌
Echarts
图标使用不是本文重点内容,想要了解更多细节内容,可访问其官网。
⏱
添加底部仪表盘
底部仪表盘主要用于数据展示,并且添加了 3
个雷达扫描动画,雷达 📡
形状则是通过 radial-gradient
径向渐变来实现的,然后利用 ::before
和 ::after
伪元素实现扫描动画效果,具体 keyframes
实现可以查看样式源码。
1 | stylus复制代码.radar |
🤳
添加交互
故障风格后期
点击第一个卡片上的按钮 START
⬜
,星际之旅进入 Hard 模式
😱
,页面将会产生如下图所示的故障动画效果。它是通过引入 Three.js
内置的后期通道 GlitchPass
实现的,添加以下代码后,记得要在页面重绘动画中更新 composer
。
1 | js复制代码const composer = new EffectComposer(renderer); |
地球点击事件
使用 Raycaster
给地球网格添加点击事件,在地球上 双击鼠标
🖱
,会弹出一个提示框 💬
,并会随机加载一些提示文案。
1 | js复制代码const raycaster = new THREE.Raycaster(); |
🎥
添加入场动画等其他细节
最后,还添加了一些样式细节和动画效果,如头部和两侧卡片的入场动画、头部时间坐标文字闪烁动画、第一张卡片按钮故障风格动画、Cyberpunk 2077 Logo
的阴影效果等。由于文章篇幅有限,不在这里细讲,感兴趣的朋友可以自己查看源码学习。也可以查看阅读我的另一篇文章 仅用CSS几步实现赛博朋克2077风格视觉效果 > 传送门 🚪
查看更多细节内容。
总结
本文包含的新知识点主要包括:
THREE.Spherical
球体坐标系的应用Shader
结合TWEEN
实现飞线和冲击波动画效果dat.GUI
调试工具库的使用clip-path
创建不规则图形Echarts
的基本使用方法radial-gradient
创建雷达图形及动画GlitchPass
添加故障风格后期Raycaster
网格点击事件等
后续计划:
本页面虽然已经做了很多效果和优化,但是还有很多改进的空间,后续我计划更新的内容包括:
🌏
地球坐标和实际地理坐标结合,可以根据经纬度定位到国家、省份等具体位置💻
缩放适配不同屏幕尺寸📊
图表以及仪表盘展示一些真实的数据并且可以实时更新🌠
头部和卡片添加一些炫酷的描边动画🌟
添加宇宙星空粒子背景(有时间的话,现在的噪点背景也不错)🐌
性能优化
想了解其他前端知识或其他未在本文中详细描述的
Web 3D
开发技术相关知识,可阅读我往期的文章。转载请注明原文地址和作者。如果觉得文章对你有帮助,不要忘了一键三连哦 👍。
附录
- 我的3D专栏可以点击此链接访问 👈
- [1]. 🦊 Three.js 实现3D开放世界小游戏:阿狸的多元宇宙
- [2]. 🔥 Three.js 火焰效果实现艾尔登法环动态logo
- [3]. 🐼 Three.js 实现2022冬奥主题3D趣味页面,含冰墩墩
...
- [1]. 📷 前端实现很哇塞的浏览器端扫码功能
- [2]. 🌏 前端瓦片地图加载之塞尔达传说旷野之息
- [3]. 😱 仅用CSS几步实现赛博朋克2077风格视觉效果
...
参考
- [1]. threejs.org
- [2]. github.com/dataarts/da…
- [3]. echarts.apache.org/zh/index.ht…
- [4]. www.cnblogs.com/pangys/p/13…
- [5]. developer.mozilla.org/zh-CN/docs/…
- [6]. developer.mozilla.org/zh-CN/docs/…
本文转载自: 掘金