极光高级工程师——曾晖腾
前言
在5G技术刚出来,站在风口上的时候,好家伙,那简直铺天盖地,万物都可以5G,那时不少前端人都相信5G就是前端的未来。那时刚实习的我是看不懂的,但内心大受震撼,就在想啊,这5G究竟跟前端有啥关系呢?想了半天,晚上是横竖睡不着,是真睡不着,只能从这字缝间看出来两个字,“加班”。
哈哈,以上是活跃气氛的笑话一则,其实下一代的通信技术对我们的日常生活是会带来很大的积极影响的。数据大屏也一直在发展,一直在为摆脱华而不实的标签而努力着,为的就是突出数据的价值这件事。
回到开发中来,假如我们需要实现一款能适配所有屏幕的数据大屏应用要怎么做呢?我们先来看看几个实现方案拓展一下思路。
市面上的方案
直接使用width百分比做适配
这种方案需要精确计算出对应百分比的值,通常这个值并不好算,而且很多时候需要给出一个确定的高度。这样的做法不是说不行,只能说现在已经2021年了,有许多比这个更好的实现方案。
使用@media媒体查询适配各种屏幕
在刚接触css3的媒体查询时就觉得这个属性太及时了,刚好对应上了移动智能机的普及,给不同屏幕的适配提供了一个很不错的解决方案。但媒体查询中设置的'断点'是离散的,实际应用中可能会对大屏界面造成一些拉伸,不能按百分百按比例显示出界面。而且要写的适配样式将会很多,有点费手。
使用postcss在打包编译时将px经过一系列计算转换成rem来实现适配
这个方案本质上是用到了rem这个相对长度单位的特性,例如页面根元素的字体大小为16px,那么这时1rem就等于16px。当然页面根元素的默认值就是16px,如果我们设置为12px,那么这时1rem就等于12px。
这个时候我们可以知道,设计稿的高宽是固定的,而屏幕的高宽的会变的。但是我们可以算出设计稿与屏幕的比例。这样可以推算出以下这个关键公式:
实际屏幕显示的某元素宽度 = (实际屏幕宽度 / 设计稿宽度) * 设计稿中某元素的宽度
在项目配置中,我们将实际屏幕与设计稿的比例应用到页面根元素中,如果这个比例是1/2即0.5,那么此时1rem就等于8px,然后在postcss中配置根元素字体大小为8px,这样在代码的开发中,就是直接使用设计稿所标注的尺寸了。
postcss需要如下配置
不过这个方案有个问题,就是虽然能按比例显示还原设计稿,但屏幕高宽变了怎么办?postcss的配置是在打包编译过程中转换相关的rem单位的,所以无法应对这种情况。
综上以上几种方法有的不够直观,有的很难维护,有的无法适配所有的屏幕。那么有没有一种方法能很好的解决这一系列问题呢?答案是有的,我们需要结合现实情况对第三中方案作出一些改进,我们先来看看需要实现的效果。
需要实现的效果
能适配所有比例的屏幕
一比一无损还原设计稿,无论是比例还是尺寸
方便维护,最好能直接用设计稿里标注的数值
分析
要达到这样的效果,我们需要移除在编译阶段对单位的相关转换,这样才能动态去计算相关的转换。而且有时宽度填满屏幕的时候,为了保持比例不变,高度不一定等填充满屏幕的高度,反之高度填满屏幕的时候,宽度也不一定能填充满,这些情况都是需要考虑到的。
统一数值转换
经过上面的铺垫,不难发现其实页面根元素的fontSize可以直接当做一个比例,观察以下变换,如果这个比例时1000/2000即0.5,那么此时根元素fontSize设置成0.5px,1rem等于0.5px。这样如果设计稿中某个元素的尺寸是2000px,那么在代码中我们可以设置成2000rem。这样在实际屏幕上显示的就是2000*0.5=1000px。完美,能直接使用设计稿的数值,虽然写的时候单位要换一下。
考虑到高度或者宽度填不满屏幕的情况,我们可以加一些判断补充一下。
在高度或者宽度填不满屏幕时,空白的部分可以考虑使用同一主题色或背景去填充。
到这里适配基本就做好了,但是除了还原尺寸比例之外,相关的动画特效也是很重要的组成部分。
svg组件与动画
在大屏应用当中,是建议尽量使用svg矢量图的,这样可以彻底避免分辨率的问题,而且svg图在动画特效里也有很重要的作用。
例如下面是一段svg组件里path标签的设置,其中containerBox绑定onSize事件,这样path可以根据内容的尺寸,动态调整边框的大小。
其中strokeDasharray,strokeDashoffset这两天属性是控制边框动画的关键。
这个动画帧的效果比较简单,只是一个高亮沿边框流动的鎏金效果。如果是一些复杂的动画可以使用TimelineLite/TimelineMax等时间轴工具去创建。
结语
到此为止,编写一个数据大屏应用似乎并不是一件困难的事,要达到的效果已经全部实现,再开发相关的大屏产品时就不用为相关的问题发愁了。当然这里仅限于2D纯展示类的大屏应用,如果是3D可交互的数据应用就是另一个话题了。