一、背景
过去经历的几个DataV大屏项目都是“门面项目”,主要界面就是展示介绍信息和图表数据,甚至有些还是仿真数据。这种情况下使用阿里云DataV其实相当方便。只需要UI设计完切图,在阿里云素材库中上传对应文件。然后在可视化界面中拖拉拽即可。
阿里云DataV操作界面
但如果存在以下需求时,阿里云DataV就不太适合了:
- 数据源涉及到数据接口转换,或者调用第三方SDK;
- 轮播区域(如图表、区块等)未提供现成组件;
- 存在一定交互效果的项目(点击放大、移入移出效果等);
主要的原因是虽然可视化提升了大屏开发的直观性和易用性,但是又在上述需求点时大大增加操作复杂性。所以当需求覆盖以上1~3项时,使用阿里云DataV开发就有些痛苦了。
二、自研
在团队内部我们主要参考DataV-Team/DataV、阿里云DataV项目,以Vue2为基础设计了一套大屏开发模板。因为是团队内部开发者使用,所以没有去考虑可视化操作的界面。在项目告一段落后,分享下
2.1 布局定位
整体的布局定位参考了阿里云DataV,借助Position定位来实现,通过配置x(left)、y(top)来控制元素展示位置(例如x="1"
就会转换为css的left: 1px
)。
如果在项目中有用到蓝湖等工具的话,获取元素的位置就会方便的多。
蓝湖的右侧面板里提供了相应数据
但需要注意是,如果多个div之间嵌套,Position是基于父元素的定位,此时通过蓝湖的位置信息去设置就会发现位置错位了。
2.2 缩放
我们采用了CSS的Scale属性来控制不同屏幕间的缩放,这种方式相比flex自适应布局,在固定比例的屏幕上显示效果极好(缺点是在非固定比例下可能会出现无法铺满全屏,如果投屏设备硬要拉伸显示就会显示的很不协调)。
|
Flex |
Css Scale |
屏幕适配 |
任意尺寸 |
固定尺寸 |
UI效果 |
存在拉伸变形情况 |
几乎完全一致 |
宽高适配 |
需要额外设置元素的宽高限制 |
无需额外配置 |
开发量 |
多 |
适中 |
特点 |
能满足不同比例的屏幕,但是显示效果不一定好 |
满足单一比例屏幕,显示效果好 |
例如按16:9的比例去做一个2K分辨率的大屏,之后屏幕尺寸即使变为1080P、4K都可以通过Scale进行完美的放大缩小,确保展示效果一致。
在固定比例下可以完美放大缩小
如果换到了其他比例的屏幕中,也可以根据铺满宽度或者铺满高度尽可能的实现占满屏幕。
效果示例
2.3 组件
根据实际业务需求,我们把基础组件分为了五类:基础类、表格类、媒体类、信息类、图表类。下列组件已基本满足现有业务,并承建了几个数据大屏项目。
2.4 属性
这里拿容器组件举个例子,在页面中使用时是这样的:
1 2 3 4 5 6 7 8 9
| <node-container x="100" y="100" width="5472" height="2160" opacity="70" > 其他内容... </node-container>
|
而在node-container
组件内部,其实是以css style的形式存在的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| <template> <div class="node-container" :style="{ left: leftProperty, top: topProperty, width: widthProperty, height: heightProperty, opacity: opacityProperty, zIndex: zIndexProperty }" > <slot/> </div> </template>
<script> export default { props: { x: { type: [Number, String], default: 0 }, y: { type: [Number, String], default: 0 }, width: { type: [Number, String], default: 0, }, height: { type: [Number, String], default: 0, }, opacity: { type: Number, default: 1, }, zIndex: { type: Number, default: 10 } }, computed: { leftProperty () { return isNaN(this.x) ? this.x : `${this.x}px` }, topProperty () { return isNaN(this.y) ? this.y : `${this.y}px` }, widthProperty () { return isNaN(this.width) ? this.width : `${this.width}px` }, heightProperty () { return isNaN(this.height) ? this.height : `${this.height}px` }, opacityProperty () { return this.opacity }, zIndexProperty () { return this.zIndex } } } </script>
|
随着组件数量的增加,这些重复的属性值就会越来越多。所以我们又进行了一次mixins封装,根据对应的css属性类型拆分成了NodeProps
、TextProps
、FontProps
等mixins混入类。
三、问题
在项目实施过程中也遇到了一些非技术方面的问题,感觉在沟通层面确实还存在不足,导致最终效果不佳。
3.1 提供的屏幕尺寸有误
对方提供的大屏尺寸与实际投屏尺寸不一致,导致比例出现变化。由于对方的大屏是由18块显示器屏幕组合而成,而硬件处理时仅有中间12块显示器屏幕可以组成一块大屏,边缘六块显示器屏幕都是正常比例显示投屏内容。
只有⑦的位置可以组合成大屏
然后临时将大屏设置为铺满高度,解决了该问题。
高度铺满时内容居中展示,两侧空白区域会填充页面背景色
3.2 LED屏幕显示效果差
另一块LED屏幕投屏出来的效果整体偏暗,导致有一些渐变效果基本看不出来。只能看出几个主色调颜色。这个受限于硬件原因没有办法解决,只能在后续项目中要求UI设计师加大色调的对比度。
LED屏幕示例