Weex BindingX 尝鲜
前言三月初,阿里巴巴开源的一套基于 Weex、React Native 的富交互解决方案 「BindingX」。提供了一种称之为 「Expression Binding」 的机制可以在 Weex、React Native 上让手势等复杂交互操作以60fps的帧率流畅执行,而不会导致卡顿,因而带来了更优秀的用户体验。 背景听上去「高大上」,那为啥要造这个轮子呢? 我们知道,Weex 和 React Native 同样都是三层结构,「 JS 层、 Native 层、 Bridge 层」,Native 层负责视觉绘制、事件收集,JS 层负责视觉控制、事件处理,Bridge 层是 JS 层和 Native 层的沟通桥梁,负责指令「翻译」。以 Weex 为例:
想让 Native 层做一些复杂的交互操作时,JS 层就需要不停得处理从 Native 层收集来的事件然后作出「及时」响应,如果响应「不及时」就会导致视觉卡顿。 怎么样才算是「及时」呢? 我们常说 60fps 帧率是流畅的基础,这就意味着,一次有效的刷新需要在 1/60 s 内完成,如果 JS 层从事件接受、处理、回馈到 Native 绘制新的视图完成超过了 16.67ms 将会出现「视觉卡顿」。 另外,即使每一次更新都可以完全控制在 16.67ms 内,大量的通讯操作也会消耗掉过多的 CPU,以至于加大了 Crash 的风险 如果不突破这层瓶颈,此类技术将很难达到一个新的高度。 BindingX 就是解决这个问题的。 原理BindingX 提出的 「Expression Binding」 将具体的手势控制行为以 「表达式」 的方式传递给 Native,监控「被绑定元素」上发生的手势操作并输出过程中横向「x」和纵向「y」的偏移量,因此我们即可将「x,y」作为表达式「f(x),f(y)」的入参,针对性的对某一目标元素的样式进行「绑定变化」。 而这所以操作都是在 Native 层独立完成的,大大减小了 JS 层和 Bridge 层的压力。 「无 Binding 模式」
「Binding 模式」
表达式表达式,是由数字、运算符、变量等以能求得有意义数值的字符串。譬如, 下面举一个简单的例子。 /* 简码 */ bindingx.bind({ anchor:foo_view.ref,//==> 事件的触发者 eventType:'pan',//==> 事件类型 props: [ { element:foo_view.ref,//==> 要改变的视图的引用或者id property:'transform.translateX',//==> 要改变的属性 expression:'x+0' //==> 表达式 } ] }); 就这么简单,几行代码即可绑定 除了基本的四则运算外,还支持三元运算符、数学函数等高级语法,基本可以满足绝大部分的场景。 事件类型前面的例子中用到了 Do it怎么样能快速体验呢? playground官方虽然也提供了 试验田 https://alibaba.github.io/bindingx/playground,但语法均为 Rax 但 DSL,并不少 Weex 对外的 Vue 版本,我们无法在线编辑查看效果,只能使用阿里系App「如淘宝、闲鱼、飞猪」扫码体验效果。 这些都不是我们想要的。 当然方法总是有的。 直接将 BindingX 的官方代码 bindingx/weex/playground/[ios|android] ios 和 android 选一个用工具安装到自己的手机上。此处就不多解释了,不会的问下 google,或者下方留言。 使用 http://dotwe.org/vue/ 在线编辑,扫码看效果。 给大家分享几个 Vue 版本的 demo。 http://dotwe.org/vue/e50f76a6c13337b6fa4201a045c5dc0c http://dotwe.org/vue/2dff486956044ea59b3d38a2cf20b506 http://dotwe.org/vue/64998432f2a249f5cb35b4de0040526d http://dotwe.org/vue/cd942c4bee9c4b7bcceda4e3aaf94c70 严选 demo 引入 BindingX这是很早以前的一个小 Demo,感兴趣的可以 star 一下 下面我基于严选的 Demo 进行的小试用。 升级 ios platform要想使用 BindingX 插件,就必须使自己的 platform 支持。方法很简单,只需要将 source 'git@github.com/CocoaPods/Specs.git' platform :ios,'8.0' #最低8.0 #inhibit_all_warnings! def common pod 'WeexSDK','0.17.0' #升级至 0.17.0 pod 'Weexplugin',:path=>'./Weexplugin/' pod 'WXDevtool' pod 'SDWebImage','3.7.5' pod 'SocketRocket','0.4.2' pod 'BindingX' #增加 BindingX end target 'WeexDemo' do common end target 'WeexUITestDemo' do common end 随后执行一遍 小试牛刀Vue 的引入方式不同于 Rax,需要使用 <template> <div class="wrapper"> <image ref="headerBg" resize="cover" src="http://cdn.zwwill.com/yanxuan/imgs/bg5.png"></image> <scroller ref="contentScroller"> <div> <!-- 省略非关键代码 --> </div> <div class="fbs"> <!-- 省略非关键代码 --> </div> </scroller> </div> </template> <script> const binding = weex.requireModule('bindingx'); //引入 bindingx export default { mounted(){ this.headerBgBinding(); },beforeDestroy(){ this.headerBgBindingDestory(); },methods: { headerBgBinding(){ let self = this,scroller = self.$refs.contentScroller.ref,headerBg = self.$refs.headerBg.ref; let bindingResult = binding && binding.bind({ eventType:'scroll',anchor:scroller,props:[ { element:headerBg,property:'transform.scale',expression:{ origin:'y<0?(1-y/500):(1+y/500)' } },{ element:headerBg,property:'transform.translateY',expression:{ origin:'-y/2' } } ] },function(e){ }); self.gesToken = bindingResult.token; } headerBgBindingDestory(){ let self = this; if(self.gesToken != 0) { binding.unbind({ eventType:'scroll',token:self.gesToken }) self.gesToken = 0; } } } } </script> 实现的效果就是最常见的个人信息页,title 背景随着滚动事件变换大小。 效果动图 http://cdn.zwwill.com/yanxuan/resource/bindingx2.gif
写在最后Weex 有了 BindingX 如虎添翼。效率更高性!能更稳定!同期开源的还有 GCanvas 也是一把神器。 近期工作繁重,通宵写文章,如发现文章残瑕处,敬请谅解! 相关链接
作者: 木羽 zwwill (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |