前端可玩性UP项目:大屏布局和封装
前言
autofit.js 发布马上要一年了,也收获了一批力挺用户,截至目前它在github上有1k 的 star,npm 上有超过 13k 的下载量。
这篇文章主要讲从设计稿到落地开发大屏应用,大道至简,这篇文章能帮助各位潇洒自如的开发大屏。
分析设计稿
分析设计稿之前先吐槽一下大屏这种展现形式,这简直就是自欺欺人、面子工程的最直接的诠释,是吊用没有,只为了好看,如果设计的再不好看啊,这就纯纯是屎。在我的理解中,这就像把PPT放到了web端,仅此而已。
但是王哥告诉我:"你看似没有用的东西,其实都有用,很多想真正做出有用的产品的企业,没钱,就要先把面子工程做好,告诉别人他们要做一件什么事,这样投资人才会看到,后面才有机会发展。"
布局方案
上图展示了一个传统意义上且比较普遍的大屏形态,分为四个部分,分别是
头部
头部经常放标题、功能菜单、时间、天气
左右面板
左右面板承载了各种数字和报表,还有视频、轮播图等等
中间
中间部分一般放地图,这其中又分假地图(一张图片)、图表地图(如echarts)、地图引擎(如:leaflet、mapbox、高德、百度)。或者有的还会放3D场景,一般有专门的同事去做3D场景,然后导入到web端。
大屏的设计通常的分辨率是 1920*1080 的,这也是迄今为止应用最广泛的显示器配置,当然也有基于客户屏幕做的异形分辨率,这就五花八门了。
但是万变不离其宗,分辨率的变化不会影响它的基本结构,根据上面的图,我们可以快速构建结构代码
<div class='Box'>
<div class="header"></div>
<div class="body">
<div class="leftPanel"></div>
<div class="mainMap"></div>
<div class="rightPanel"></div>
</div>
</div>
上面的代码实现了最简单的上下(Box)+左右(body)的布局结构,完全不需要任何定位策略。
要实现上图的效果,只需最简单的CSS即可完成布局。
组件方案
大屏虽然是屎,但是是一种可玩性很强的项目,想的越复杂,做起来就越复杂,想的越简单,做起来就越简单。
可以疯狂封装炫技,因为大屏里面的可玩组件简直太多了,且涵盖的太全了,想怎么玩都可以,包括但不限于 各类图表库的封装(echarts、highCharts、vChart)、轮播图(swiper)、地图引擎、视频库(包括直播流)等等。
如果想简单,甚至可以不用封装,可以看到结构甚至简单到不用CSS几行就可以搭建出基本框架,只把header、leaftPanel、rightPanel、map封装一下就可以了。
这里还有一个误区,就是大家都喜欢把 大型的组件库 拉到大屏里来用,结果做完了发现好像只用了一个 toast 和一个下拉组件,项目打包后却增大了几十倍的体积,其实像这种简单的组件,完全可以手写,或者找小的独立包来用,一方面会减小体积,不至于让项目臃肿,另一方面可以锻炼自己的手写能力,这才是有必要的封装。
适配
目前主流的适配方案,依然是 rem 方案,其原理就是根据根元素的 font-size 自动计算大小,但是此方法需要手动计算 rem 值,或者使用第三方插件如postcss等,但是此方案还有一个弊端,就是无法向下兼容,因为浏览器中最小的文字大小是12px。
vh/vw方案就不再赘述了,原理基本和 rem/em 相似,都涉及到单位的转换。
autofit.js
主要讲一下使用 autofit.js 如何快速实现适配。
不支持的场景
首先 autofit.js 不支持 elementUI(plus)、ant-design等组件库,具体是不支持包含popper.js的组件,popper.js 在计算弹出层位置时,不会考虑 scale 后的元素的视觉大小,所以会造成弹出元素的位置偏移。
其次,不支持 百度地图,百度地图对窗口缩放事件没有任何处理,有同学反馈说,即使使用了resize属性,百度地图在和autofit.js共同使用时,也会有事件热区偏移的问题。而且百度地图使用 bd-09 坐标系,和其他图商不通用,引擎的性能方面也差点意思,个人不推荐在开发中使用百度地图。
然后一些拖拽库,如甘特图插件,可能也不支持,他们在计算鼠标位置时同样没有考虑 scale 后的元素的视觉大小。
用什么单位
不支持的单位:vh、vw、rem、em
让我诧异的是,老有人问我该用什么单位,主要徘徊在 px 和 % 之间,加群的同学多数是因为用了相对单位,导致留白了。不过人各有所长,跟着各位大佬我也学到了很多。
看下图
假如有两个宽度为1000的元素,他们内部都有一个子元素,第一个用百分比设置为 width:50%;left:1%
, 第二个设置为 wdith:500px;left:10px
。此时,只要外部的1000px的容器宽度不变,这两个内部元素在视觉上是一模一样的,且在实际数值上也是一模一样的,他们宽度都为500px,距离左侧10px。
但是如果外部容器变大了,来看一下效果:
在样式不变的情况下,仅改变外部容器大小,差异就出来了,由上图可知,50%的元素依然占父元素的一半,实际宽度变成了 1000px,距离左侧的实际距离变成了 20px。
这当然不难理解,百分比单位是根据 最近的、有确定大小的父级元素计算的。
所以,应该用什么单位其实取决于想做什么,举个例子:在1920*1080
基础上开发,中间的地图写成了宽度为 500px ,这在正常情况下,看起来没有任何问题,它大概占屏幕的 26%,当屏幕分辨率达到4096*2160
时,它在屏幕上只占 12%,看起来就是缩在一角。而当你设置宽度为26%时,无论显示器如何变化,它始终占屏幕26%。
autofit.js 所干的事,就是把1000px 变成了 2000px或者把2000px变成了1000px,并给它设置了一个合适的缩放大小。
图表、图片拉伸
背景或各种图片按需设置 object-fit: cover;
即可
图表如echarts一般推荐使用百分比,且监听窗口变化事件做resize()
结语
再次感慨,大道至简,事情往往没有那么复杂,祝各位前程似锦。
来源:juejin.cn/post/7344625554530779176