企鹅电竞weex实践之UI篇
随着电竞业务的不断发展,页面功能越来越多,交互逻辑更加复杂,类似无限滚动、上拉刷新、横竖切换滚动等形式在业务中已是标配,经过重重优化后在H5中的体验一直达不到理想状态,没错,种种卡,H5的性能太差! 是持续优化还是破而后立选择新的技术方向呢?我们选择了更有效的后者。
为什么选择weex
相对H5来说,weex带来的用户体验更好,它结合了H5和Native各自的优势,既能像H5一样快速迭代,又能和Native一样流畅。
次尝试新方案、新技术时都将面临着许多问题,企鹅电竞接入weex也不例外,我们在使用weex进行设计还原时并不是像H5一样顺利,为了避免小伙伴重复踩坑,本文将主要围绕H5与weex的区别以及weex ui开发时遇到的问题进行说明。
本文将从以下几个方面对Weex进行介绍:
H5与Weex的区别
- 项目结构
- 标签
- 引入sass
- sass变量
weex ui开发踩坑
- 通用样式
- 布局
- 组件
- 动画
- UI性能
H5与Weex的区别
项目结构
由于weex和H5是两套不同的技术方案,代码组织方式、构建工具、和开发侧对接方式都会不同。
下图是电竞重构稿H5与weex目录结构对比,之前H5开发是基于jinja模版,采用grunt构建,在release中生成相应的html文件,而weex则主要在src中开发组件,采用webpack编译,最终会在dist中生成相对应地web和weex版jsbundle文件,再由weex.html生成的二维码查看weex版页面效果。
此外weex下的src目录内容是与开发侧保持一致的,这样的好处在于开发人员只需要关注组件的结构变化,其它资源直接更新替换即可。
标签
weex只提供了17个组件,如div、text、image等,其中text和H5中p标签等同,文字只能放到text下,text中不能嵌套其他标签。
引入sass
- 安装sass依赖的npm包:sass-loader、node-sass、sass-loader、stylus-loader。
- 在build文件夹下webpack.base.conf.js的rules里面添加配置。
rules:{{test: /\.(scss|css)$/,loader: 'vue-style-loader!css-loader!sass-loader!stylus-loader?indentedSyntax',}}er-width:$border.width;}
- style中修改lang=“stylus”
sass变量
weex中的sass变量类似于对象的写法:
//variable.scss
$border={
color: #E9E9E9
width:2px
}
@import "./variable.scss";
.border{
border-color:$border.color;
border-width:$border.width;
}
weex ui踩坑
通用样式
1、border
weex不支持使用border创建三角形,web可以正常显示,而ios和android上显示的是矩形,建议使用图片代替。
2、transform
1、rotate角度尽量避免设置负数,某些部分安卓机型会不生效。
2、不支持transform:skew 对于这一类角标需要做倾斜处理可以采用 图片加 渐变代码处理。
3、图片
1、weex提供了image组件,但只支持远程图片链接。
2、避免在image标签上使用v-for,否则会导致安卓上图片渲染异常(如slider中的图片)。
4、透明度
以下是涉及到颜色的相关属性对透明度的支持度列表。如图:
注意:box-shadow (本身不支持android),background-image不支持IOS透明。
5、点击态
项目比较常见的点击态多半是透明度的变化,如按钮、列表、链接等,css的做法是添加伪类 (:active),weex中也同样支持,但是weex需要在原样式中添加 opacity:1,否则点击后回不到初始状态;此外,:active使用时,background-image在ios下会失效。例如:
<template> <div class="ui-btn"><text class="ui-btn-text">下载</text></div></template><style scoped>.ui-btn{opacity: 1; /*必须添加*/}.ui-btn:active{opacity: .5;}</style>
6、文本截断
如下图,要实现下面的效果:
文本从限制1行到不限制可以用lines:0;
<template><text class="info-text" @click="textClick" :style="textStyle">城市赛战报,《王者荣耀》城市赛郑州站欢乐落幕城市赛战报,《王者荣耀》城市赛郑州站欢乐落幕城市赛战报,《王者荣耀》城市赛郑州站欢乐落幕城市赛战报,《王者荣耀》城市赛郑州站欢乐落幕</text></template><style scoped>.info-text{lines:1;text-overflow:ellipsis;}</style><script>export default {data(){return {textStyle:{}};},methods:{textClick(){this.textStyle = {lines:0}}}}</script></style>
7、层级问题
例如,有a、b、c、d 四层结构,其中a、b、c均为absolute定位,z-index由大到小,d为普通结构,我们知道在css中a层应该是处于最上方,d在最下方,那么在weex中表现如何呢?
<div class="wrapper"><div class="box a">a</div><div class="box b">b</div><div class="box c">c</div><div class="d">d</div></div>
可以看到web和ios、android的表现不一致,ios、android中是以代码中dom顺序来依次添加的,和z-index无关,后面加载的视图会覆盖前面的视图。所以要保证web、ios、android三端表现一致,改变dom书写顺序即可。
<div class="d"></div>
<div class="box c"></div>
<div class="box b"></div>
<div class="box a"></div>
8、安卓遮挡问题
安卓环境下容器如果设置了宽高,那么子元素不能超出容器范围。
建议:fixed定位不会受父容器影响,如果需要超出限制,子元素可以设置fixed
9、v-if问题
在做一些操作切换状态时(如按钮点击置灰),应尽量避免使用v-if,使用v-if会闪,且部分安卓机子会发生不可描述的事情(如部分三星机型会出现按钮文字居顶),可采用添加class的方式。
布局
1、单行文本与图片并排方案
目前项目中存在这样的情形,昵称与直播标签并排,昵称文字短时直播要跟随,昵称很长时要做溢出截断(超出时加…) 。
这种布局方式在css中要做到很容易,而在weex中利用提供的flex布局确很难实现,最后的解决方案是通过js动态设置文字与标签父级的宽度,从而控制文字的溢出。
<template><div class="wrapper" @appear="onappear"><div class="info-container" ref='info-container'><div class="info" ref='info' :class="isFullText?['info-full']:[]"><text class="nick-text">{{isFullText}}企鹅电竞企鹅电竞企鹅电竞企鹅电竞</text><img src="http://119.29.8.64/vipstyle/egame/app/weex/tab/ERICKCHEN-MC0/dist/static/img/live.b467410.png" class="live-image"></div></div></div></template><style scoped lang="stylus">.info-full{width:300px;}</style><script>const dom = weex.requireModule('dom')export default {data(){return {isFullText:false};},methods:{onappear(){dom.getComponentRect(this.$refs['info'],option1=>{dom.getComponentRect(this.$refs['info-container'],option2=>{if(option1.size.width>=option2.size.width){this.isFullText=true;}})});}}}</script>
2、多行文本与图片并排方案
场景一:图片位于段落左侧
css的float可以做到图文混排,而weex只提供了flex布局,并且text组件之间也不能进行嵌套,无法做到这种图文混排效果,不过weex的text组件比较奇特,那就是text组件中的空格是照代码原样输出的。例如:
<text> 战国鬼才传,这个名字想必很多人听都没有听过吧,这个名字说实话真的不是很吸引人…</text>
那么运行效果如下图:
所以解决的方案可以利用填充空格给图片预留位置,先计算一个空格的宽度,再计算这张图片所需要的空格数量,最后空格连接字符串输出。
结构代码:
<template><div class="wrapper"><scroller class="scroller"><div @appear="handleAppear"> <text>空格宽度:{{spaceWidth}}-空格数量:{{spaceNum}}</text><text class="demo-text" ref="demo-text1"> test</text><text class="demo-text" ref="demo-text2">test</text></div><div class="rich"><div class="rich-icon"></div><text class="rich-text" :style="textStyle">{{content}}</text></div></scroller> </div></template>
样式:
<style scoped>.demo-text{position: absolute;font-size: 32px;/*文字大小与需要加空格文字大小保持一致*/opacity: 0;}.rich{position: relative;}.rich-icon{position: absolute;left:0;top:4px;width: 120px;height: 32px;background-color: red;}.rich-text{font-size: 32px;}</style>
核心代码:
<script>const dom = weex.requireModule('dom');export default {data(){return {spaceWidth:0,//空格宽度spaceNum:0,//所需空格数量opacity:0,//初始透明度为0,避免文案抖动content:'王者荣耀游戏中的钻石用来做什么最合算?王者荣耀钻石用来干什么最好?在王者荣耀中钻石并不是唯一通用的货币,在游戏中还有金币和点券,小编个人觉得钻石在游戏中并没有其他两种货币有优势。'};},computed:{textStyle(){return {opacity:this.opacity}}},methods:{handleAppear(){setTimeout(()=>{this.setTextContent();},30)},async setTextContent(){const text1El = this.$refs['demo-text1'];const text2El = this.$refs['demo-text2'];let textSize1,textSize2;await this.getSpaceSize(text1El,(data)=>{textSize1 = data;});await this.getSpaceSize(text2El,(data)=>{textSize2 = data;});this.spaceWidth=Math.abs(textSize1-textSize2)/10;this.content=this.getSpaceNum();this.opacity=1;},getSpaceSize(el,callback){return new Promise(function (resolve) {dom.getComponentRect(el, option => {if(option.result){resolve(callback(option.size.width));}});})},getSpaceNum(){this.spaceNum = Math.ceil(120 / this.spaceWidth);//120为红色区块宽度return new Array(this.spaceNum).join(' ')+ this.content;}}}</script>
场景二:图片位于段落末尾
很遗憾,目前这种特殊文本以及图片置于段落末尾并没有找到相应的解决方案,只能依赖终端添加相应的富文本功能。
组件
1、命名
组件命名应避免使用JS关键字和保留字,以及weex提供的组件名称,如用loading作为组件名称,在ios与android中将呈现空白。
2、自定义slider组件
weex本身提供了slider组件,但轮播图指示器(indicator)只能修改颜色与位置,大小却无法更改,所以需要自定义slider组件。
weex轮播图指示器效果
电竞项目轮播图指示器效果
weex slider提供了change事件,可以获取到当前播放的序号,从而做到自定义轮播指示器。 但是当中遇到一个诡异问题:如果“div.indicator-item”的内容为空的话,H5中的指示器并不会随着图片切换而变化(样式不生效),div中需要添加内容才行。以下是示例代码:
<div class="indicator-item" v-for="(item,index) in data" ...>
{{index}}/*添加内容,解决H5中class切换样式不生效问题*/
</div><template><div class="slider-container" :style="sliderStyle"><slider class="slider" :interval="interval" @change="change" :auto-play="autoPlay"><div class="slider-item" v-for="img in data" ><image class="slider-image" :style="sliderStyle" resize="cover" :src="img.src"></image></div></slider><div class="slider-indicator"><div class="indicator-item" v-for="(item,index) in data" :class="[current == index ? 'indicator-active' : '']">{{index}}</div></div></div></template>
动画
关键帧动画是很常见的一种动画,css3中可以利用@keyframes规则达到动画效果。
weex中提供了transition,可以传入相应的style,通过setInterval控制动画循环播放,但setInterval比较耗性能,建议终端对weex sdk进行改造,加入相应的循环播放功能。
<template><div class="wrapper"><div class="demo" ref="demo"></div></div></template><style scoped>.demo{width: 200px;height: 200px;background-color: gold;}</style><script>import * as animation from './animation.js'export default {mounted() {setTimeout(()=>{setInterval(() => {animation.run(this.$refs.demo);}, 2100);},200)}}</script>
animation.js
const animation = weex.requireModule('animation');export function transition(el, opts,dd) {let duration = dd || 400if (!el) {return Promise.resolve();}return new Promise(function (resolve) {animation.transition(el, {duration: duration, timingFunction: 'linear',delay: 0, ...opts}, resolve);})}export async function run(el, obj) {await transition(el, {styles: {backgroundColor: 'red',}},0.0001)await transition(el, {styles: {backgroundColor: 'purple',}},1000)await transition(el, {styles: {backgroundColor: 'lime',} },1000)}
性能
安卓下打开“调试GPU过度绘制”选项,打开之后选择“显示过度区域绘制”后,会发现手机界面基本被蓝色,淡绿,淡红,深红所填充,这几种颜色代表了不同程度的绘制情况,其中蓝色绘制最少,而深红色绘制最多,可能会造成页面卡顿,应避免出现大面积红色区域。
优化建议:
1、尽量不要设置背景色;
2、不要过度嵌套,结构尽量扁平化;
企鹅电竞weex实践之UI篇相关推荐
- 企鹅电竞weex实践——UI开发篇
腾讯DeepOcean原创文章:dopro.io/egame-weex-- 随着电竞业务的不断发展,页面功能越来越多,交互逻辑更加复杂,类似无限滚动.上拉刷新.横竖切换滚动等形式在业务中已是标配,经过 ...
- Weex实战分享|企鹅电竞Weex实践和性能优化
渠宏伟 企鹅电竞前端团队Leader H5页面存在的问题 H5页面对比终端的不足,第一,加载慢:第二,交互差. 加载耗时比较长,因为它受限于Webview,Webview在Android上启动就比较慢 ...
- weex android 性能,跨越适配性能那道坎,企鹅电竞Android weex优化
作者:龙泉,腾讯企鹅电竞工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. WeTest 导读 企鹅电竞从17年6月接入weex,到现在已经有一年半的时间,这段时间里面,针对遇到的 ...
- 企鹅电竞Web P2P实践
前言:本文是基于SwarmCloud创始人在2018腾讯Live开发者大会上的演讲整理而成. 项目背景 我们知道,Adobe宣布2020年将停止Flash的更新.实际上,Flash本身就存在很多问题, ...
- Flutter 布局之企鹅电竞
本人主要在知乎上发布相关Flutter文章,知乎了解下: https://www.zhihu.com/people/qiang-fu-5-67/activities 我们来实战剖析下"企鹅电 ...
- mfc程序转化为qt_以“企鹅电竞小程序”改版为例,讲解如何将用户核心路径转化为设计语言...
前言 用户路径是指用户达到目标时一系列的操作.我们可以将用户在产品中由开始到结束的整个过程划分成很多节点,用户从一个节点到另一个节点的过程可以被视为是一条路径.用户路径主要分为两种:一种是用户找寻信息 ...
- 企鹅电竞宣布将于6月7日终止运营
4月7日消息,企鹅电竞官网今日发布退市公告,称由于业务发展策略的变更 ,<企鹅电竞>(包括其网页端.App端.PC端.TV端.H5.微信小程序)以及<企鹅电竞直播助手>(包括其 ...
- android 7双排设置菜单,联想拯救者电竞手机优化横屏UI 设置菜单呈左右双排显示...
原标题:联想拯救者电竞手机优化横屏UI 设置菜单呈左右双排显示 过去的直板手机都由物理按键来实现操作,按键加上屏幕后手机整体偏长,而进入大屏智能机时代,按键的位置被屏幕取缔,但长方形的屏幕设计依然得到 ...
- python 发送企鹅电竞弹幕(简单版)
相信大家在看过小编上次的获取弹幕,也一定想要知道怎么发送弹幕.那么今天小编也来介绍一下怎么发送弹幕. 但是事先声明,小编也不喜欢水军.希望大家能不破坏弹幕界的和谐和安宁.如果你玩啥水军,官方把规则改了 ...
最新文章
- 【共振峰跟踪】通过平均不同分辨率的方法跟踪共振峰,基于时频lpc的频谱图的MATLAB仿真
- 弱电工程室内外光纤敷设有哪些技术要求
- Scala Hbase 问题汇总
- 【HDU - 6185】Covering(矩阵快速幂优化二维dp,高斯消元,轮廓线dp打表)
- 原始Dao开发方法以及存在的问题
- java 共享锁 独占锁_java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁...
- 隐马尔可夫模型(五)——隐马尔可夫模型的解码问题(维特比算法)
- 前端网页设计必逛的六个宝藏网站(非常值得收藏)
- ajax传参无法传中文,IE浏览器 ajax传参数值为中文时出现乱码的解决方案
- 【Jquery练习】tab栏切换
- 小米云服务器怎么管理员密码,小米路由器初始密码是什么 小米路由器管理密码是多少-192路由网...
- IDEA环境下模块的右下角蓝色小方块缺失的解决方法,pom文件未识别
- 每日一读---补充正能量
- html转换为pdf php,js实现html转成pdf
- 歌曲 新贵妃醉酒 - 梦回大唐爱
- 茶学领域如何用的上计算机,优秀茶学论文参考文献 茶学专著类参考文献哪里找...
- elastic-job入门(二)
- python教材答案程序设计导论论文_计算机基础及Python程序设计导论(高等学校通识教育系列教材)...
- 大数据-爬虫框架学习--scrapy
- 一线互联网架构师360°全方面性能调优,完整PDF