Weex BindingX 尝鲜

前言

三月初,阿里巴巴开源的一套基于 Weex、React Native 的富交互解决方案 「BindingX」。提供了一种称之为 「Expression Binding」 的机制能够在 Weex、React Native 上让手势等复杂交互操做以60fps的帧率流畅执行,而不会致使卡顿,于是带来了更优秀的用户体验。javascript

背景

听上去「高大上」,那为啥要造这个轮子呢?html

这就得从源头提及,他到底解决了什么问题。vue

咱们知道,Weex 和 React Native 一样都是三层结构,「 JS 层、 Native 层、 Bridge 层」,Native 层负责视觉绘制、事件收集,JS 层负责视觉控制、事件处理,Bridge 层是 JS 层和 Native 层的沟通桥梁,负责指令「翻译」。以 Weex 为例:java

想让 Native 层作一些复杂的交互操做时,JS 层就须要不停得处理从 Native 层收集来的事件而后做出「及时」响应,若是响应「不及时」就会致使视觉卡顿。android

怎么样才算是「及时」呢?ios

咱们常说 60fps 帧率是流畅的基础,这就意味着,一次有效的刷新须要在 1/60 s 内完成,若是 JS 层从事件接受、处理、回馈到 Native 绘制新的视图完成超过了 16.67ms 将会出现「视觉卡顿」。git

另外,即便每一次更新均可以彻底控制在 16.67ms 内,大量的通信操做也会消耗掉过多的 CPU,以致于加大了 Crash 的风险github

若是不突破这层瓶颈,此类技术将很难达到一个新的高度。express

BindingX 就是解决这个问题的。bash

原理

BindingX 提出的 「Expression Binding」 将具体的手势控制行为以 「表达式」 的方式传递给 Native,监控「被绑定元素」上发生的手势操做并输出过程当中横向「x」和纵向「y」的偏移量,所以咱们便可将「x,y」做为表达式「f(x),f(y)」的入参,针对性的对某一目标元素的样式进行「绑定变化」。

而这因此操做都是在 Native 层独立完成的,大大减少了 JS 层和 Bridge 层的压力。

「无 Binding 模式」

「Binding 模式」

表达式

表达式,是由数字、运算符、变量等以能求得有意义数值的字符串。譬如, x\*3+10 就是一个表达式,当x被赋值时,整个表达式就会有一个明确的结果。经过表达式,咱们就能够描述一个具体的交互行为,好比咱们但愿x从0变化到100时,透明度能从1变化到0.5,那么表达式能够描述为: f(alpha) = 1-(x/100)*0.5 也能够是 f(alpha) = 1-x/200 只不过第一种表达式更直白。

下面举一个简单的例子。

/* 简码 */
bindingx.bind({
      anchor:foo_view.ref  ,                    //==> 事件的触发者
      eventType:'pan',                          //==> 事件类型
      props: [
          {
            element:foo_view.ref,               //==> 要改变的视图的引用或者id
            property:'transform.translateX',    //==> 要改变的属性
            expression:'x+0'                    //==> 表达式
          }
        ]
    });
复制代码

就这么简单,几行代码便可绑定 foo_view 实现视图随手势移动的交互。固然复杂的也有,只不过都是由这么一个个小的交互堆积而成的。

除了基本的四则运算外,还支持三元运算符、数学函数等高级语法,基本能够知足绝大部分的场景。

事件类型

前面的例子中用到了 pan 手势,除手势外,BindingX 还支持「列表的滚动 scroll」、「动画 timing」甚至是「陀螺仪感 orientation」,每种事件类型使用方式大体相同,也有注意点,详细请参阅《bindingx 官方文档》

Do it

怎么样能快速体验呢?

跟上个人脚步

playground

官方虽然也提供了 试验田 https://alibaba.github.io/bindingx/playground,但语法均为 Rax 但 DSL,并很多 Weex 对外的 Vue 版本,咱们没法在线编辑查看效果,只能使用阿里系App「如淘宝、闲鱼、飞猪」扫码体验效果。

这些都不是咱们想要的。

固然方法老是有的。

直接将 BindingX 的官方代码 clone 下来,上面有支持 Vue 版本的 Weex Playground。

bindingx/weex/playground/[ios|android]
复制代码

ios 和 android 选一个用工具安装到本身的手机上。此处就很少解释了,不会的问下 google,或者下方留言。

使用 dotwe.org/vue/ 在线编辑,扫码看效果。

给你们分享几个 Vue 版本的 demo。

dotwe.org/vue/e50f76a…

dotwe.org/vue/2dff486…

dotwe.org/vue/6499843…

dotwe.org/vue/cd942c4…

严选 demo 引入 BindingX

这是很早之前的一个小 Demo,感兴趣的能够 star 一下 github.com/zwwill/yanx…

下面我基于严选的 Demo 进行的小试用。

升级 ios platform

要想使用 BindingX 插件,就必须使本身的 platform 支持。方法很简单,只须要将 platforms/ios/Podfile 进行升级修改便可。

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

复制代码

随后执行一遍 pod install 便可安装成功。如出现错误提示,按提示 fix 掉便可。

小试牛刀

Vue 的引入方式不一样于 Rax,须要使用 weex.requireModule() API。

<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 背景随着滚动事件变换大小。

效果动图 cdn.zwwill.com/yanxuan/res…

写在最后

Weex 有了 BindingX 如虎添翼。效率更高性!能更稳定!同期开源的还有 GCanvas 也是一把神器。

近期工做繁重,通宵写文章,如发现文章残瑕处,敬请谅解!

相关连接

做者: 木羽 zwwill 首发地址:github.com/zwwill/blog…

相关文章
相关标签/搜索