【广州前端实习日记】3d数据大屏的实现
先讲一下背景。我目前大四应届,在一家不知名机器人公司做前端实习生。然后为了2022.11月中国深圳数字交通大会和今后的运维工作。leader,产品老早就在筹划做一个全新的数据大屏。最近收到消息因为疫情的原因这个展会推后了。。。。本来火急火燎的任务就一下子可以慢慢做了,哈哈哈,摸鱼人狂喜。讲一下我们这个项目的人员配置。前端一个,后端一个,ui设计一个,3d建模人员一个。


然后是关于背景,这里我曾跟leader提出过用天空盒子。leader跟我说用天空盒子会丑到天际的。那么我们就需要一张炫酷的图片。图片那里ui已经给我提供好了,那么难点就是怎么把图片插入3d图层的背景中。其实就两行代码
接下来如果我们要使得3d模型可以滚动查看,拉动远近视角的话的话我们就需要threejs的OrbitControls,一些代码如下
重难点2:自适应问题

他都会在刷新后将你的canvas画布变成你的1.5倍。但是你的界面缩放又放大后他又会变回到原来的尺寸,着实头疼(具体原因不详,我个人猜测是slot重绘回流的时候顺序有点问题?)
后来为了解决这个问题,我就决定不用组件了。用原生html搭建出一个demo,最后再把3d界面放上去。下图的示例代码在这个链接:https://gitee.com/Electrolux/front-css-package/blob/master/%E5%8D%A1%E7%89%87/2/index.html

#前端开发实习##前端##前端实习#
先上一下这个项目的某一个界面的复现图。
然后简单说一下做这个项目的重难点吧
重难点1:首先是three这个库
首先很多操作是异步的。比如加载obj或者是fbx模型的时候。因此这里我们需要封装一些同步的方法。
同样用加载模型来做示例
重难点1:首先是three这个库
首先很多操作是异步的。比如加载obj或者是fbx模型的时候。因此这里我们需要封装一些同步的方法。
同样用加载模型来做示例
initModel(url) { return new Promise((resolve) => { new FBXLoader().load(url, (object) => { resolve(object); }); }); },
然后是关于背景,这里我曾跟leader提出过用天空盒子。leader跟我说用天空盒子会丑到天际的。那么我们就需要一张炫酷的图片。图片那里ui已经给我提供好了,那么难点就是怎么把图片插入3d图层的背景中。其实就两行代码
//设置透明化 this.renderer = new THREE.WebGLRenderer({ alpha: true }); //然后css 直接插入图片就可以了,类似于下面 document.body.style.cssText = `background-image: url("@/assets/bigdata/img/background.png") !important;`;
接下来如果我们要使得3d模型可以滚动查看,拉动远近视角的话的话我们就需要threejs的OrbitControls,一些代码如下
const controls = new OrbitControls(this.camera, this.renderer.domElement); // controls.target.set(120, 120, 0); controls.update();
重难点2:自适应问题
设计稿给我们的是3840*2160,那么这个时候如何做屏幕在自适应是一个问题,要在1920x1080或者8k的屏幕不会太走样。这是第二个问题。咱们知道已知的大屏自适应方案主要有两种。第一种是rem,第二种是scale。
前者计算公式如下
前者计算公式如下
个人感觉这方法实在麻烦。并且还有一个最大的缺陷。就是rem的方案对于1920及以上分辨率没有什么问题,但当切换到1266*668等小分辨率时,由于浏览器默认最小font-size为12px,所以会导致文字比理想效果更多大, 而如果我们要用echart这个库,由于这个库的文字是用px写死的,所以放大缩小的时候都会有问题
好了,这就是我为什么用scale来进行屏幕适配的一个原因,然后在用到这玩意的时候又有问题。一开始我是想用vue的slot并且封装一个组件来做这个的。通过slot组件的机制能够实现一个比较优雅的封装,但是我们这里用到的是threejs这玩意,你的3d画面是要渲染到你界面的一个canvas元素中。渲染调用的是three中的render,但是在实操的时候无论你的画布大小如何设置。例如下面
好了,这就是我为什么用scale来进行屏幕适配的一个原因,然后在用到这玩意的时候又有问题。一开始我是想用vue的slot并且封装一个组件来做这个的。通过slot组件的机制能够实现一个比较优雅的封装,但是我们这里用到的是threejs这玩意,你的3d画面是要渲染到你界面的一个canvas元素中。渲染调用的是three中的render,但是在实操的时候无论你的画布大小如何设置。例如下面
this.renderer.setSize(3840, 2160);
他都会在刷新后将你的canvas画布变成你的1.5倍。但是你的界面缩放又放大后他又会变回到原来的尺寸,着实头疼(具体原因不详,我个人猜测是slot重绘回流的时候顺序有点问题?)
后来为了解决这个问题,我就决定不用组件了。用原生html搭建出一个demo,最后再把3d界面放上去。下图的示例代码在这个链接:https://gitee.com/Electrolux/front-css-package/blob/master/%E5%8D%A1%E7%89%87/2/index.html
事实证明这是可行的,最后放一个自适应的demo代码示例上来:
https://gitee.com/Electrolux/front-css-package/tree/master/%E5%B8%83%E5%B1%80/%E6%97%A0%E6%95%8C%E8%87%AA%E9%80%82%E5%BA%94
好了这大概就是我做这个3d数据大屏某一个界面的一些思路。欢迎各位大佬交流
https://gitee.com/Electrolux/front-css-package/tree/master/%E5%B8%83%E5%B1%80/%E6%97%A0%E6%95%8C%E8%87%AA%E9%80%82%E5%BA%94
好了这大概就是我做这个3d数据大屏某一个界面的一些思路。欢迎各位大佬交流